diff options
Diffstat (limited to 'scripts/gdb/linux/tasks.py')
-rw-r--r-- | scripts/gdb/linux/tasks.py | 100 |
1 files changed, 100 insertions, 0 deletions
diff --git a/scripts/gdb/linux/tasks.py b/scripts/gdb/linux/tasks.py new file mode 100644 index 000000000000..e2037d9bb7eb --- /dev/null +++ b/scripts/gdb/linux/tasks.py | |||
@@ -0,0 +1,100 @@ | |||
1 | # | ||
2 | # gdb helper commands and functions for Linux kernel debugging | ||
3 | # | ||
4 | # task & thread tools | ||
5 | # | ||
6 | # Copyright (c) Siemens AG, 2011-2013 | ||
7 | # | ||
8 | # Authors: | ||
9 | # Jan Kiszka <jan.kiszka@siemens.com> | ||
10 | # | ||
11 | # This work is licensed under the terms of the GNU GPL version 2. | ||
12 | # | ||
13 | |||
14 | import gdb | ||
15 | |||
16 | from linux import utils | ||
17 | |||
18 | |||
19 | task_type = utils.CachedType("struct task_struct") | ||
20 | |||
21 | def task_lists(): | ||
22 | global task_type | ||
23 | task_ptr_type = task_type.get_type().pointer() | ||
24 | init_task = gdb.parse_and_eval("init_task").address | ||
25 | t = g = init_task | ||
26 | |||
27 | while True: | ||
28 | while True: | ||
29 | yield t | ||
30 | |||
31 | t = utils.container_of(t['thread_group']['next'], | ||
32 | task_ptr_type, "thread_group") | ||
33 | if t == g: | ||
34 | break | ||
35 | |||
36 | t = g = utils.container_of(g['tasks']['next'], | ||
37 | task_ptr_type, "tasks") | ||
38 | if t == init_task: | ||
39 | return | ||
40 | |||
41 | def get_task_by_pid(pid): | ||
42 | for task in task_lists(): | ||
43 | if int(task['pid']) == pid: | ||
44 | return task | ||
45 | return None | ||
46 | |||
47 | |||
48 | class LxTaskByPidFunc(gdb.Function): | ||
49 | """Find Linux task by PID and return the task_struct variable. | ||
50 | |||
51 | $lx_task_by_pid(PID): Given PID, iterate over all tasks of the target and | ||
52 | return that task_struct variable which PID matches.""" | ||
53 | |||
54 | def __init__(self): | ||
55 | super(LxTaskByPidFunc, self).__init__("lx_task_by_pid") | ||
56 | |||
57 | def invoke(self, pid): | ||
58 | task = get_task_by_pid(pid) | ||
59 | if task: | ||
60 | return task.dereference() | ||
61 | else: | ||
62 | raise gdb.GdbError("No task of PID " + str(pid)) | ||
63 | |||
64 | |||
65 | LxTaskByPidFunc() | ||
66 | |||
67 | |||
68 | thread_info_type = utils.CachedType("struct thread_info") | ||
69 | |||
70 | ia64_task_size = None | ||
71 | |||
72 | |||
73 | def get_thread_info(task): | ||
74 | global thread_info_type | ||
75 | thread_info_ptr_type = thread_info_type.get_type().pointer() | ||
76 | if utils.is_target_arch("ia64"): | ||
77 | global ia64_task_size | ||
78 | if ia64_task_size is None: | ||
79 | ia64_task_size = gdb.parse_and_eval("sizeof(struct task_struct)") | ||
80 | thread_info_addr = task.address + ia64_task_size | ||
81 | thread_info = thread_info_addr.cast(thread_info_ptr_type) | ||
82 | else: | ||
83 | thread_info = task['stack'].cast(thread_info_ptr_type) | ||
84 | return thread_info.dereference() | ||
85 | |||
86 | |||
87 | class LxThreadInfoFunc (gdb.Function): | ||
88 | """Calculate Linux thread_info from task variable. | ||
89 | |||
90 | $lx_thread_info(TASK): Given TASK, return the corresponding thread_info | ||
91 | variable.""" | ||
92 | |||
93 | def __init__(self): | ||
94 | super(LxThreadInfoFunc, self).__init__("lx_thread_info") | ||
95 | |||
96 | def invoke(self, task): | ||
97 | return get_thread_info(task) | ||
98 | |||
99 | |||
100 | LxThreadInfoFunc() | ||