从 GDB 中的列表中打印取消引用的值
Posted
技术标签:
【中文标题】从 GDB 中的列表中打印取消引用的值【英文标题】:Print dereferenced values from list in GDB 【发布时间】:2020-09-21 21:02:45 【问题描述】:我正在查看 gdb 中的核心文件。我有一个 std::list 指向堆上对象的指针。使用 GDB 进行调试,打印列表会返回地址列表。这是有道理的。
我可以轻松打印列表中第一个元素的取消引用对象,即'print *$1.my_list.front()'。我想查看列表中每个元素的内容。我无法打印每个取消引用的元素。是否有一种简单的方法来打印每个取消引用的元素?
我认为自己是一个 gdb 初学者,并且在需要使用它时通常会应付自如。我知道网上有导入 python 脚本的示例,尽管大多数示例显示调试正在运行的程序。如果您还知道有任何好的资源可供新手了解更多关于 gdb 最佳实践的信息,我们将不胜感激。
【问题讨论】:
还要查看 xmethods/pretty printers 的源代码,看看如何访问成员。 (尽管如果 xmethods 已经可用,则不需要) 【参考方案1】:gdb 对大多数标准库都有漂亮的打印机,因此在大多数情况下,print your_list
就足够了。但是,由于您有一个指针列表并且想要查看引用的对象,因此您必须获取列表中的一个元素,然后使用 p *your_list.front()
来尊重它,就像您已经完成的那样。对于除第一个元素之外的其他元素,您可以使用p *(your_list.front()+1)
、p *(your_list.front()+2)
等。使用像这样的指针算法,您可以在 取消引用它之前获得另一个元素的地址。
您还可以将第一个元素视为数组的开头,并在地址中使用@SIZE
查看整个“数组”。这是 gdb 中的一种特殊语法,用于将内存区域视为 C 数组。假设您想查看列表中的前 4 个元素。你可以使用p *your_list.front()@4
。
注意: 从核心文件调试或从正在运行的程序进行调试的主要区别在于,从核心文件进行调试时没有正在运行的进程。这意味着当您从核心文件调试时,您不能调用函数,除非在 gdb 中为您尝试调用的方法定义了 xmethod。 gdb 还定义了许多 xmethods,这就是为什么您可以在列表中调用 .front()
以及其他方法,例如 .size()
。
【讨论】:
front()
只返回对集合第一个元素的引用。用于your_list.front()+1
等算术运算时,该值不是索引为1的元素的值。begin()
用于遍历列表。以上是关于从 GDB 中的列表中打印取消引用的值的主要内容,如果未能解决你的问题,请参考以下文章