i = 0
res = ['"']
while i < len:
- c = chr ((chars.cast(gdb.Type ("gint64")) + (i * 2)).cast(gdb.Type ("gunichar2").pointer ()).dereference ())
+ val = (chars.cast(gdb.Type ("gint64")) + (i * 2)).cast(gdb.Type ("gunichar2").pointer ()).dereference ()
+ if val >= 256:
+ c = "\u%X" % val
+ else:
+ c = chr (val)
res.append (c)
i = i + 1
res.append ('"')
return "byte"
if name == "String":
return "string"
- return "%s.%s" % (ns, name)
+ if ns == "":
+ return name
+ else:
+ return "%s.%s" % (ns, name)
class ArrayPrinter:
"Print a C# array"
"Print a C# object"
def __init__(self, val):
- self.val = val
+ if str(val.type ())[-1] == "&":
+ self.val = val.address.cast (gdb.Type ("MonoObject").pointer ())
+ else:
+ self.val = val.cast (gdb.Type ("MonoObject").pointer ())
class _iterator:
def __init__(self,obj):
def next(self):
field = self.iter.next ()
- return (field.name, self.obj [field.name])
+ try:
+ if str(self.obj [field.name].type ()) == "object":
+ # Avoid recursion
+ return (field.name, self.obj [field.name].cast (gdb.Type ("void").pointer ()))
+ else:
+ return (field.name, self.obj [field.name])
+ except:
+ # Superclass
+ return (field.name, self.obj.cast (gdb.Type ("%s" % (field.name))))
def children(self):
# FIXME: It would be easier if gdb.Value would support iteration itself
if int(self.val.cast (gdb.Type ("guint64"))) == 0:
return {}.__iter__ ()
try:
- obj = self.val.cast (gdb.Type ("MonoObject").pointer ()).dereference ()
+ obj = self.val.dereference ()
class_ns = obj ['vtable'].dereference ()['klass'].dereference ()['name_space'].string ()
class_name = obj ['vtable'].dereference ()['klass'].dereference ()['name'].string ()
- gdb_type = gdb.Type ("struct %s.%s" % (class_ns, class_name))
+ if class_name [-2:len(class_name)] == "[]":
+ return {}.__iter__ ()
+ gdb_type = gdb.Type ("struct %s_%s" % (class_ns.replace (".", "_"), class_name))
return self._iterator(obj.cast (gdb_type))
except:
+ print sys.exc_info ()[0]
+ print sys.exc_info ()[1]
return {}.__iter__ ()
def to_string(self):
if int(self.val.cast (gdb.Type ("guint64"))) == 0:
return "null"
try:
- obj = self.val.cast (gdb.Type ("MonoObject").pointer ()).dereference ()
+ obj = self.val.dereference ()
class_ns = obj ['vtable'].dereference ()['klass'].dereference ()['name_space'].string ()
class_name = obj ['vtable'].dereference ()['klass'].dereference ()['name'].string ()
if class_ns == "System" and class_name == "String":
# FIXME: This can happen because we don't have liveness information
return self.val.cast (gdb.Type ("guint64"))
+def lookup_pretty_printer(val):
+ t = str (val.type ())
+ if t == "object":
+ return ObjectPrinter (val)
+ if t[0:5] == "class" and t[-1] == "&":
+ return ObjectPrinter (val)
+ if t == "string":
+ return StringPrinter (val)
+ return None
+
def register_csharp_printers(obj):
"Register C# pretty-printers with objfile Obj."
if obj == None:
obj = gdb
- obj.pretty_printers['object'] = ObjectPrinter
- obj.pretty_printers['string'] = StringPrinter
+ obj.pretty_printers.append (lookup_pretty_printer)
register_csharp_printers (gdb.current_objfile())