diff options
Diffstat (limited to 'kernel/scripts/gdb/linux')
-rw-r--r-- | kernel/scripts/gdb/linux/dmesg.py | 1 | ||||
-rw-r--r-- | kernel/scripts/gdb/linux/lists.py | 92 | ||||
-rw-r--r-- | kernel/scripts/gdb/linux/symbols.py | 9 | ||||
-rw-r--r-- | kernel/scripts/gdb/linux/tasks.py | 20 | ||||
-rw-r--r-- | kernel/scripts/gdb/linux/utils.py | 4 |
5 files changed, 116 insertions, 10 deletions
diff --git a/kernel/scripts/gdb/linux/dmesg.py b/kernel/scripts/gdb/linux/dmesg.py index 3c947f0c5..927d0d2a3 100644 --- a/kernel/scripts/gdb/linux/dmesg.py +++ b/kernel/scripts/gdb/linux/dmesg.py @@ -12,7 +12,6 @@ # import gdb -import string from linux import utils diff --git a/kernel/scripts/gdb/linux/lists.py b/kernel/scripts/gdb/linux/lists.py new file mode 100644 index 000000000..3a3775bc1 --- /dev/null +++ b/kernel/scripts/gdb/linux/lists.py @@ -0,0 +1,92 @@ +# +# gdb helper commands and functions for Linux kernel debugging +# +# list tools +# +# Copyright (c) Thiebaud Weksteen, 2015 +# +# Authors: +# Thiebaud Weksteen <thiebaud@weksteen.fr> +# +# This work is licensed under the terms of the GNU GPL version 2. +# + +import gdb + +from linux import utils + +list_head = utils.CachedType("struct list_head") + + +def list_check(head): + nb = 0 + if (head.type == list_head.get_type().pointer()): + head = head.dereference() + elif (head.type != list_head.get_type()): + raise gdb.GdbError('argument must be of type (struct list_head [*])') + c = head + try: + gdb.write("Starting with: {}\n".format(c)) + except gdb.MemoryError: + gdb.write('head is not accessible\n') + return + while True: + p = c['prev'].dereference() + n = c['next'].dereference() + try: + if p['next'] != c.address: + gdb.write('prev.next != current: ' + 'current@{current_addr}={current} ' + 'prev@{p_addr}={p}\n'.format( + current_addr=c.address, + current=c, + p_addr=p.address, + p=p, + )) + return + except gdb.MemoryError: + gdb.write('prev is not accessible: ' + 'current@{current_addr}={current}\n'.format( + current_addr=c.address, + current=c + )) + return + try: + if n['prev'] != c.address: + gdb.write('next.prev != current: ' + 'current@{current_addr}={current} ' + 'next@{n_addr}={n}\n'.format( + current_addr=c.address, + current=c, + n_addr=n.address, + n=n, + )) + return + except gdb.MemoryError: + gdb.write('next is not accessible: ' + 'current@{current_addr}={current}\n'.format( + current_addr=c.address, + current=c + )) + return + c = n + nb += 1 + if c == head: + gdb.write("list is consistent: {} node(s)\n".format(nb)) + return + + +class LxListChk(gdb.Command): + """Verify a list consistency""" + + def __init__(self): + super(LxListChk, self).__init__("lx-list-check", gdb.COMMAND_DATA, + gdb.COMPLETE_EXPRESSION) + + def invoke(self, arg, from_tty): + argv = gdb.string_to_argv(arg) + if len(argv) != 1: + raise gdb.GdbError("lx-list-check takes one argument") + list_check(gdb.parse_and_eval(argv[0])) + +LxListChk() diff --git a/kernel/scripts/gdb/linux/symbols.py b/kernel/scripts/gdb/linux/symbols.py index cd5bea965..627750cb4 100644 --- a/kernel/scripts/gdb/linux/symbols.py +++ b/kernel/scripts/gdb/linux/symbols.py @@ -14,9 +14,8 @@ import gdb import os import re -import string -from linux import modules, utils +from linux import modules if hasattr(gdb, 'Breakpoint'): @@ -97,7 +96,7 @@ lx-symbols command.""" return "" attrs = sect_attrs['attrs'] section_name_to_address = { - attrs[n]['name'].string() : attrs[n]['address'] + attrs[n]['name'].string(): attrs[n]['address'] for n in range(int(sect_attrs['nsections']))} args = [] for section_name in [".data", ".data..read_mostly", ".rodata", ".bss"]: @@ -124,7 +123,7 @@ lx-symbols command.""" addr=module_addr, sections=self._section_arguments(module)) gdb.execute(cmdline, to_string=True) - if not module_name in self.loaded_modules: + if module_name not in self.loaded_modules: self.loaded_modules.append(module_name) else: gdb.write("no module object found for '{0}'\n".format(module_name)) @@ -164,7 +163,7 @@ lx-symbols command.""" self.load_all_symbols() if hasattr(gdb, 'Breakpoint'): - if not self.breakpoint is None: + if self.breakpoint is not None: self.breakpoint.delete() self.breakpoint = None self.breakpoint = LoadModuleBreakpoint( diff --git a/kernel/scripts/gdb/linux/tasks.py b/kernel/scripts/gdb/linux/tasks.py index e2037d9bb..862a4ae24 100644 --- a/kernel/scripts/gdb/linux/tasks.py +++ b/kernel/scripts/gdb/linux/tasks.py @@ -18,8 +18,8 @@ from linux import utils task_type = utils.CachedType("struct task_struct") + def task_lists(): - global task_type task_ptr_type = task_type.get_type().pointer() init_task = gdb.parse_and_eval("init_task").address t = g = init_task @@ -38,6 +38,7 @@ def task_lists(): if t == init_task: return + def get_task_by_pid(pid): for task in task_lists(): if int(task['pid']) == pid: @@ -65,13 +66,28 @@ return that task_struct variable which PID matches.""" LxTaskByPidFunc() +class LxPs(gdb.Command): + """Dump Linux tasks.""" + + def __init__(self): + super(LxPs, self).__init__("lx-ps", gdb.COMMAND_DATA) + + def invoke(self, arg, from_tty): + for task in task_lists(): + gdb.write("{address} {pid} {comm}\n".format( + address=task, + pid=task["pid"], + comm=task["comm"].string())) + +LxPs() + + thread_info_type = utils.CachedType("struct thread_info") ia64_task_size = None def get_thread_info(task): - global thread_info_type thread_info_ptr_type = thread_info_type.get_type().pointer() if utils.is_target_arch("ia64"): global ia64_task_size diff --git a/kernel/scripts/gdb/linux/utils.py b/kernel/scripts/gdb/linux/utils.py index 128c306db..0893b326a 100644 --- a/kernel/scripts/gdb/linux/utils.py +++ b/kernel/scripts/gdb/linux/utils.py @@ -83,7 +83,7 @@ def get_target_endianness(): elif "big endian" in endian: target_endianness = BIG_ENDIAN else: - raise gdb.GdgError("unknown endianness '{0}'".format(str(endian))) + raise gdb.GdbError("unknown endianness '{0}'".format(str(endian))) return target_endianness @@ -151,6 +151,6 @@ def get_gdbserver_type(): gdbserver_type = GDBSERVER_QEMU elif probe_kgdb(): gdbserver_type = GDBSERVER_KGDB - if not gdbserver_type is None and hasattr(gdb, 'events'): + if gdbserver_type is not None and hasattr(gdb, 'events'): gdb.events.exited.connect(exit_handler) return gdbserver_type |