This is the mail archive of the gdb@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]