From 9fe6d3c7df8769ff54617ea8ae9d2a4ff91cbff9 Mon Sep 17 00:00:00 2001 From: Mathieu Maret Date: Thu, 20 Aug 2020 23:38:17 +0200 Subject: [PATCH] add some pretty-printer for kthread --- README.md | 11 +++++++++ custom_gdb_extension.py | 55 ++++++++++++++++++++++++++++++++++++++--- 2 files changed, 62 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 71aec0a..958c10a 100644 --- a/README.md +++ b/README.md @@ -16,3 +16,14 @@ To generate iso image you can also test it `make self_test` + +# Debug + +gdb could be launch with debug symbols using : + + make debug + +Then you can check some matos specific commands or pretty printing with + + help user-defined + info pretty-printer (Should contains matos_pretty_printers) diff --git a/custom_gdb_extension.py b/custom_gdb_extension.py index cd11ba0..0341750 100644 --- a/custom_gdb_extension.py +++ b/custom_gdb_extension.py @@ -1,3 +1,48 @@ +from gdb.printing import PrettyPrinter, register_pretty_printer +import gdb + +class KthreadPrettyPrinter(object): + + def __init__(self, val): + self.val = val + + def to_string(self): + result = "" + name = self.val["name"] + state = self.val["state"] + # Should get PC on stack for non-current thread otherwise will only get address in cpu_context_switch + cpuState = self.val["cpuState"] + cmdline = "info line *%s"%int(cpuState["eip"].cast(gdb.lookup_type("long").pointer())) + line = gdb.execute(cmdline, to_string=True) + #line = gdb.find_pc_line(int(cpuState["eip"].cast(gdb.lookup_type("long").pointer()).referenced_value())) + currentThread = gdb.parse_and_eval("currentThread") + if self.val == currentThread: + result += "->" + else: + result += " " + result += "Addr: 0x%x, name: %s, state: %s, PC: %s" % (self.val, name, state, line) + return result + + +class CustomPrettyPrinterLocator(PrettyPrinter): + """Given a gdb.Value, search for a custom pretty printer""" + + def __init__(self): + super(CustomPrettyPrinterLocator, self).__init__( + "matos_pretty_printers", [] + ) + + def __call__(self, val): + """Return the custom formatter if the type can be handled""" + + typename = gdb.types.get_basic_type(val.type).tag + if typename is None: + typename = val.type.name + + if typename == "kthread": + return KthreadPrettyPrinter(val) + + class KthreadListDumpCmd(gdb.Command): """Prints the kthread list""" @@ -16,8 +61,7 @@ class KthreadListDumpCmd(gdb.Command): kthread_ptr = val result = "" while kthread_ptr != 0 and (idx == 0 or kthread_ptr != head) : - name = kthread_ptr["name"] - result += "\n%d: Addr: 0x%x, name: %s" % (idx, kthread_ptr, name) + result += "\n%d: %s" % (idx, KthreadPrettyPrinter(kthread_ptr).to_string()) kthread_ptr = kthread_ptr["next"] idx += 1 result = ("Found a Linked List with %d kthread:" % idx) + result @@ -32,13 +76,16 @@ class KthreadListDumpCmd(gdb.Command): # We can pass args here and use Python CLI utilities like argparse # to do argument parsing print("Args Passed: %s" % args) - - kthread_ptr_val = gdb.parse_and_eval(args) + if args: + kthread_ptr_val = gdb.parse_and_eval(args) + else: + kthread_ptr_val = gdb.parse_and_eval("currentThread") if str(kthread_ptr_val.type) != "struct kthread *": print("Expected pointer argument of type (struct kthread *)") return print(self._kthread_list_to_str(kthread_ptr_val)) +register_pretty_printer(None, CustomPrettyPrinterLocator(), replace=True) KthreadListDumpCmd()