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/modules.py | 9 | ||||
| -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 |
6 files changed, 117 insertions, 18 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/modules.py b/scripts/gdb/linux/modules.py index a1504c4f1900..25db8cff44a2 100644 --- a/scripts/gdb/linux/modules.py +++ b/scripts/gdb/linux/modules.py | |||
| @@ -73,18 +73,11 @@ class LxLsmod(gdb.Command): | |||
| 73 | " " if utils.get_long_type().sizeof == 8 else "")) | 73 | " " if utils.get_long_type().sizeof == 8 else "")) |
| 74 | 74 | ||
| 75 | for module in module_list(): | 75 | for module in module_list(): |
| 76 | ref = 0 | ||
| 77 | module_refptr = module['refptr'] | ||
| 78 | for cpu in cpus.cpu_list("cpu_possible_mask"): | ||
| 79 | refptr = cpus.per_cpu(module_refptr, cpu) | ||
| 80 | ref += refptr['incs'] | ||
| 81 | ref -= refptr['decs'] | ||
| 82 | |||
| 83 | gdb.write("{address} {name:<19} {size:>8} {ref}".format( | 76 | gdb.write("{address} {name:<19} {size:>8} {ref}".format( |
| 84 | address=str(module['module_core']).split()[0], | 77 | address=str(module['module_core']).split()[0], |
| 85 | name=module['name'].string(), | 78 | name=module['name'].string(), |
| 86 | size=str(module['core_size']), | 79 | size=str(module['core_size']), |
| 87 | ref=str(ref))) | 80 | ref=str(module['refcnt']['counter']))) |
| 88 | 81 | ||
| 89 | source_list = module['source_list'] | 82 | source_list = module['source_list'] |
| 90 | t = self._module_use_type.get_type().pointer() | 83 | t = self._module_use_type.get_type().pointer() |
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 |
