0

I want to add new pretty printers by updating the existing printers.py file of my std::pretty printers OR boost::prettyprinters. They were setup appropriately using the below links: https://sourceware.org/gdb/wiki/STLSupport https://github.com/ruediger/Boost-Pretty-Printer

I have also gone through their tutorial to add new printers, but somehow failed to get a good understanding. Had a chance to look into similar threads too: pretty printing boost::mpl::string<...> types in gdb and Pretty printing boost::unordered_map on gdb

It would be great to know how to add the above boost::unorder_map registered in my printers.py file. I did the below modification to the printers.py file in my boost directory

@_register_printer
class BoostUnorderedMapPrinter:
"Pretty printer for a boost::unordered_map"
printer_name = 'boost::unordered_map'
version = '1.40'
type_name_re = '^boost::unordered_map$'

class _iterator:
    def __init__ (self, fields):
        type_1 = fields.val.type.template_argument(0)
        type_2 = fields.val.type.template_argument(1)
        self.buckets = fields.val['table_']['buckets_']
        self.bucket_count = fields.val['table_']['bucket_count_']
        self.current_bucket = 0
        pair = "std::pair<%s const, %s>" % (type_1, type_2)
        self.pair_pointer = gdb.lookup_type(pair).pointer()
        self.base_pointer = gdb.lookup_type("boost::unordered_detail::value_base< %s >" % pair).pointer()
        self.node_pointer = gdb.lookup_type("boost::unordered_detail::hash_node<std::allocator< %s >, boost::unordered_detail::ungrouped>" % pair).pointer()
        self.node = self.buckets[self.current_bucket]['next_']

    def __iter__(self):
        return self

    def next(self):
        while not self.node:
            self.current_bucket = self.current_bucket + 1
            if self.current_bucket >= self.bucket_count:
                raise StopIteration
            self.node = self.buckets[self.current_bucket]['next_']

        iterator = self.node.cast(self.node_pointer).cast(self.base_pointer).cast(self.pair_pointer).dereference()   
        self.node = self.node['next_']

        return ('%s' % iterator['first'], iterator['second'])

def __init__(self, val):
    self.val = val

def children(self):
    return self._iterator(self)

def to_string(self):
    return "boost::unordered_map"

Somehow, it doesnt seem to identify this class.

Thanks in advance

Community
  • 1
  • 1
Spooferman
  • 353
  • 1
  • 5
  • 15

2 Answers2

0

The boost printing code on github uses a decorator to note that a given printer should be registered and then some fields in the class to control registration:

@_register_printer
class BoostIteratorRange:
...
printer_name = 'boost::iterator_range'
version = '1.40'
type_name_re = '^boost::iterator_range<.*>$'

So I suppose you could add those to the example code given in the other SO post to set things up.

Alternatively you could just write the registration code by hand yourself.

Tom Tromey
  • 21,507
  • 2
  • 45
  • 63
  • I made changes to the printers.py file in the boost directory as seen above(edited section), but still my unordered map does not print understandable result. Am i doing anything wrong? – Spooferman Feb 12 '14 at 11:34
0

Might not be the best way, but it works for quick debugging session for me:

import gdb
import re

def lookup_type(val)
   resolved_type = str(val.type.unqualified().strip_typedefs())
   if (re.search("^boost::unordered_map>.*>$", resolved_type):
      return BoostUnorderedMapPrinter()

gdb.pretty_printers.append (lookup_type)

Luka Bradeško
  • 542
  • 7
  • 16