diff options
author | Zoltan Varga <vargaz@gmail.com> | 2010-06-28 02:34:46 +0400 |
---|---|---|
committer | Zoltan Varga <vargaz@gmail.com> | 2010-06-28 02:34:46 +0400 |
commit | 7978f18689e07a8b937fa9b80a27f9b68732a710 (patch) | |
tree | 696bc99598e42263d42b56b31e5cdff0cc6d4ccd /data | |
parent | 5c0b87d424d2f0623a96167766cc5a0dead1935e (diff) |
2010-06-28 Zoltan Varga <vargaz@gmail.com>
* mono-gdb.py: Add pretty printers for more runtime data structures.
svn path=/trunk/mono/; revision=159586
Diffstat (limited to 'data')
-rw-r--r-- | data/gdb/ChangeLog | 4 | ||||
-rw-r--r-- | data/gdb/mono-gdb.py | 122 |
2 files changed, 124 insertions, 2 deletions
diff --git a/data/gdb/ChangeLog b/data/gdb/ChangeLog index 03775d80c28..2f5997d0655 100644 --- a/data/gdb/ChangeLog +++ b/data/gdb/ChangeLog @@ -1,3 +1,7 @@ +2010-06-28 Zoltan Varga <vargaz@gmail.com> + + * mono-gdb.py: Add pretty printers for more runtime data structures. + 2009-10-13 Zoltan Varga <vargaz@gmail.com> * mono-gdb.py: Add an 'xdb' command to flush the debugging info. diff --git a/data/gdb/mono-gdb.py b/data/gdb/mono-gdb.py index ca0d19e294f..fc101f122f9 100644 --- a/data/gdb/mono-gdb.py +++ b/data/gdb/mono-gdb.py @@ -158,15 +158,125 @@ class MonoClassPrinter: def __init__(self, val): self.val = val - def to_string(self): + def to_string_inner(self, add_quotes): if int(self.val.cast (gdb.lookup_type ("guint64"))) == 0: return "0x0" klass = self.val.dereference () class_name = stringify_class_name (klass ["name_space"].string (), klass ["name"].string ()) - return "\"%s\"" % (class_name) + if add_quotes: + return "\"%s\"" % (class_name) + else: + return class_name # This returns more info but requires calling into the inferior #return "\"%s\"" % (gdb.parse_and_eval ("mono_type_full_name (&((MonoClass*)%s)->byval_arg)" % (str (int ((self.val).cast (gdb.lookup_type ("guint64"))))))) + def to_string(self): + try: + return self.to_string_inner (True) + except: + #print sys.exc_info ()[0] + #print sys.exc_info ()[1] + return str(self.val.cast (gdb.lookup_type ("gpointer"))) + +class MonoGenericInstPrinter: + "Print a MonoGenericInst structure" + + def __init__(self, val): + self.val = val + + def to_string(self): + inst = self.val.dereference () + inst_len = inst ["type_argc"] + inst_args = inst ["type_argv"] + inst_str = "" + for i in range(0, inst_len): + print inst_args + type_printer = MonoTypePrinter (inst_args [i]) + if i > 0: + inst_str = inst_str + ", " + inst_str = inst_str + type_printer.to_string () + return inst_str + +class MonoGenericClassPrinter: + "Print a MonoGenericClass structure" + + def __init__(self, val): + self.val = val + + def to_string_inner(self): + gclass = self.val.dereference () + container_str = str(gclass ["container_class"]) + class_inst = gclass ["context"]["class_inst"] + class_inst_str = "" + if int(class_inst.cast (gdb.lookup_type ("guint64"))) != 0: + class_inst_str = str(class_inst) + method_inst = gclass ["context"]["method_inst"] + method_inst_str = "" + if int(method_inst.cast (gdb.lookup_type ("guint64"))) != 0: + method_inst_str = str(method_inst) + return "%s, [%s], [%s]>" % (container_str, class_inst_str, method_inst_str) + + def to_string(self): + try: + return self.to_string_inner () + except: + #print sys.exc_info ()[0] + #print sys.exc_info ()[1] + return str(self.val.cast (gdb.lookup_type ("gpointer"))) + +class MonoTypePrinter: + "Print a MonoType structure" + + def __init__(self, val): + self.val = val + + def to_string_inner(self, csharp): + try: + t = self.val.dereference () + + kind = str (t ["type"]).replace ("MONO_TYPE_", "").lower () + info = "" + + if kind == "class": + p = MonoClassPrinter(t ["data"]["klass"]) + info = p.to_string () + elif kind == "genericinst": + info = str(t ["data"]["generic_class"]) + + if info != "": + return "{%s, %s}" % (kind, info) + else: + return "{%s}" % (kind) + except: + #print sys.exc_info ()[0] + #print sys.exc_info ()[1] + return str(self.val.cast (gdb.lookup_type ("gpointer"))) + + def to_string(self): + return self.to_string_inner (False) + +class MonoMethodRgctxPrinter: + "Print a MonoMethodRgctx structure" + + def __init__(self, val): + self.val = val + + def to_string(self): + rgctx = self.val.dereference () + klass = rgctx ["class_vtable"].dereference () ["klass"] + klass_printer = MonoClassPrinter (klass) + inst = rgctx ["method_inst"].dereference () + inst_len = inst ["type_argc"] + inst_args = inst ["type_argv"] + inst_str = "" + for i in range(0, inst_len): + print inst_args + type_printer = MonoTypePrinter (inst_args [i]) + if i > 0: + inst_str = inst_str + ", " + inst_str = inst_str + type_printer.to_string () + return "MRGCTX[%s, [%s]]" % (klass_printer.to_string(), inst_str) + def lookup_pretty_printer(val): t = str (val.type) if t == "object": @@ -179,6 +289,14 @@ def lookup_pretty_printer(val): return MonoMethodPrinter (val) if t == "MonoClass *": return MonoClassPrinter (val) + if t == "MonoType *": + return MonoTypePrinter (val) + if t == "MonoGenericInst *": + return MonoGenericInstPrinter (val) + if t == "MonoGenericClass *": + return MonoGenericClassPrinter (val) + if t == "MonoMethodRuntimeGenericContext *": + return MonoMethodRgctxPrinter (val) return None def register_csharp_printers(obj): |