diff options
Diffstat (limited to 'scripts/gdb/linux')
-rw-r--r-- | scripts/gdb/linux/dmesg.py | 1 | ||||
-rw-r--r-- | scripts/gdb/linux/lists.py | 92 | ||||
-rw-r--r-- | scripts/gdb/linux/symbols.py | 9 | ||||
-rw-r--r-- | scripts/gdb/linux/tasks.py | 20 | ||||
-rw-r--r-- | scripts/gdb/linux/utils.py | 4 |
5 files changed, 116 insertions, 10 deletions
diff --git a/scripts/gdb/linux/dmesg.py b/scripts/gdb/linux/dmesg.py index 3c947f0c5dad..927d0d2a3145 100644 --- a/scripts/gdb/linux/dmesg.py +++ b/scripts/gdb/linux/dmesg.py | |||
@@ -12,7 +12,6 @@ | |||
12 | # | 12 | # |
13 | 13 | ||
14 | import gdb | 14 | import gdb |
15 | import string | ||
16 | 15 | ||
17 | from linux import utils | 16 | from linux import utils |
18 | 17 | ||
diff --git a/scripts/gdb/linux/lists.py b/scripts/gdb/linux/lists.py new file mode 100644 index 000000000000..3a3775bc162b --- /dev/null +++ b/scripts/gdb/linux/lists.py | |||
@@ -0,0 +1,92 @@ | |||
1 | # | ||
2 | # gdb helper commands and functions for Linux kernel debugging | ||
3 | # | ||
4 | # list tools | ||
5 | # | ||
6 | # Copyright (c) Thiebaud Weksteen, 2015 | ||
7 | # | ||
8 | # Authors: | ||
9 | # Thiebaud Weksteen <thiebaud@weksteen.fr> | ||
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 | list_head = utils.CachedType("struct list_head") | ||
19 | |||
20 | |||
21 | def list_check(head): | ||
22 | nb = 0 | ||
23 | if (head.type == list_head.get_type().pointer()): | ||
24 | head = head.dereference() | ||
25 | elif (head.type != list_head.get_type()): | ||
26 | raise gdb.GdbError('argument must be of type (struct list_head [*])') | ||
27 | c = head | ||
28 | try: | ||
29 | gdb.write("Starting with: {}\n".format(c)) | ||
30 | except gdb.MemoryError: | ||
31 | gdb.write('head is not accessible\n') | ||
32 | return | ||
33 | while True: | ||
34 | p = c['prev'].dereference() | ||
35 | n = c['next'].dereference() | ||
36 | try: | ||
37 | if p['next'] != c.address: | ||
38 | gdb.write('prev.next != current: ' | ||
39 | 'current@{current_addr}={current} ' | ||
40 | 'prev@{p_addr}={p}\n'.format( | ||
41 | current_addr=c.address, | ||
42 | current=c, | ||
43 | p_addr=p.address, | ||
44 | p=p, | ||
45 | )) | ||
46 | return | ||
47 | except gdb.MemoryError: | ||
48 | gdb.write('prev is not accessible: ' | ||
49 | 'current@{current_addr}={current}\n'.format( | ||
50 | current_addr=c.address, | ||
51 | current=c | ||
52 | )) | ||
53 | return | ||
54 | try: | ||
55 | if n['prev'] != c.address: | ||
56 | gdb.write('next.prev != current: ' | ||
57 | 'current@{current_addr}={current} ' | ||
58 | 'next@{n_addr}={n}\n'.format( | ||
59 | current_addr=c.address, | ||
60 | current=c, | ||
61 | n_addr=n.address, | ||
62 | n=n, | ||
63 | )) | ||
64 | return | ||
65 | except gdb.MemoryError: | ||
66 | gdb.write('next is not accessible: ' | ||
67 | 'current@{current_addr}={current}\n'.format( | ||
68 | current_addr=c.address, | ||
69 | current=c | ||
70 | )) | ||
71 | return | ||
72 | c = n | ||
73 | nb += 1 | ||
74 | if c == head: | ||
75 | gdb.write("list is consistent: {} node(s)\n".format(nb)) | ||
76 | return | ||
77 | |||
78 | |||
79 | class LxListChk(gdb.Command): | ||
80 | """Verify a list consistency""" | ||
81 | |||
82 | def __init__(self): | ||
83 | super(LxListChk, self).__init__("lx-list-check", gdb.COMMAND_DATA, | ||
84 | gdb.COMPLETE_EXPRESSION) | ||
85 | |||
86 | def invoke(self, arg, from_tty): | ||
87 | argv = gdb.string_to_argv(arg) | ||
88 | if len(argv) != 1: | ||
89 | raise gdb.GdbError("lx-list-check takes one argument") | ||
90 | list_check(gdb.parse_and_eval(argv[0])) | ||
91 | |||
92 | LxListChk() | ||
diff --git a/scripts/gdb/linux/symbols.py b/scripts/gdb/linux/symbols.py index cd5bea965d4e..627750cb420d 100644 --- a/scripts/gdb/linux/symbols.py +++ b/scripts/gdb/linux/symbols.py | |||
@@ -14,9 +14,8 @@ | |||
14 | import gdb | 14 | import gdb |
15 | import os | 15 | import os |
16 | import re | 16 | import re |
17 | import string | ||
18 | 17 | ||
19 | from linux import modules, utils | 18 | from linux import modules |
20 | 19 | ||
21 | 20 | ||
22 | if hasattr(gdb, 'Breakpoint'): | 21 | if hasattr(gdb, 'Breakpoint'): |
@@ -97,7 +96,7 @@ lx-symbols command.""" | |||
97 | return "" | 96 | return "" |
98 | attrs = sect_attrs['attrs'] | 97 | attrs = sect_attrs['attrs'] |
99 | section_name_to_address = { | 98 | section_name_to_address = { |
100 | attrs[n]['name'].string() : attrs[n]['address'] | 99 | attrs[n]['name'].string(): attrs[n]['address'] |
101 | for n in range(int(sect_attrs['nsections']))} | 100 | for n in range(int(sect_attrs['nsections']))} |
102 | args = [] | 101 | args = [] |
103 | for section_name in [".data", ".data..read_mostly", ".rodata", ".bss"]: | 102 | for section_name in [".data", ".data..read_mostly", ".rodata", ".bss"]: |
@@ -124,7 +123,7 @@ lx-symbols command.""" | |||
124 | addr=module_addr, | 123 | addr=module_addr, |
125 | sections=self._section_arguments(module)) | 124 | sections=self._section_arguments(module)) |
126 | gdb.execute(cmdline, to_string=True) | 125 | gdb.execute(cmdline, to_string=True) |
127 | if not module_name in self.loaded_modules: | 126 | if module_name not in self.loaded_modules: |
128 | self.loaded_modules.append(module_name) | 127 | self.loaded_modules.append(module_name) |
129 | else: | 128 | else: |
130 | gdb.write("no module object found for '{0}'\n".format(module_name)) | 129 | gdb.write("no module object found for '{0}'\n".format(module_name)) |
@@ -164,7 +163,7 @@ lx-symbols command.""" | |||
164 | self.load_all_symbols() | 163 | self.load_all_symbols() |
165 | 164 | ||
166 | if hasattr(gdb, 'Breakpoint'): | 165 | if hasattr(gdb, 'Breakpoint'): |
167 | if not self.breakpoint is None: | 166 | if self.breakpoint is not None: |
168 | self.breakpoint.delete() | 167 | self.breakpoint.delete() |
169 | self.breakpoint = None | 168 | self.breakpoint = None |
170 | self.breakpoint = LoadModuleBreakpoint( | 169 | self.breakpoint = LoadModuleBreakpoint( |
diff --git a/scripts/gdb/linux/tasks.py b/scripts/gdb/linux/tasks.py index e2037d9bb7eb..862a4ae24d49 100644 --- a/scripts/gdb/linux/tasks.py +++ b/scripts/gdb/linux/tasks.py | |||
@@ -18,8 +18,8 @@ from linux import utils | |||
18 | 18 | ||
19 | task_type = utils.CachedType("struct task_struct") | 19 | task_type = utils.CachedType("struct task_struct") |
20 | 20 | ||
21 | |||
21 | def task_lists(): | 22 | def task_lists(): |
22 | global task_type | ||
23 | task_ptr_type = task_type.get_type().pointer() | 23 | task_ptr_type = task_type.get_type().pointer() |
24 | init_task = gdb.parse_and_eval("init_task").address | 24 | init_task = gdb.parse_and_eval("init_task").address |
25 | t = g = init_task | 25 | t = g = init_task |
@@ -38,6 +38,7 @@ def task_lists(): | |||
38 | if t == init_task: | 38 | if t == init_task: |
39 | return | 39 | return |
40 | 40 | ||
41 | |||
41 | def get_task_by_pid(pid): | 42 | def get_task_by_pid(pid): |
42 | for task in task_lists(): | 43 | for task in task_lists(): |
43 | if int(task['pid']) == pid: | 44 | if int(task['pid']) == pid: |
@@ -65,13 +66,28 @@ return that task_struct variable which PID matches.""" | |||
65 | LxTaskByPidFunc() | 66 | LxTaskByPidFunc() |
66 | 67 | ||
67 | 68 | ||
69 | class LxPs(gdb.Command): | ||
70 | """Dump Linux tasks.""" | ||
71 | |||
72 | def __init__(self): | ||
73 | super(LxPs, self).__init__("lx-ps", gdb.COMMAND_DATA) | ||
74 | |||
75 | def invoke(self, arg, from_tty): | ||
76 | for task in task_lists(): | ||
77 | gdb.write("{address} {pid} {comm}\n".format( | ||
78 | address=task, | ||
79 | pid=task["pid"], | ||
80 | comm=task["comm"].string())) | ||
81 | |||
82 | LxPs() | ||
83 | |||
84 | |||
68 | thread_info_type = utils.CachedType("struct thread_info") | 85 | thread_info_type = utils.CachedType("struct thread_info") |
69 | 86 | ||
70 | ia64_task_size = None | 87 | ia64_task_size = None |
71 | 88 | ||
72 | 89 | ||
73 | def get_thread_info(task): | 90 | def get_thread_info(task): |
74 | global thread_info_type | ||
75 | thread_info_ptr_type = thread_info_type.get_type().pointer() | 91 | thread_info_ptr_type = thread_info_type.get_type().pointer() |
76 | if utils.is_target_arch("ia64"): | 92 | if utils.is_target_arch("ia64"): |
77 | global ia64_task_size | 93 | global ia64_task_size |
diff --git a/scripts/gdb/linux/utils.py b/scripts/gdb/linux/utils.py index 128c306db3ee..0893b326a28b 100644 --- a/scripts/gdb/linux/utils.py +++ b/scripts/gdb/linux/utils.py | |||
@@ -83,7 +83,7 @@ def get_target_endianness(): | |||
83 | elif "big endian" in endian: | 83 | elif "big endian" in endian: |
84 | target_endianness = BIG_ENDIAN | 84 | target_endianness = BIG_ENDIAN |
85 | else: | 85 | else: |
86 | raise gdb.GdgError("unknown endianness '{0}'".format(str(endian))) | 86 | raise gdb.GdbError("unknown endianness '{0}'".format(str(endian))) |
87 | return target_endianness | 87 | return target_endianness |
88 | 88 | ||
89 | 89 | ||
@@ -151,6 +151,6 @@ def get_gdbserver_type(): | |||
151 | gdbserver_type = GDBSERVER_QEMU | 151 | gdbserver_type = GDBSERVER_QEMU |
152 | elif probe_kgdb(): | 152 | elif probe_kgdb(): |
153 | gdbserver_type = GDBSERVER_KGDB | 153 | gdbserver_type = GDBSERVER_KGDB |
154 | if not gdbserver_type is None and hasattr(gdb, 'events'): | 154 | if gdbserver_type is not None and hasattr(gdb, 'events'): |
155 | gdb.events.exited.connect(exit_handler) | 155 | gdb.events.exited.connect(exit_handler) |
156 | return gdbserver_type | 156 | return gdbserver_type |