Home | History | Annotate | Download | only in gcc-4.9
      1 # Pretty-printers for libstdc++.
      2 
      3 # Copyright (C) 2008-2014 Free Software Foundation, Inc.
      4 
      5 # This program is free software; you can redistribute it and/or modify
      6 # it under the terms of the GNU General Public License as published by
      7 # the Free Software Foundation; either version 3 of the License, or
      8 # (at your option) any later version.
      9 #
     10 # This program is distributed in the hope that it will be useful,
     11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
     12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     13 # GNU General Public License for more details.
     14 #
     15 # You should have received a copy of the GNU General Public License
     16 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
     17 
     18 import gdb
     19 import itertools
     20 import re
     21 import sys
     22 
     23 ### Python 2 + Python 3 compatibility code
     24 
     25 # Resources about compatibility:
     26 #
     27 #  * <http://pythonhosted.org/six/>: Documentation of the "six" module
     28 
     29 # FIXME: The handling of e.g. std::basic_string (at least on char)
     30 # probably needs updating to work with Python 3's new string rules.
     31 #
     32 # In particular, Python 3 has a separate type (called byte) for
     33 # bytestrings, and a special b"" syntax for the byte literals; the old
     34 # str() type has been redefined to always store Unicode text.
     35 #
     36 # We probably can't do much about this until this GDB PR is addressed:
     37 # <https://sourceware.org/bugzilla/show_bug.cgi?id=17138>
     38 
     39 if sys.version_info[0] > 2:
     40     ### Python 3 stuff
     41     Iterator = object
     42     # Python 3 folds these into the normal functions.
     43     imap = map
     44     izip = zip
     45     # Also, int subsumes long
     46     long = int
     47 else:
     48     ### Python 2 stuff
     49     class Iterator:
     50         """Compatibility mixin for iterators
     51 
     52         Instead of writing next() methods for iterators, write
     53         __next__() methods and use this mixin to make them work in
     54         Python 2 as well as Python 3.
     55 
     56         Idea stolen from the "six" documentation:
     57         <http://pythonhosted.org/six/#six.Iterator>
     58         """
     59 
     60         def next(self):
     61             return self.__next__()
     62 
     63     # In Python 2, we still need these from itertools
     64     from itertools import imap, izip
     65 
     66 # Try to use the new-style pretty-printing if available.
     67 _use_gdb_pp = True
     68 try:
     69     import gdb.printing
     70 except ImportError:
     71     _use_gdb_pp = False
     72 
     73 # Try to install type-printers.
     74 _use_type_printing = False
     75 try:
     76     import gdb.types
     77     if hasattr(gdb.types, 'TypePrinter'):
     78         _use_type_printing = True
     79 except ImportError:
     80     pass
     81 
     82 # Starting with the type ORIG, search for the member type NAME.  This
     83 # handles searching upward through superclasses.  This is needed to
     84 # work around http://sourceware.org/bugzilla/show_bug.cgi?id=13615.
     85 def find_type(orig, name):
     86     typ = orig.strip_typedefs()
     87     while True:
     88         search = str(typ) + '::' + name
     89         try:
     90             return gdb.lookup_type(search)
     91         except RuntimeError:
     92             pass
     93         # The type was not found, so try the superclass.  We only need
     94         # to check the first superclass, so we don't bother with
     95         # anything fancier here.
     96         field = typ.fields()[0]
     97         if not field.is_base_class:
     98             raise ValueError("Cannot find type %s::%s" % (str(orig), name))
     99         typ = field.type
    100 
    101 class SharedPointerPrinter:
    102     "Print a shared_ptr or weak_ptr"
    103 
    104     def __init__ (self, typename, val):
    105         self.typename = typename
    106         self.val = val
    107 
    108     def to_string (self):
    109         state = 'empty'
    110         refcounts = self.val['_M_refcount']['_M_pi']
    111         if refcounts != 0:
    112             usecount = refcounts['_M_use_count']
    113             weakcount = refcounts['_M_weak_count']
    114             if usecount == 0:
    115                 state = 'expired, weak %d' % weakcount
    116             else:
    117                 state = 'count %d, weak %d' % (usecount, weakcount - 1)
    118         return '%s (%s) %s' % (self.typename, state, self.val['_M_ptr'])
    119 
    120 class UniquePointerPrinter:
    121     "Print a unique_ptr"
    122 
    123     def __init__ (self, typename, val):
    124         self.val = val
    125 
    126     def to_string (self):
    127         v = self.val['_M_t']['_M_head_impl']
    128         return ('std::unique_ptr<%s> containing %s' % (str(v.type.target()),
    129                                                        str(v)))
    130 
    131 class StdListPrinter:
    132     "Print a std::list"
    133 
    134     class _iterator(Iterator):
    135         def __init__(self, nodetype, head):
    136             self.nodetype = nodetype
    137             self.base = head['_M_next']
    138             self.head = head.address
    139             self.count = 0
    140 
    141         def __iter__(self):
    142             return self
    143 
    144         def __next__(self):
    145             if self.base == self.head:
    146                 raise StopIteration
    147             elt = self.base.cast(self.nodetype).dereference()
    148             self.base = elt['_M_next']
    149             count = self.count
    150             self.count = self.count + 1
    151             return ('[%d]' % count, elt['_M_data'])
    152 
    153     def __init__(self, typename, val):
    154         self.typename = typename
    155         self.val = val
    156 
    157     def children(self):
    158         nodetype = find_type(self.val.type, '_Node')
    159         nodetype = nodetype.strip_typedefs().pointer()
    160         return self._iterator(nodetype, self.val['_M_impl']['_M_node'])
    161 
    162     def to_string(self):
    163         if self.val['_M_impl']['_M_node'].address == self.val['_M_impl']['_M_node']['_M_next']:
    164             return 'empty %s' % (self.typename)
    165         return '%s' % (self.typename)
    166 
    167 class StdListIteratorPrinter:
    168     "Print std::list::iterator"
    169 
    170     def __init__(self, typename, val):
    171         self.val = val
    172         self.typename = typename
    173 
    174     def to_string(self):
    175         nodetype = find_type(self.val.type, '_Node')
    176         nodetype = nodetype.strip_typedefs().pointer()
    177         return self.val['_M_node'].cast(nodetype).dereference()['_M_data']
    178 
    179 class StdSlistPrinter:
    180     "Print a __gnu_cxx::slist"
    181 
    182     class _iterator(Iterator):
    183         def __init__(self, nodetype, head):
    184             self.nodetype = nodetype
    185             self.base = head['_M_head']['_M_next']
    186             self.count = 0
    187 
    188         def __iter__(self):
    189             return self
    190 
    191         def __next__(self):
    192             if self.base == 0:
    193                 raise StopIteration
    194             elt = self.base.cast(self.nodetype).dereference()
    195             self.base = elt['_M_next']
    196             count = self.count
    197             self.count = self.count + 1
    198             return ('[%d]' % count, elt['_M_data'])
    199 
    200     def __init__(self, typename, val):
    201         self.val = val
    202 
    203     def children(self):
    204         nodetype = find_type(self.val.type, '_Node')
    205         nodetype = nodetype.strip_typedefs().pointer()
    206         return self._iterator(nodetype, self.val)
    207 
    208     def to_string(self):
    209         if self.val['_M_head']['_M_next'] == 0:
    210             return 'empty __gnu_cxx::slist'
    211         return '__gnu_cxx::slist'
    212 
    213 class StdSlistIteratorPrinter:
    214     "Print __gnu_cxx::slist::iterator"
    215 
    216     def __init__(self, typename, val):
    217         self.val = val
    218 
    219     def to_string(self):
    220         nodetype = find_type(self.val.type, '_Node')
    221         nodetype = nodetype.strip_typedefs().pointer()
    222         return self.val['_M_node'].cast(nodetype).dereference()['_M_data']
    223 
    224 class StdVectorPrinter:
    225     "Print a std::vector"
    226 
    227     class _iterator(Iterator):
    228         def __init__ (self, start, finish, bitvec):
    229             self.bitvec = bitvec
    230             if bitvec:
    231                 self.item   = start['_M_p']
    232                 self.so     = start['_M_offset']
    233                 self.finish = finish['_M_p']
    234                 self.fo     = finish['_M_offset']
    235                 itype = self.item.dereference().type
    236                 self.isize = 8 * itype.sizeof
    237             else:
    238                 self.item = start
    239                 self.finish = finish
    240             self.count = 0
    241 
    242         def __iter__(self):
    243             return self
    244 
    245         def __next__(self):
    246             count = self.count
    247             self.count = self.count + 1
    248             if self.bitvec:
    249                 if self.item == self.finish and self.so >= self.fo:
    250                     raise StopIteration
    251                 elt = self.item.dereference()
    252                 if elt & (1 << self.so):
    253                     obit = 1
    254                 else:
    255                     obit = 0
    256                 self.so = self.so + 1
    257                 if self.so >= self.isize:
    258                     self.item = self.item + 1
    259                     self.so = 0
    260                 return ('[%d]' % count, obit)
    261             else:
    262                 if self.item == self.finish:
    263                     raise StopIteration
    264                 elt = self.item.dereference()
    265                 self.item = self.item + 1
    266                 return ('[%d]' % count, elt)
    267 
    268     def __init__(self, typename, val):
    269         self.typename = typename
    270         self.val = val
    271         self.is_bool = val.type.template_argument(0).code  == gdb.TYPE_CODE_BOOL
    272 
    273     def children(self):
    274         return self._iterator(self.val['_M_impl']['_M_start'],
    275                               self.val['_M_impl']['_M_finish'],
    276                               self.is_bool)
    277 
    278     def to_string(self):
    279         start = self.val['_M_impl']['_M_start']
    280         finish = self.val['_M_impl']['_M_finish']
    281         end = self.val['_M_impl']['_M_end_of_storage']
    282         if self.is_bool:
    283             start = self.val['_M_impl']['_M_start']['_M_p']
    284             so    = self.val['_M_impl']['_M_start']['_M_offset']
    285             finish = self.val['_M_impl']['_M_finish']['_M_p']
    286             fo     = self.val['_M_impl']['_M_finish']['_M_offset']
    287             itype = start.dereference().type
    288             bl = 8 * itype.sizeof
    289             length   = (bl - so) + bl * ((finish - start) - 1) + fo
    290             capacity = bl * (end - start)
    291             return ('%s<bool> of length %d, capacity %d'
    292                     % (self.typename, int (length), int (capacity)))
    293         else:
    294             return ('%s of length %d, capacity %d'
    295                     % (self.typename, int (finish - start), int (end - start)))
    296 
    297     def display_hint(self):
    298         return 'array'
    299 
    300 class StdVectorIteratorPrinter:
    301     "Print std::vector::iterator"
    302 
    303     def __init__(self, typename, val):
    304         self.val = val
    305 
    306     def to_string(self):
    307         return self.val['_M_current'].dereference()
    308 
    309 class StdTuplePrinter:
    310     "Print a std::tuple"
    311 
    312     class _iterator(Iterator):
    313         def __init__ (self, head):
    314             self.head = head
    315 
    316             # Set the base class as the initial head of the
    317             # tuple.
    318             nodes = self.head.type.fields ()
    319             if len (nodes) == 1:
    320                 # Set the actual head to the first pair.
    321                 self.head  = self.head.cast (nodes[0].type)
    322             elif len (nodes) != 0:
    323                 raise ValueError("Top of tuple tree does not consist of a single node.")
    324             self.count = 0
    325 
    326         def __iter__ (self):
    327             return self
    328 
    329         def __next__ (self):
    330             nodes = self.head.type.fields ()
    331             # Check for further recursions in the inheritance tree.
    332             if len (nodes) == 0:
    333                 raise StopIteration
    334             # Check that this iteration has an expected structure.
    335             if len (nodes) != 2:
    336                 raise ValueError("Cannot parse more than 2 nodes in a tuple tree.")
    337 
    338             # - Left node is the next recursion parent.
    339             # - Right node is the actual class contained in the tuple.
    340 
    341             # Process right node.
    342             impl = self.head.cast (nodes[1].type)
    343 
    344             # Process left node and set it as head.
    345             self.head  = self.head.cast (nodes[0].type)
    346             self.count = self.count + 1
    347 
    348             # Finally, check the implementation.  If it is
    349             # wrapped in _M_head_impl return that, otherwise return
    350             # the value "as is".
    351             fields = impl.type.fields ()
    352             if len (fields) < 1 or fields[0].name != "_M_head_impl":
    353                 return ('[%d]' % self.count, impl)
    354             else:
    355                 return ('[%d]' % self.count, impl['_M_head_impl'])
    356 
    357     def __init__ (self, typename, val):
    358         self.typename = typename
    359         self.val = val;
    360 
    361     def children (self):
    362         return self._iterator (self.val)
    363 
    364     def to_string (self):
    365         if len (self.val.type.fields ()) == 0:
    366             return 'empty %s' % (self.typename)
    367         return '%s containing' % (self.typename)
    368 
    369 class StdStackOrQueuePrinter:
    370     "Print a std::stack or std::queue"
    371 
    372     def __init__ (self, typename, val):
    373         self.typename = typename
    374         self.visualizer = gdb.default_visualizer(val['c'])
    375 
    376     def children (self):
    377         return self.visualizer.children()
    378 
    379     def to_string (self):
    380         return '%s wrapping: %s' % (self.typename,
    381                                     self.visualizer.to_string())
    382 
    383     def display_hint (self):
    384         if hasattr (self.visualizer, 'display_hint'):
    385             return self.visualizer.display_hint ()
    386         return None
    387 
    388 class RbtreeIterator(Iterator):
    389     def __init__(self, rbtree):
    390         self.size = rbtree['_M_t']['_M_impl']['_M_node_count']
    391         self.node = rbtree['_M_t']['_M_impl']['_M_header']['_M_left']
    392         self.count = 0
    393 
    394     def __iter__(self):
    395         return self
    396 
    397     def __len__(self):
    398         return int (self.size)
    399 
    400     def __next__(self):
    401         if self.count == self.size:
    402             raise StopIteration
    403         result = self.node
    404         self.count = self.count + 1
    405         if self.count < self.size:
    406             # Compute the next node.
    407             node = self.node
    408             if node.dereference()['_M_right']:
    409                 node = node.dereference()['_M_right']
    410                 while node.dereference()['_M_left']:
    411                     node = node.dereference()['_M_left']
    412             else:
    413                 parent = node.dereference()['_M_parent']
    414                 while node == parent.dereference()['_M_right']:
    415                     node = parent
    416                     parent = parent.dereference()['_M_parent']
    417                 if node.dereference()['_M_right'] != parent:
    418                     node = parent
    419             self.node = node
    420         return result
    421 
    422 def get_value_from_Rb_tree_node(node):
    423     """Returns the value held in an _Rb_tree_node<_Val>"""
    424     try:
    425         member = node.type.fields()[1].name
    426         if member == '_M_value_field':
    427             # C++03 implementation, node contains the value as a member
    428             return node['_M_value_field']
    429         elif member == '_M_storage':
    430             # C++11 implementation, node stores value in __aligned_buffer
    431             p = node['_M_storage']['_M_storage'].address
    432             p = p.cast(node.type.template_argument(0).pointer())
    433             return p.dereference()
    434     except:
    435         pass
    436     raise ValueError("Unsupported implementation for %s" % str(node.type))
    437 
    438 # This is a pretty printer for std::_Rb_tree_iterator (which is
    439 # std::map::iterator), and has nothing to do with the RbtreeIterator
    440 # class above.
    441 class StdRbtreeIteratorPrinter:
    442     "Print std::map::iterator"
    443 
    444     def __init__ (self, typename, val):
    445         self.val = val
    446         valtype = self.val.type.template_argument(0).strip_typedefs()
    447         nodetype = gdb.lookup_type('std::_Rb_tree_node<' + str(valtype) + '>')
    448         self.link_type = nodetype.strip_typedefs().pointer()
    449 
    450     def to_string (self):
    451         node = self.val['_M_node'].cast(self.link_type).dereference()
    452         return get_value_from_Rb_tree_node(node)
    453 
    454 class StdDebugIteratorPrinter:
    455     "Print a debug enabled version of an iterator"
    456 
    457     def __init__ (self, typename, val):
    458         self.val = val
    459 
    460     # Just strip away the encapsulating __gnu_debug::_Safe_iterator
    461     # and return the wrapped iterator value.
    462     def to_string (self):
    463         itype = self.val.type.template_argument(0)
    464         return self.val['_M_current'].cast(itype)
    465 
    466 class StdMapPrinter:
    467     "Print a std::map or std::multimap"
    468 
    469     # Turn an RbtreeIterator into a pretty-print iterator.
    470     class _iter(Iterator):
    471         def __init__(self, rbiter, type):
    472             self.rbiter = rbiter
    473             self.count = 0
    474             self.type = type
    475 
    476         def __iter__(self):
    477             return self
    478 
    479         def __next__(self):
    480             if self.count % 2 == 0:
    481                 n = next(self.rbiter)
    482                 n = n.cast(self.type).dereference()
    483                 n = get_value_from_Rb_tree_node(n)
    484                 self.pair = n
    485                 item = n['first']
    486             else:
    487                 item = self.pair['second']
    488             result = ('[%d]' % self.count, item)
    489             self.count = self.count + 1
    490             return result
    491 
    492     def __init__ (self, typename, val):
    493         self.typename = typename
    494         self.val = val
    495 
    496     def to_string (self):
    497         return '%s with %d elements' % (self.typename,
    498                                         len (RbtreeIterator (self.val)))
    499 
    500     def children (self):
    501         rep_type = find_type(self.val.type, '_Rep_type')
    502         node = find_type(rep_type, '_Link_type')
    503         node = node.strip_typedefs()
    504         return self._iter (RbtreeIterator (self.val), node)
    505 
    506     def display_hint (self):
    507         return 'map'
    508 
    509 class StdSetPrinter:
    510     "Print a std::set or std::multiset"
    511 
    512     # Turn an RbtreeIterator into a pretty-print iterator.
    513     class _iter(Iterator):
    514         def __init__(self, rbiter, type):
    515             self.rbiter = rbiter
    516             self.count = 0
    517             self.type = type
    518 
    519         def __iter__(self):
    520             return self
    521 
    522         def __next__(self):
    523             item = next(self.rbiter)
    524             item = item.cast(self.type).dereference()
    525             item = get_value_from_Rb_tree_node(item)
    526             # FIXME: this is weird ... what to do?
    527             # Maybe a 'set' display hint?
    528             result = ('[%d]' % self.count, item)
    529             self.count = self.count + 1
    530             return result
    531 
    532     def __init__ (self, typename, val):
    533         self.typename = typename
    534         self.val = val
    535 
    536     def to_string (self):
    537         return '%s with %d elements' % (self.typename,
    538                                         len (RbtreeIterator (self.val)))
    539 
    540     def children (self):
    541         rep_type = find_type(self.val.type, '_Rep_type')
    542         node = find_type(rep_type, '_Link_type')
    543         node = node.strip_typedefs()
    544         return self._iter (RbtreeIterator (self.val), node)
    545 
    546 class StdBitsetPrinter:
    547     "Print a std::bitset"
    548 
    549     def __init__(self, typename, val):
    550         self.typename = typename
    551         self.val = val
    552 
    553     def to_string (self):
    554         # If template_argument handled values, we could print the
    555         # size.  Or we could use a regexp on the type.
    556         return '%s' % (self.typename)
    557 
    558     def children (self):
    559         words = self.val['_M_w']
    560         wtype = words.type
    561 
    562         # The _M_w member can be either an unsigned long, or an
    563         # array.  This depends on the template specialization used.
    564         # If it is a single long, convert to a single element list.
    565         if wtype.code == gdb.TYPE_CODE_ARRAY:
    566             tsize = wtype.target ().sizeof
    567         else:
    568             words = [words]
    569             tsize = wtype.sizeof 
    570 
    571         nwords = wtype.sizeof / tsize
    572         result = []
    573         byte = 0
    574         while byte < nwords:
    575             w = words[byte]
    576             bit = 0
    577             while w != 0:
    578                 if (w & 1) != 0:
    579                     # Another spot where we could use 'set'?
    580                     result.append(('[%d]' % (byte * tsize * 8 + bit), 1))
    581                 bit = bit + 1
    582                 w = w >> 1
    583             byte = byte + 1
    584         return result
    585 
    586 class StdDequePrinter:
    587     "Print a std::deque"
    588 
    589     class _iter(Iterator):
    590         def __init__(self, node, start, end, last, buffer_size):
    591             self.node = node
    592             self.p = start
    593             self.end = end
    594             self.last = last
    595             self.buffer_size = buffer_size
    596             self.count = 0
    597 
    598         def __iter__(self):
    599             return self
    600 
    601         def __next__(self):
    602             if self.p == self.last:
    603                 raise StopIteration
    604 
    605             result = ('[%d]' % self.count, self.p.dereference())
    606             self.count = self.count + 1
    607 
    608             # Advance the 'cur' pointer.
    609             self.p = self.p + 1
    610             if self.p == self.end:
    611                 # If we got to the end of this bucket, move to the
    612                 # next bucket.
    613                 self.node = self.node + 1
    614                 self.p = self.node[0]
    615                 self.end = self.p + self.buffer_size
    616 
    617             return result
    618 
    619     def __init__(self, typename, val):
    620         self.typename = typename
    621         self.val = val
    622         self.elttype = val.type.template_argument(0)
    623         size = self.elttype.sizeof
    624         if size < 512:
    625             self.buffer_size = int (512 / size)
    626         else:
    627             self.buffer_size = 1
    628 
    629     def to_string(self):
    630         start = self.val['_M_impl']['_M_start']
    631         end = self.val['_M_impl']['_M_finish']
    632 
    633         delta_n = end['_M_node'] - start['_M_node'] - 1
    634         delta_s = start['_M_last'] - start['_M_cur']
    635         delta_e = end['_M_cur'] - end['_M_first']
    636 
    637         size = self.buffer_size * delta_n + delta_s + delta_e
    638 
    639         return '%s with %d elements' % (self.typename, long (size))
    640 
    641     def children(self):
    642         start = self.val['_M_impl']['_M_start']
    643         end = self.val['_M_impl']['_M_finish']
    644         return self._iter(start['_M_node'], start['_M_cur'], start['_M_last'],
    645                           end['_M_cur'], self.buffer_size)
    646 
    647     def display_hint (self):
    648         return 'array'
    649 
    650 class StdDequeIteratorPrinter:
    651     "Print std::deque::iterator"
    652 
    653     def __init__(self, typename, val):
    654         self.val = val
    655 
    656     def to_string(self):
    657         return self.val['_M_cur'].dereference()
    658 
    659 class StdStringPrinter:
    660     "Print a std::basic_string of some kind"
    661 
    662     def __init__(self, typename, val):
    663         self.val = val
    664 
    665     def to_string(self):
    666         # Make sure &string works, too.
    667         type = self.val.type
    668         if type.code == gdb.TYPE_CODE_REF:
    669             type = type.target ()
    670 
    671         # Calculate the length of the string so that to_string returns
    672         # the string according to length, not according to first null
    673         # encountered.
    674         ptr = self.val ['_M_dataplus']['_M_p']
    675         realtype = type.unqualified ().strip_typedefs ()
    676         reptype = gdb.lookup_type (str (realtype) + '::_Rep').pointer ()
    677         header = ptr.cast(reptype) - 1
    678         len = header.dereference ()['_M_length']
    679         if hasattr(ptr, "lazy_string"):
    680             return ptr.lazy_string (length = len)
    681         return ptr.string (length = len)
    682 
    683     def display_hint (self):
    684         return 'string'
    685 
    686 class Tr1HashtableIterator(Iterator):
    687     def __init__ (self, hash):
    688         self.buckets = hash['_M_buckets']
    689         self.bucket = 0
    690         self.bucket_count = hash['_M_bucket_count']
    691         self.node_type = find_type(hash.type, '_Node').pointer()
    692         self.node = 0
    693         while self.bucket != self.bucket_count:
    694             self.node = self.buckets[self.bucket]
    695             if self.node:
    696                 break
    697             self.bucket = self.bucket + 1        
    698 
    699     def __iter__ (self):
    700         return self
    701 
    702     def __next__ (self):
    703         if self.node == 0:
    704             raise StopIteration
    705         node = self.node.cast(self.node_type)
    706         result = node.dereference()['_M_v']
    707         self.node = node.dereference()['_M_next'];
    708         if self.node == 0:
    709             self.bucket = self.bucket + 1
    710             while self.bucket != self.bucket_count:
    711                 self.node = self.buckets[self.bucket]
    712                 if self.node:
    713                     break
    714                 self.bucket = self.bucket + 1
    715         return result
    716 
    717 class StdHashtableIterator(Iterator):
    718     def __init__(self, hash):
    719         self.node = hash['_M_before_begin']['_M_nxt']
    720         self.node_type = find_type(hash.type, '__node_type').pointer()
    721 
    722     def __iter__(self):
    723         return self
    724 
    725     def __next__(self):
    726         if self.node == 0:
    727             raise StopIteration
    728         elt = self.node.cast(self.node_type).dereference()
    729         self.node = elt['_M_nxt']
    730         valptr = elt['_M_storage'].address
    731         valptr = valptr.cast(elt.type.template_argument(0).pointer())
    732         return valptr.dereference()
    733 
    734 class Tr1UnorderedSetPrinter:
    735     "Print a tr1::unordered_set"
    736 
    737     def __init__ (self, typename, val):
    738         self.typename = typename
    739         self.val = val
    740 
    741     def hashtable (self):
    742         if self.typename.startswith('std::tr1'):
    743             return self.val
    744         return self.val['_M_h']
    745 
    746     def to_string (self):
    747         return '%s with %d elements' % (self.typename, self.hashtable()['_M_element_count'])
    748 
    749     @staticmethod
    750     def format_count (i):
    751         return '[%d]' % i
    752 
    753     def children (self):
    754         counter = imap (self.format_count, itertools.count())
    755         if self.typename.startswith('std::tr1'):
    756             return izip (counter, Tr1HashtableIterator (self.hashtable()))
    757         return izip (counter, StdHashtableIterator (self.hashtable()))
    758 
    759 class Tr1UnorderedMapPrinter:
    760     "Print a tr1::unordered_map"
    761 
    762     def __init__ (self, typename, val):
    763         self.typename = typename
    764         self.val = val
    765 
    766     def hashtable (self):
    767         if self.typename.startswith('std::tr1'):
    768             return self.val
    769         return self.val['_M_h']
    770 
    771     def to_string (self):
    772         return '%s with %d elements' % (self.typename, self.hashtable()['_M_element_count'])
    773 
    774     @staticmethod
    775     def flatten (list):
    776         for elt in list:
    777             for i in elt:
    778                 yield i
    779 
    780     @staticmethod
    781     def format_one (elt):
    782         return (elt['first'], elt['second'])
    783 
    784     @staticmethod
    785     def format_count (i):
    786         return '[%d]' % i
    787 
    788     def children (self):
    789         counter = imap (self.format_count, itertools.count())
    790         # Map over the hash table and flatten the result.
    791         if self.typename.startswith('std::tr1'):
    792             data = self.flatten (imap (self.format_one, Tr1HashtableIterator (self.hashtable())))
    793             # Zip the two iterators together.
    794             return izip (counter, data)
    795         data = self.flatten (imap (self.format_one, StdHashtableIterator (self.hashtable())))
    796         # Zip the two iterators together.
    797         return izip (counter, data)
    798         
    799 
    800     def display_hint (self):
    801         return 'map'
    802 
    803 class StdForwardListPrinter:
    804     "Print a std::forward_list"
    805 
    806     class _iterator(Iterator):
    807         def __init__(self, nodetype, head):
    808             self.nodetype = nodetype
    809             self.base = head['_M_next']
    810             self.count = 0
    811 
    812         def __iter__(self):
    813             return self
    814 
    815         def __next__(self):
    816             if self.base == 0:
    817                 raise StopIteration
    818             elt = self.base.cast(self.nodetype).dereference()
    819             self.base = elt['_M_next']
    820             count = self.count
    821             self.count = self.count + 1
    822             valptr = elt['_M_storage'].address
    823             valptr = valptr.cast(elt.type.template_argument(0).pointer())
    824             return ('[%d]' % count, valptr.dereference())
    825 
    826     def __init__(self, typename, val):
    827         self.val = val
    828         self.typename = typename
    829 
    830     def children(self):
    831         nodetype = find_type(self.val.type, '_Node')
    832         nodetype = nodetype.strip_typedefs().pointer()
    833         return self._iterator(nodetype, self.val['_M_impl']['_M_head'])
    834 
    835     def to_string(self):
    836         if self.val['_M_impl']['_M_head']['_M_next'] == 0:
    837             return 'empty %s' % (self.typename)
    838         return '%s' % (self.typename)
    839 
    840 
    841 # A "regular expression" printer which conforms to the
    842 # "SubPrettyPrinter" protocol from gdb.printing.
    843 class RxPrinter(object):
    844     def __init__(self, name, function):
    845         super(RxPrinter, self).__init__()
    846         self.name = name
    847         self.function = function
    848         self.enabled = True
    849 
    850     def invoke(self, value):
    851         if not self.enabled:
    852             return None
    853 
    854         if value.type.code == gdb.TYPE_CODE_REF:
    855             if hasattr(gdb.Value,"referenced_value"):
    856                 value = value.referenced_value()
    857 
    858         return self.function(self.name, value)
    859 
    860 # A pretty-printer that conforms to the "PrettyPrinter" protocol from
    861 # gdb.printing.  It can also be used directly as an old-style printer.
    862 class Printer(object):
    863     def __init__(self, name):
    864         super(Printer, self).__init__()
    865         self.name = name
    866         self.subprinters = []
    867         self.lookup = {}
    868         self.enabled = True
    869         self.compiled_rx = re.compile('^([a-zA-Z0-9_:]+)<.*>$')
    870 
    871     def add(self, name, function):
    872         # A small sanity check.
    873         # FIXME
    874         if not self.compiled_rx.match(name + '<>'):
    875             raise ValueError('libstdc++ programming error: "%s" does not match' % name)
    876         printer = RxPrinter(name, function)
    877         self.subprinters.append(printer)
    878         self.lookup[name] = printer
    879 
    880     # Add a name using _GLIBCXX_BEGIN_NAMESPACE_VERSION.
    881     def add_version(self, base, name, function):
    882         self.add(base + name, function)
    883         self.add(base + '__7::' + name, function)
    884 
    885     # Add a name using _GLIBCXX_BEGIN_NAMESPACE_CONTAINER.
    886     def add_container(self, base, name, function):
    887         self.add_version(base, name, function)
    888         self.add_version(base + '__cxx1998::', name, function)
    889 
    890     @staticmethod
    891     def get_basic_type(type):
    892         # If it points to a reference, get the reference.
    893         if type.code == gdb.TYPE_CODE_REF:
    894             type = type.target ()
    895 
    896         # Get the unqualified type, stripped of typedefs.
    897         type = type.unqualified ().strip_typedefs ()
    898 
    899         return type.tag
    900 
    901     def __call__(self, val):
    902         typename = self.get_basic_type(val.type)
    903         if not typename:
    904             return None
    905 
    906         # All the types we match are template types, so we can use a
    907         # dictionary.
    908         match = self.compiled_rx.match(typename)
    909         if not match:
    910             return None
    911 
    912         basename = match.group(1)
    913 
    914         if val.type.code == gdb.TYPE_CODE_REF:
    915             if hasattr(gdb.Value,"referenced_value"):
    916                 val = val.referenced_value()
    917 
    918         if basename in self.lookup:
    919             return self.lookup[basename].invoke(val)
    920 
    921         # Cannot find a pretty printer.  Return None.
    922         return None
    923 
    924 libstdcxx_printer = None
    925 
    926 class FilteringTypePrinter(object):
    927     def __init__(self, match, name):
    928         self.match = match
    929         self.name = name
    930         self.enabled = True
    931 
    932     class _recognizer(object):
    933         def __init__(self, match, name):
    934             self.match = match
    935             self.name = name
    936             self.type_obj = None
    937 
    938         def recognize(self, type_obj):
    939             if type_obj.tag is None:
    940                 return None
    941 
    942             if self.type_obj is None:
    943                 if not self.match in type_obj.tag:
    944                     # Filter didn't match.
    945                     return None
    946                 try:
    947                     self.type_obj = gdb.lookup_type(self.name).strip_typedefs()
    948                 except:
    949                     pass
    950             if self.type_obj == type_obj:
    951                 return self.name
    952             return None
    953 
    954     def instantiate(self):
    955         return self._recognizer(self.match, self.name)
    956 
    957 def add_one_type_printer(obj, match, name):
    958     printer = FilteringTypePrinter(match, 'std::' + name)
    959     gdb.types.register_type_printer(obj, printer)
    960 
    961 def register_type_printers(obj):
    962     global _use_type_printing
    963 
    964     if not _use_type_printing:
    965         return
    966 
    967     for pfx in ('', 'w'):
    968         add_one_type_printer(obj, 'basic_string', pfx + 'string')
    969         add_one_type_printer(obj, 'basic_ios', pfx + 'ios')
    970         add_one_type_printer(obj, 'basic_streambuf', pfx + 'streambuf')
    971         add_one_type_printer(obj, 'basic_istream', pfx + 'istream')
    972         add_one_type_printer(obj, 'basic_ostream', pfx + 'ostream')
    973         add_one_type_printer(obj, 'basic_iostream', pfx + 'iostream')
    974         add_one_type_printer(obj, 'basic_stringbuf', pfx + 'stringbuf')
    975         add_one_type_printer(obj, 'basic_istringstream',
    976                                  pfx + 'istringstream')
    977         add_one_type_printer(obj, 'basic_ostringstream',
    978                                  pfx + 'ostringstream')
    979         add_one_type_printer(obj, 'basic_stringstream',
    980                                  pfx + 'stringstream')
    981         add_one_type_printer(obj, 'basic_filebuf', pfx + 'filebuf')
    982         add_one_type_printer(obj, 'basic_ifstream', pfx + 'ifstream')
    983         add_one_type_printer(obj, 'basic_ofstream', pfx + 'ofstream')
    984         add_one_type_printer(obj, 'basic_fstream', pfx + 'fstream')
    985         add_one_type_printer(obj, 'basic_regex', pfx + 'regex')
    986         add_one_type_printer(obj, 'sub_match', pfx + 'csub_match')
    987         add_one_type_printer(obj, 'sub_match', pfx + 'ssub_match')
    988         add_one_type_printer(obj, 'match_results', pfx + 'cmatch')
    989         add_one_type_printer(obj, 'match_results', pfx + 'smatch')
    990         add_one_type_printer(obj, 'regex_iterator', pfx + 'cregex_iterator')
    991         add_one_type_printer(obj, 'regex_iterator', pfx + 'sregex_iterator')
    992         add_one_type_printer(obj, 'regex_token_iterator',
    993                                  pfx + 'cregex_token_iterator')
    994         add_one_type_printer(obj, 'regex_token_iterator',
    995                                  pfx + 'sregex_token_iterator')
    996 
    997     # Note that we can't have a printer for std::wstreampos, because
    998     # it shares the same underlying type as std::streampos.
    999     add_one_type_printer(obj, 'fpos', 'streampos')
   1000     add_one_type_printer(obj, 'basic_string', 'u16string')
   1001     add_one_type_printer(obj, 'basic_string', 'u32string')
   1002 
   1003     for dur in ('nanoseconds', 'microseconds', 'milliseconds',
   1004                 'seconds', 'minutes', 'hours'):
   1005         add_one_type_printer(obj, 'duration', dur)
   1006 
   1007     add_one_type_printer(obj, 'linear_congruential_engine', 'minstd_rand0')
   1008     add_one_type_printer(obj, 'linear_congruential_engine', 'minstd_rand')
   1009     add_one_type_printer(obj, 'mersenne_twister_engine', 'mt19937')
   1010     add_one_type_printer(obj, 'mersenne_twister_engine', 'mt19937_64')
   1011     add_one_type_printer(obj, 'subtract_with_carry_engine', 'ranlux24_base')
   1012     add_one_type_printer(obj, 'subtract_with_carry_engine', 'ranlux48_base')
   1013     add_one_type_printer(obj, 'discard_block_engine', 'ranlux24')
   1014     add_one_type_printer(obj, 'discard_block_engine', 'ranlux48')
   1015     add_one_type_printer(obj, 'shuffle_order_engine', 'knuth_b')
   1016 
   1017 def register_libstdcxx_printers (obj):
   1018     "Register libstdc++ pretty-printers with objfile Obj."
   1019 
   1020     global _use_gdb_pp
   1021     global libstdcxx_printer
   1022 
   1023     if _use_gdb_pp:
   1024         gdb.printing.register_pretty_printer(obj, libstdcxx_printer)
   1025     else:
   1026         if obj is None:
   1027             obj = gdb
   1028         obj.pretty_printers.append(libstdcxx_printer)
   1029 
   1030     register_type_printers(obj)
   1031 
   1032 def build_libstdcxx_dictionary ():
   1033     global libstdcxx_printer
   1034 
   1035     libstdcxx_printer = Printer("libstdc++-v6")
   1036 
   1037     # For _GLIBCXX_BEGIN_NAMESPACE_VERSION.
   1038     vers = '(__7::)?'
   1039     # For _GLIBCXX_BEGIN_NAMESPACE_CONTAINER.
   1040     container = '(__cxx1998::' + vers + ')?'
   1041 
   1042     # libstdc++ objects requiring pretty-printing.
   1043     # In order from:
   1044     # http://gcc.gnu.org/onlinedocs/libstdc++/latest-doxygen/a01847.html
   1045     libstdcxx_printer.add_version('std::', 'basic_string', StdStringPrinter)
   1046     libstdcxx_printer.add_container('std::', 'bitset', StdBitsetPrinter)
   1047     libstdcxx_printer.add_container('std::', 'deque', StdDequePrinter)
   1048     libstdcxx_printer.add_container('std::', 'list', StdListPrinter)
   1049     libstdcxx_printer.add_container('std::', 'map', StdMapPrinter)
   1050     libstdcxx_printer.add_container('std::', 'multimap', StdMapPrinter)
   1051     libstdcxx_printer.add_container('std::', 'multiset', StdSetPrinter)
   1052     libstdcxx_printer.add_version('std::', 'priority_queue',
   1053                                   StdStackOrQueuePrinter)
   1054     libstdcxx_printer.add_version('std::', 'queue', StdStackOrQueuePrinter)
   1055     libstdcxx_printer.add_version('std::', 'tuple', StdTuplePrinter)
   1056     libstdcxx_printer.add_container('std::', 'set', StdSetPrinter)
   1057     libstdcxx_printer.add_version('std::', 'stack', StdStackOrQueuePrinter)
   1058     libstdcxx_printer.add_version('std::', 'unique_ptr', UniquePointerPrinter)
   1059     libstdcxx_printer.add_container('std::', 'vector', StdVectorPrinter)
   1060     # vector<bool>
   1061 
   1062     # Printer registrations for classes compiled with -D_GLIBCXX_DEBUG.
   1063     libstdcxx_printer.add('std::__debug::bitset', StdBitsetPrinter)
   1064     libstdcxx_printer.add('std::__debug::deque', StdDequePrinter)
   1065     libstdcxx_printer.add('std::__debug::list', StdListPrinter)
   1066     libstdcxx_printer.add('std::__debug::map', StdMapPrinter)
   1067     libstdcxx_printer.add('std::__debug::multimap', StdMapPrinter)
   1068     libstdcxx_printer.add('std::__debug::multiset', StdSetPrinter)
   1069     libstdcxx_printer.add('std::__debug::priority_queue',
   1070                           StdStackOrQueuePrinter)
   1071     libstdcxx_printer.add('std::__debug::queue', StdStackOrQueuePrinter)
   1072     libstdcxx_printer.add('std::__debug::set', StdSetPrinter)
   1073     libstdcxx_printer.add('std::__debug::stack', StdStackOrQueuePrinter)
   1074     libstdcxx_printer.add('std::__debug::unique_ptr', UniquePointerPrinter)
   1075     libstdcxx_printer.add('std::__debug::vector', StdVectorPrinter)
   1076 
   1077     # These are the TR1 and C++0x printers.
   1078     # For array - the default GDB pretty-printer seems reasonable.
   1079     libstdcxx_printer.add_version('std::', 'shared_ptr', SharedPointerPrinter)
   1080     libstdcxx_printer.add_version('std::', 'weak_ptr', SharedPointerPrinter)
   1081     libstdcxx_printer.add_container('std::', 'unordered_map',
   1082                                     Tr1UnorderedMapPrinter)
   1083     libstdcxx_printer.add_container('std::', 'unordered_set',
   1084                                     Tr1UnorderedSetPrinter)
   1085     libstdcxx_printer.add_container('std::', 'unordered_multimap',
   1086                                     Tr1UnorderedMapPrinter)
   1087     libstdcxx_printer.add_container('std::', 'unordered_multiset',
   1088                                     Tr1UnorderedSetPrinter)
   1089     libstdcxx_printer.add_container('std::', 'forward_list',
   1090                                     StdForwardListPrinter)
   1091 
   1092     libstdcxx_printer.add_version('std::tr1::', 'shared_ptr', SharedPointerPrinter)
   1093     libstdcxx_printer.add_version('std::tr1::', 'weak_ptr', SharedPointerPrinter)
   1094     libstdcxx_printer.add_version('std::tr1::', 'unordered_map',
   1095                                   Tr1UnorderedMapPrinter)
   1096     libstdcxx_printer.add_version('std::tr1::', 'unordered_set',
   1097                                   Tr1UnorderedSetPrinter)
   1098     libstdcxx_printer.add_version('std::tr1::', 'unordered_multimap',
   1099                                   Tr1UnorderedMapPrinter)
   1100     libstdcxx_printer.add_version('std::tr1::', 'unordered_multiset',
   1101                                   Tr1UnorderedSetPrinter)
   1102 
   1103     # These are the C++0x printer registrations for -D_GLIBCXX_DEBUG cases.
   1104     # The tr1 namespace printers do not seem to have any debug
   1105     # equivalents, so do no register them.
   1106     libstdcxx_printer.add('std::__debug::unordered_map',
   1107                           Tr1UnorderedMapPrinter)
   1108     libstdcxx_printer.add('std::__debug::unordered_set',
   1109                           Tr1UnorderedSetPrinter)
   1110     libstdcxx_printer.add('std::__debug::unordered_multimap',
   1111                           Tr1UnorderedMapPrinter)
   1112     libstdcxx_printer.add('std::__debug::unordered_multiset',
   1113                           Tr1UnorderedSetPrinter)
   1114     libstdcxx_printer.add('std::__debug::forward_list',
   1115                           StdForwardListPrinter)
   1116 
   1117 
   1118     # Extensions.
   1119     libstdcxx_printer.add_version('__gnu_cxx::', 'slist', StdSlistPrinter)
   1120 
   1121     if True:
   1122         # These shouldn't be necessary, if GDB "print *i" worked.
   1123         # But it often doesn't, so here they are.
   1124         libstdcxx_printer.add_container('std::', '_List_iterator',
   1125                                         StdListIteratorPrinter)
   1126         libstdcxx_printer.add_container('std::', '_List_const_iterator',
   1127                                         StdListIteratorPrinter)
   1128         libstdcxx_printer.add_version('std::', '_Rb_tree_iterator',
   1129                                       StdRbtreeIteratorPrinter)
   1130         libstdcxx_printer.add_version('std::', '_Rb_tree_const_iterator',
   1131                                       StdRbtreeIteratorPrinter)
   1132         libstdcxx_printer.add_container('std::', '_Deque_iterator',
   1133                                         StdDequeIteratorPrinter)
   1134         libstdcxx_printer.add_container('std::', '_Deque_const_iterator',
   1135                                         StdDequeIteratorPrinter)
   1136         libstdcxx_printer.add_version('__gnu_cxx::', '__normal_iterator',
   1137                                       StdVectorIteratorPrinter)
   1138         libstdcxx_printer.add_version('__gnu_cxx::', '_Slist_iterator',
   1139                                       StdSlistIteratorPrinter)
   1140 
   1141         # Debug (compiled with -D_GLIBCXX_DEBUG) printer
   1142         # registrations.  The Rb_tree debug iterator when unwrapped
   1143         # from the encapsulating __gnu_debug::_Safe_iterator does not
   1144         # have the __norm namespace. Just use the existing printer
   1145         # registration for that.
   1146         libstdcxx_printer.add('__gnu_debug::_Safe_iterator',
   1147                               StdDebugIteratorPrinter)
   1148         libstdcxx_printer.add('std::__norm::_List_iterator',
   1149                               StdListIteratorPrinter)
   1150         libstdcxx_printer.add('std::__norm::_List_const_iterator',
   1151                               StdListIteratorPrinter)
   1152         libstdcxx_printer.add('std::__norm::_Deque_const_iterator',
   1153                               StdDequeIteratorPrinter)
   1154         libstdcxx_printer.add('std::__norm::_Deque_iterator',
   1155                               StdDequeIteratorPrinter)
   1156 
   1157 build_libstdcxx_dictionary ()
   1158