# - run mono under gdb, or attach to a mono process started with --debug=gdb using gdb.
#
+from __future__ import print_function
import os
class StringPrinter:
while i < len:
val = (chars.cast(gdb.lookup_type ("gint64")) + (i * 2)).cast(gdb.lookup_type ("gunichar2").pointer ()).dereference ()
if val >= 256:
- c = "\u%X" % val
+ c = unichr (val)
else:
c = chr (val)
res.append (c)
if ns == "":
return name
else:
- return "%s.%s" % (ns, name)
+ return "{}.{}".format (ns, name)
class ArrayPrinter:
"Print a C# array"
def to_string(self):
obj = self.val.cast (gdb.lookup_type ("MonoArray").pointer ()).dereference ()
length = obj ['max_length']
- return "%s [%d]" % (stringify_class_name (self.class_ns, self.class_name [0:len(self.class_name) - 2]), int(length))
+ return "{} [{}]".format (stringify_class_name (self.class_ns, self.class_name [0:len(self.class_name) - 2]), int(length))
class ObjectPrinter:
"Print a C# object"
return (field.name, self.obj [field.name])
except:
# Superclass
- return (field.name, self.obj.cast (gdb.lookup_type ("%s" % (field.name))))
+ return (field.name, self.obj.cast (gdb.lookup_type ("{}".format (field.name))))
def children(self):
# FIXME: It would be easier if gdb.Value would support iteration itself
if class_name [-2:len(class_name)] == "[]":
return {}.__iter__ ()
try:
- gdb_type = gdb.lookup_type ("struct %s_%s" % (class_ns.replace (".", "_"), class_name))
+ gdb_type = gdb.lookup_type ("struct {}_{}".format (class_ns.replace (".", "_"), class_name))
return self._iterator(obj.cast (gdb_type))
except:
return {}.__iter__ ()
except:
- print sys.exc_info ()[0]
- print sys.exc_info ()[1]
+ print (sys.exc_info ()[0])
+ print (sys.exc_info ()[1])
return {}.__iter__ ()
def to_string(self):
return ArrayPrinter (self.val,class_ns,class_name).to_string ()
if class_ns != "":
try:
- gdb_type = gdb.lookup_type ("struct %s.%s" % (class_ns, class_name))
+ gdb_type = gdb.lookup_type ("struct {}.{}".format (class_ns, class_name))
except:
# Maybe there is no debug info for that type
- return "%s.%s" % (class_ns, class_name)
+ return "{}.{}".format (class_ns, class_name)
#return obj.cast (gdb_type)
- return "%s.%s" % (class_ns, class_name)
+ return "{}.{}".format (class_ns, class_name)
return class_name
except:
- print sys.exc_info ()[0]
- print sys.exc_info ()[1]
+ print (sys.exc_info ()[0])
+ print (sys.exc_info ()[1])
# FIXME: This can happen because we don't have liveness information
return self.val.cast (gdb.lookup_type ("guint64"))
val = self.val.dereference ()
klass = val ["klass"].dereference ()
class_name = stringify_class_name (klass ["name_space"].string (), klass ["name"].string ())
- return "\"%s:%s ()\"" % (class_name, val ["name"].string ())
+ return "\"{}:{} ()\"".format (class_name, val ["name"].string ())
# This returns more info but requires calling into the inferior
- #return "\"%s\"" % (gdb.parse_and_eval ("mono_method_full_name (%s, 1)" % (str (int (self.val.cast (gdb.lookup_type ("guint64")))))).string ())
+ #return "\"{}\"".format (gdb.parse_and_eval ("mono_method_full_name ({}, 1)".format (str (int (self.val.cast (gdb.lookup_type ("guint64")))))).string ())
class MonoClassPrinter:
"Print a MonoClass structure"
klass = self.val.dereference ()
class_name = stringify_class_name (klass ["name_space"].string (), klass ["name"].string ())
if add_quotes:
- return "\"%s\"" % (class_name)
+ return "\"{}\"".format (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")))))))
+ #return "\"{}\"".format (gdb.parse_and_eval ("mono_type_full_name (&((MonoClass*){})->byval_arg)".format (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]
+ #print (sys.exc_info ()[0])
+ #print (sys.exc_info ()[1])
return str(self.val.cast (gdb.lookup_type ("gpointer")))
class MonoGenericInstPrinter:
self.val = val
def to_string(self):
+ if int(self.val.cast (gdb.lookup_type ("guint64"))) == 0:
+ return "0x0"
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
+ # print (inst_args)
type_printer = MonoTypePrinter (inst_args [i])
if i > 0:
inst_str = inst_str + ", "
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)
+ return "{}, [{}], [{}]>".format (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]
+ #print (sys.exc_info ()[0])
+ #print (sys.exc_info ()[1])
return str(self.val.cast (gdb.lookup_type ("gpointer")))
class MonoTypePrinter:
def to_string_inner(self, csharp):
try:
- t = self.val.dereference ()
+ t = self.val.referenced_value ()
kind = str (t ["type"]).replace ("MONO_TYPE_", "").lower ()
info = ""
info = str(t ["data"]["generic_class"])
if info != "":
- return "{%s, %s}" % (kind, info)
+ return "{{{}, {}}}".format (kind, info)
else:
- return "{%s}" % (kind)
+ return "{{{}}}".format (kind)
except:
- #print sys.exc_info ()[0]
- #print sys.exc_info ()[1]
+ #print (sys.exc_info ()[0])
+ #print (sys.exc_info ()[1])
return str(self.val.cast (gdb.lookup_type ("gpointer")))
def to_string(self):
inst_args = inst ["type_argv"]
inst_str = ""
for i in range(0, inst_len):
- print inst_args
+ # 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)
+ return "MRGCTX[{}, [{}]]".format (klass_printer.to_string(), inst_str)
+
+class MonoVTablePrinter:
+ "Print a MonoVTable structure"
+
+ def __init__(self, val):
+ self.val = val
+
+ def to_string(self):
+ if int(self.val.cast (gdb.lookup_type ("guint64"))) == 0:
+ return "0x0"
+ vtable = self.val.dereference ()
+ klass = vtable ["klass"]
+ klass_printer = MonoClassPrinter (klass)
+
+ return "vtable({})".format (klass_printer.to_string ())
def lookup_pretty_printer(val):
t = str (val.type)
return ObjectPrinter (val)
if t == "string":
return StringPrinter (val)
+ if t == "MonoString *":
+ return StringPrinter (val)
if t == "MonoMethod *":
return MonoMethodPrinter (val)
if t == "MonoClass *":
return MonoGenericClassPrinter (val)
if t == "MonoMethodRuntimeGenericContext *":
return MonoMethodRgctxPrinter (val)
+ if t == "MonoVTable *":
+ return MonoVTablePrinter (val)
return None
def register_csharp_printers(obj):
gdb.execute ("set environment MONO_XDEBUG gdb")
-print "Mono support loaded."
+print ("Mono support loaded.")