Author: Antonio Cuni <anto.c...@gmail.com> Branch: Changeset: r46255:d5704088efa9 Date: 2011-08-03 19:54 +0200 http://bitbucket.org/pypy/pypy/changeset/d5704088efa9/
Log: a macro for gdb which gives you the rpython type of an expression diff --git a/pypy/tool/gdb_pypy.py b/pypy/tool/gdb_pypy.py new file mode 100644 --- /dev/null +++ b/pypy/tool/gdb_pypy.py @@ -0,0 +1,78 @@ +""" +Some convenience macros for gdb. Load them by putting this file somewhere in +the path and then, from gdb: + +(gdb) python import pypy_gdb + +Or, alternatively: + +(gdb) python execfile('/path/to/pypy_gdb.py') +""" + +import sys +import gdb + +def load_typeids(): + """ + Returns a mapping offset --> description + """ + typeids = {} + for line in open('typeids.txt'): + member, descr = map(str.strip, line.split(None, 1)) + expr = "((char*)(&pypy_g_typeinfo.%s)) - (char*)&pypy_g_typeinfo" % member + offset = int(gdb.parse_and_eval(expr)) + typeids[offset] = descr + return typeids + +class RPyType (gdb.Command): + """ + Prints the RPython type of the expression (remember to dereference it!) + It assumes to find ``typeids.txt`` in the current directory. + E.g.: + + (gdb) rpy_type *l_v123 + GcStruct pypy.foo.Bar { super, inst_xxx, inst_yyy } + """ + + def __init__(self): + gdb.Command.__init__(self, "rpy_type", gdb.COMMAND_NONE) + + ## # some magic code to automatically reload the python file while developing + ## def invoke(self, arg, from_tty): + ## sys.path.insert(0, '') + ## import gdb_pypy + ## reload(gdb_pypy) + ## self.__class__ = gdb_pypy.RPyType + ## self.do_invoke(arg, from_tty) + + def invoke(self, arg, from_tty): + obj = gdb.parse_and_eval(arg) + hdr = self.get_gc_header(obj) + tid = hdr['h_tid'] + offset = tid & 0xFFFFFFFF # 64bit only + offset = int(offset) # convert from gdb.Value to python int + typeids = load_typeids() + if offset in typeids: + print typeids[offset] + else: + print 'Cannot find the type with offset %d' % offset + + def get_first_field_if(self, obj, suffix): + ctype = obj.type + field = ctype.fields()[0] + if field.name.endswith(suffix): + return obj[field.name] + return None + + def get_super(self, obj): + return self.get_first_field_if(obj, '_super') + + def get_gc_header(self, obj): + while True: + sup = self.get_super(obj) + if sup is None: + break + obj = sup + return self.get_first_field_if(obj, '_gcheader') + +RPyType() # side effects _______________________________________________ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit