0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 import gdb
0015
0016 from linux import utils
0017
0018
0019 task_type = utils.CachedType("struct task_struct")
0020
0021
0022 def task_lists():
0023 task_ptr_type = task_type.get_type().pointer()
0024 init_task = gdb.parse_and_eval("init_task").address
0025 t = g = init_task
0026
0027 while True:
0028 while True:
0029 yield t
0030
0031 t = utils.container_of(t['thread_group']['next'],
0032 task_ptr_type, "thread_group")
0033 if t == g:
0034 break
0035
0036 t = g = utils.container_of(g['tasks']['next'],
0037 task_ptr_type, "tasks")
0038 if t == init_task:
0039 return
0040
0041
0042 def get_task_by_pid(pid):
0043 for task in task_lists():
0044 if int(task['pid']) == pid:
0045 return task
0046 return None
0047
0048
0049 class LxTaskByPidFunc(gdb.Function):
0050 """Find Linux task by PID and return the task_struct variable.
0051
0052 $lx_task_by_pid(PID): Given PID, iterate over all tasks of the target and
0053 return that task_struct variable which PID matches."""
0054
0055 def __init__(self):
0056 super(LxTaskByPidFunc, self).__init__("lx_task_by_pid")
0057
0058 def invoke(self, pid):
0059 task = get_task_by_pid(pid)
0060 if task:
0061 return task.dereference()
0062 else:
0063 raise gdb.GdbError("No task of PID " + str(pid))
0064
0065
0066 LxTaskByPidFunc()
0067
0068
0069 class LxPs(gdb.Command):
0070 """Dump Linux tasks."""
0071
0072 def __init__(self):
0073 super(LxPs, self).__init__("lx-ps", gdb.COMMAND_DATA)
0074
0075 def invoke(self, arg, from_tty):
0076 gdb.write("{:>10} {:>12} {:>7}\n".format("TASK", "PID", "COMM"))
0077 for task in task_lists():
0078 gdb.write("{} {:^5} {}\n".format(
0079 task.format_string().split()[0],
0080 task["pid"].format_string(),
0081 task["comm"].string()))
0082
0083
0084 LxPs()
0085
0086
0087 thread_info_type = utils.CachedType("struct thread_info")
0088
0089 ia64_task_size = None
0090
0091
0092 def get_thread_info(task):
0093 thread_info_ptr_type = thread_info_type.get_type().pointer()
0094 if utils.is_target_arch("ia64"):
0095 global ia64_task_size
0096 if ia64_task_size is None:
0097 ia64_task_size = gdb.parse_and_eval("sizeof(struct task_struct)")
0098 thread_info_addr = task.address + ia64_task_size
0099 thread_info = thread_info_addr.cast(thread_info_ptr_type)
0100 else:
0101 if task.type.fields()[0].type == thread_info_type.get_type():
0102 return task['thread_info']
0103 thread_info = task['stack'].cast(thread_info_ptr_type)
0104 return thread_info.dereference()
0105
0106
0107 class LxThreadInfoFunc (gdb.Function):
0108 """Calculate Linux thread_info from task variable.
0109
0110 $lx_thread_info(TASK): Given TASK, return the corresponding thread_info
0111 variable."""
0112
0113 def __init__(self):
0114 super(LxThreadInfoFunc, self).__init__("lx_thread_info")
0115
0116 def invoke(self, task):
0117 return get_thread_info(task)
0118
0119
0120 LxThreadInfoFunc()
0121
0122
0123 class LxThreadInfoByPidFunc (gdb.Function):
0124 """Calculate Linux thread_info from task variable found by pid
0125
0126 $lx_thread_info_by_pid(PID): Given PID, return the corresponding thread_info
0127 variable."""
0128
0129 def __init__(self):
0130 super(LxThreadInfoByPidFunc, self).__init__("lx_thread_info_by_pid")
0131
0132 def invoke(self, pid):
0133 task = get_task_by_pid(pid)
0134 if task:
0135 return get_thread_info(task.dereference())
0136 else:
0137 raise gdb.GdbError("No task of PID " + str(pid))
0138
0139
0140 LxThreadInfoByPidFunc()