在gdb中漂亮地打印boost::unordered_map

7

最近我开始在我的系统上使用优秀的boost::unordered_map,但是遇到了一个缺点:我不知道如何检查它的内容。在gdb上打印它会给我一个table_和buckets_,但是我没有找到项目所在的位置。有人知道吗?

2个回答

10

对于那些想要打印机的人,我已经成功创建了一个。这是代码:

class BoostUnorderedMapPrinter:
    "prints a 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"

10
我知道我来晚了,但是我该如何在GDB中加载(和使用)这个漂亮的打印机? - bruno nery
2
感谢您发布这个。它不适用于较新的版本(我已经在1.58+上测试过了),但是我今天早上拿到了它并更新了它,使其与1.58兼容。再飞行一段时间后,如果可以的话,我将向https://github.com/ruediger/Boost-Pretty-Printer提供一个拉取请求。 - Chris Cleeland

2
在典型的哈希表实现中,桶包含链接列表的头部,该列表实际上包含与此特定哈希对应的值。因此,我会选择buckets_
另一个选项:现在有各种Python漂亮的打印机库供gdb使用,我认为您可以找到一个适用于C++0x并检查它查找值的库。

当然,我已经检查了gcc tr1的实现,发现结构非常不同,替换并不好,因为我发现Boost的实现比tr1的版本更快。 - scooterman

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接