This is the mail archive of the
gdb@sourceware.org
mailing list for the GDB project.
Re: pretty print beginner question <solved>
After a few hours of hinting a got a simple result, puh! :-)
simple source the following file and all I need in my first steps is working now:
----
import gdb
import re
import pprint
class StdStringPrinter:
"Print a std::basic_string of some kind"
def __init__(self, val):
self.val = val
def to_string(self):
# Make sure &string works, too.
type = self.val.type
if type.code == gdb.TYPE_CODE_REF:
type = type.target ()
# Calculate the length of the string so that to_string returns
# the string according to length, not according to first null
# encountered.
ptr = self.val ['_M_dataplus']['_M_p']
realtype = type.unqualified ().strip_typedefs ()
reptype = gdb.lookup_type (str (realtype) + '::_Rep').pointer ()
header = ptr.cast(reptype) - 1
len = header.dereference ()['_M_length']
if hasattr(ptr, "lazy_string"):
return ptr.lazy_string (length = len)
return ptr.string (length = len)
def display_hint (self):
return 'string'
def lookup_function (val):
"Look-up and return a pretty-printer that can print val."
# Get the type.
type = val.type
# If it points to a reference, get the reference.
if type.code == gdb.TYPE_CODE_REF:
type = type.target ()
# Get the unqualified type, stripped of typedefs.
type = type.unqualified ().strip_typedefs ()
# Get the type name.
typename = type.tag
if typename == None:
return None
# Iterate over local dictionary of types to determine
# if a printer is registered for that type. Return an
# instantiation of the printer if found.
#print typename
for function in pretty_printers_dict:
if function.search (typename):
return pretty_printers_dict[function] (val)
# Cannot find a pretty printer. Return None.
return None
class DBZPrinter:
"jj"
def __init__(self, val):
self.val = val
def to_string(self):
type = self.val.type
if type.code == gdb.TYPE_CODE_REF:
type = type.target ()
#print self.val['banknr']
#print self.val['offset']
template_type = self.val.type.template_argument(0)
nn = gdb.parse_and_eval("basic_pointer");
print "############################"
print nn
print "############################"
ptr = self.val['offset'] + nn
#dptr = ptr.cast(gdb.lookup_type('A').pointer())
dptr = ptr.cast(template_type.pointer())
#print dptr.dereference()
#print "(A *) %s" % ( dptr );
return '(%s *) %s' % ( template_type, dptr );
#print dptr
def display_hint (self):
return 'dbz'
pretty_printers_dict = {}
pretty_printers_dict[re.compile('^std::basic_string<.*>$')] = lambda val: StdStringPrinter(val)
pretty_printers_dict[re.compile('^DBZ<.*>$')] = lambda val: DBZPrinter(val)
gdb.pretty_printers.append (lookup_function)
print "printers loaded"
----------------
As you can see we try to implement a special pointer type. The next step is to handle these pointer templates as normal pointers in gdb. Maybe there will come a lot more questions. Actually dereferencing them from ddd by double click is not possible. operator *() is present, but only 1 indirection is working. I will dig a bit deeper in it and will ask again.
Thanks!
Klaus
--
Empfehlen Sie GMX DSL Ihren Freunden und Bekannten und wir
belohnen Sie mit bis zu 50,- Euro! https://freundschaftswerbung.gmx.de