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 @@  #  import gdb -import string  from linux import utils 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 @@ +# +# gdb helper commands and functions for Linux kernel debugging +# +#  list tools +# +# Copyright (c) Thiebaud Weksteen, 2015 +# +# Authors: +#  Thiebaud Weksteen <[email protected]> +# +# 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/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 @@  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/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  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/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():          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  |