我有一个类,它有一个类型为std::unordered_set<SomeClass*>
的成员。 gdb 为标准库中的类型提供了漂亮的打印机,包括std::unordered_set
.打印包含 7 个元素的集合会返回类似
$50 = std::unordered_set with 7 elements = {
[0] = 0x7fffffffb750,
[1] = 0x7fffffffb330,
[2] = 0x7fffffffaf10,
[3] = 0x7fffffffaaf0,
[4] = 0x7fffffffa6d0,
[5] = 0x7fffffffa2b0,
[6] = 0x7fffffffc490
}
我需要的是 gdb python 的 API 中的一种方法来自己重新实现这个漂亮的打印机,以便在迭代时我可以从SomeClass
返回"name"字段的值,而不是原始指针。但是,我似乎找不到正确的方法来迭代unordered_set
的存储桶并检索存储桶中的各个节点。在此链接中,有一个旧版本的实现给了我一些提示,但我无法正确处理。
事实证明,我们可以简单地导入漂亮的打印机进行std::unordered_set
,并使用我们的自定义打印实现派生类。
一种可能性是
from libstdcxx.v6.printers import Tr1UnorderedSetPrinter
class UnorderedSetOfPointersPrinter(Tr1UnorderedSetPrinter):
def __init__(self, val):
Tr1UnorderedSetPrinter.__init__(self, str(val.type), val)
self._children = Tr1UnorderedSetPrinter.children(self)
self._index = 0
def children (self):
for idx, valor in self._children:
yield (idx, f'{valor.dereference()["name"]} ({valor})')
return
问题是为我们的专业化注册这台漂亮的打印机std::unordered_set
.即使我们注册了这个漂亮的打印机,也会使用std::unordered_set
常规的打印机而不是我们的新实现。(见相关问题)。一种解决方法是定义一个继承自std::unordered_set<SomeClass*>
的新类型,例如
class MyUnorderedSetOfMyClassPointers : public std::unordered_set<SomeClass*> {};
然后注册漂亮的打印机进行MyUnorderedSetOfMyClassPointers
.这有效,但它不是最佳的,因为我们不必要地创建一个新类型只是为了帮助调试。
最后,为SomeClass*
实现漂亮的打印机是解决在std::unordered_set
打印中只看到指针地址的原始问题的最简单解决方案,但是如果您想/需要创建自定义命令来迭代std::unordered_set
元素,知道如何自定义 gdb 中已有的漂亮打印机仍然很有用, 例如。