This is the mail archive of the gdb-patches@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: [rfc] expose gdb values to python


>>>>> "Daniel" == Daniel Jacobowitz <drow@false.org> writes:

Daniel> WDYT about making this work anyway - and using a documented namespace
Daniel> for any methods we add?  Then the common case will be able to use the
Daniel> attributes safely.

In practice, I don't mind how it works now.  I wrote a few
pretty-printers (appended for your viewing pleasure) and I found that
the array syntax is not a real impediment.  If anything, the
dereference method is more of a pain.

FYI -- on the current python branch, Value already has a few more
methods: address, cast, and type.

I guess I wouldn't mind a mangling scheme if it were unobtrusive enough.

Tom

# Pretty-printers for libstc++.

def printstdlist(val):
    "Print a std::list"
    itype = val.type().template_argument(0)
    nodetype = gdb.Type('std::_List_node<%s>' % itype).pointer()
    head = val['_M_impl']['_M_node']
    base = head['_M_next']
    head = head.address()
    max = gdb.get_parameter('print elements')
    n = 0
    result = []
    while base != head and (max == 0 or n < max):
        elt = base.cast(nodetype).dereference()
        datum = elt['_M_data']
        result.append ('[%d] = %s' % (n, str (datum)))
        n = n + 1
        base = elt['_M_next']
    if len (result) == 0:
        result.append('<<empty list>>')
    return "\n".join(result)

def printstdvector(val):
    "Print a std::vector"
    start = val['_M_impl']['_M_start']
    finish = val['_M_impl']['_M_finish']
    end = val['_M_impl']['_M_end_of_storage']
    max = gdb.get_parameter('print elements')
    result = []
    result.append('std::vector of length %d, capacity %d'
                  % (int (finish - start), int (end - start)))
    i = 0
    while start < finish and (max == 0 or i < max):
        result.append('[%d] = %s' % (i, str(start.dereference())))
        start = start + 1
        i = i + 1
    return "\n".join(result)

def printstdstack(val):
    "Print a std::stack or std::queue"
    # Maybe we should print stack and queue in opposite orders?
    cur = val['c']['_M_impl']['_M_start']['_M_cur']
    finish = val['c']['_M_impl']['_M_finish']['_M_cur']
    i = 0
    max = gdb.get_parameter('print elements')
    result = ['std::stack or std::queue of size %d' % int (finish -cur)]
    while cur != finish and (max == 0 or i < max):
        result.append('[%d] = %s' % (i, str (cur.dereference())))
        cur = cur + 1
        i = i + 1
    return "\n".join(result)

def rbtree_to_list(val):
    "Turn an rbtree into a size and a list of elements."
    maxprint = gdb.get_parameter('print elements')
    size = val['_M_t']['_M_impl']['_M_node_count']
    if maxprint == 0 or maxprint > size:
        maxprint = size
    node = val['_M_t']['_M_impl']['_M_header']['_M_left']
    i = 0
    result = []
    while i < maxprint:
        result.append(node)
        if node.dereference()['_M_right']:
            node = node.dereference()['_M_right']
            while node.dereference()['_M_left']:
                node = node.dereference()['_M_left']
        else:
            parent = node.dereference()['_M_parent']
            while node == parent.dereference()['_M_right']:
                node = parent
                parent = parent.dereference()['_M_parent']
            if node.dereference()['_M_right'] != parent:
                node = parent
        i = i + 1
    return (size, result)

def printstdmap(val):
    "Print a std::map"
    keytype = val.type().template_argument(0)
    valuetype = val.type().template_argument(1)
    nodetype = gdb.Type('std::_Rb_tree_node< std::pair< const %s, %s > >' % (keytype, valuetype))
    nodetype = nodetype.pointer()
    (size, nodes) = rbtree_to_list (val)
    result = ['std::map with %d elements' % int (size)]
    for node in nodes:
        pair = node.cast(nodetype).dereference()['_M_value_field']
        result.append('[%s] = %s' % (str (pair['first']), str (pair['second'])))
    return "\n".join(result)

def printstdset(val):
    "Print a std::set"
    keytype = val.type().template_argument(0)
    nodetype = gdb.Type("std::_Rb_tree_node< %s >" % keytype).pointer()
    (size, nodes) = rbtree_to_list (val)
    result = ['std::set with %d elements' % int (size)]
    for node in nodes:
        elt = node.cast(nodetype).dereference()['_M_value_field']
        result.append('  %s' % str (elt))
    return "\n".join(result)

def printstdstring(val):
    "Print a std::string"
    return val['_M_dataplus']['_M_p']

gdb.pretty_printers['^std::list<.*>$'] = printstdlist
gdb.pretty_printers['^std::vector<.*>$'] = printstdvector
gdb.pretty_printers['^std::map<.*>$'] = printstdmap
gdb.pretty_printers['^std::set<.*>$'] = printstdset
gdb.pretty_printers['^std::basic_string<char.*>$'] = printstdstring
gdb.pretty_printers['^std::stack<.*>$'] = printstdstack
gdb.pretty_printers['^std::queue<.*>$'] = printstdstack


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