python - examining memory in gdb pretty-printer -
i'm trying figure out how gdb pretty printing works in order create pretty printers display data structures in more compact, readable form, documentation seems pretty thin. starting exercise, tried create pretty printer sockaddr_in -- instead of printing umpteen different union variations in unreadable form, print in normal dotted notation.
i put following in .gdbinit
file:
python class sockaddr_in_printer(object): "print sockaddr_in" def __init__(self, val): self.val = val def to_string(self): addr = self.val['sin_addr'].address().cast(gdb.lookup_type("unsigned char *")) port = self.val['sin_port'].address().cast(gdb.lookup_type("unsigned char *")) rv = "" + addr.dereference() x in range(0,3): addr += 1 rv += "." rv += addr.dereference() pnum = port.dereference() * 256 port += 1 pnum += port.dereference() rv += ":" rv += pnum return rv; def find_pp(val): if val.type.tag == 'sockaddr_in': return sockaddr_in_printer(val) return none gdb.pretty_printers.append(find_pp) end
this seems load ok, when try print sockaddr_in, opaque error message:
(gdb) p srcaddr python exception <type 'exceptions.runtimeerror'> value not callable (not type_code_func).: $2 = (gdb)
any ideas going wrong?
anyone have pointers documentation writing/using/debugging gdb pretty printing functions? of above cribbed examples found around web, appears 'documentation' available.
edit
changing addr/port stuff to
addr = self.val['sin_addr'].address.cast(gdb.lookup_type("unsigned char").pointer()) port = self.val['sin_port'].address.cast(gdb.lookup_type("unsigned char").pointer())
fixes exception, leads to
(gdb) p src python exception <class 'gdb.error'> argument arithmetic operation not number or boolean.: $1 =
..still no line number info indicate problem is.
edit
after lots of random twiddling of code, figured out need:
python class sockaddr_in_printer(object): "print sockaddr_in" def __init__(self, val): self.val = val def to_string(self): ptr_type = gdb.lookup_type("unsigned char").pointer() addr = self.val['sin_addr'].address.cast(ptr_type) port = self.val['sin_port'].address.cast(ptr_type) rv = str(int(addr.dereference())) x in range(0,3): addr += 1 rv += "." rv += str(int(addr.dereference())) pnum = port.dereference() * 256 port += 1 pnum += port.dereference() rv += ":" rv += str(pnum) return rv; def find_pp(val): if val.type.tag == 'sockaddr_in': return sockaddr_in_printer(val) return none gdb.pretty_printers.append(find_pp) end
value.address property, not function. when write ".address()", telling gdb try make inferior function call. instead write ".address".
please file bug reports in gdb bugzilla documentation issues. current documentation written in "reference" style, adding examples worth doing.
Comments
Post a Comment