使用gdb调试C++ STL/Boost的最佳实践提示

47

使用gdb进行调试,对于使用STL/boost的任何c++代码仍然是一场噩梦。任何使用过带有STL的gdb的人都知道这一点。例如,请参见此处中某些调试会话的示例运行。

我正在尝试通过收集技巧来减轻痛苦。您能否请评论下面我收集到的技巧(特别是哪些技巧您曾经使用过,并对其进行任何更改的建议)--我已按技术性降序列出了这些技巧。

  • 是否有人使用“Stanford GDB STL utils”“UCF GDB utils”?是否有类似于boost数据结构的这种实用程序?上述实用程序似乎不可递归使用,例如在一个命令内以易读的方式打印boost::shared_ptr的向量。
  • 编写您的.gdbinit文件。包括例如,在UCF GDB工具底部列出的与C ++相关的美化程序。
  • 使用已检查/调试的STL/Boost库,例如STLport。
  • 使用日志记录(例如在此处所述)

更新:GDB有一个新的C ++分支


1
已经有人问过并回答了,但是gdb 7对STL容器的支持更好——我们的开箱即用安装包包括像"$4 = std::vector of length 4, capacity 4 = {0, 2, 4, 888}"这样的打印支持。我还没有看到它对于复杂类型或其他容器的处理方式,但它似乎是一个巨大的改进。请参见此页面获取更多详细信息... - Rob I
@RobI 谢谢! 但是我非常痛苦地发现,当我使用boost指针容器时,基于Python的支持仍然不足。 GDB只是一直抱怨并没有打印出内容。 - amit kumar
3个回答

16
也许不是你在寻找的“技巧”,但我必须说,经过几年从C++&STL转向C++&boost&STL的经验后,我现在在GDB中花费的时间要少得多。 我把这归因于以下几点:
  • boost智能指针(尤其是“共享指针”和指针容器,当需要性能时)。我不记得上次写明确的删除操作(在我看来,delete是C ++中的“goto”)。这样就会有很多GDB时间用于跟踪无效和泄漏指针。
  • boost充满了被证明过的代码,用于那些你可能会组合成一个劣质版本的东西。例如,boost :: bimap 非常适用于LRU缓存逻辑的常见模式。这样又节省了一大笔GDB时间。
  • 采用单元测试。 boost :: test 的自动宏意味着设置测试用例绝对轻松(比CppUnit更容易)。这可以捕捉到许多在构建为必须连接调试器的任何内容之前就已经存在的问题。
  • 与此相关的工具如boost :: bind 使得更容易进行测试设计。例如,算法可以更加通用,而不会与它们操作的类型耦合;这使得将它们插入到测试shim /代理/模拟对象等中更容易(以及接触boost的模板特性会鼓励您“敢于模板化”以前从未考虑过的事情,从而产生类似的测试效益)。
  • boost :: array 。在调试版本中具有范围检查的“C数组”性能。
  • boost充满了你难以不从中学到的好代码

3
我非常同意,但对于初学者来说,这是一个巨大的挑战。当他们看到半页长的编译器错误消息时,他们会感到害怕。Boost库中有很多优秀的代码可以让你受益匪浅。 - amit kumar
1
非常正确!一个有用的技巧是将它们粘贴到编辑器中,然后使用搜索和替换功能,例如将std::basic_string<yadda yadda yadda>替换为STRING,并将内容缩减为可理解的东西(通常您感兴趣的是“顶层”,而不是细节)。 - timday
如果您使用C++11,请注意boost智能指针现在已成为C++11标准库的一部分。 - Triskeldeian

5

3
特别是,请参考Archer项目(http://sourceware.org/gdb/wiki/ProjectArcher),我刚刚在那里添加了。 - Employed Russian

3
我认为最简单且最有效的方法是使用记录日志(实际上我使用调试打印,但我认为这不是关键点)。最大的优点是您可以检查任何类型的数据,每个程序执行多次,然后使用文本编辑器搜索以查找有趣的数据。请注意,这非常快速。缺点显而易见,您必须预先选择要记录的数据和记录位置。但是,这并不是一个严重的问题,因为通常您知道在代码中哪里出现了问题(如果不知道,只需在此处添加一些健全性检查,然后您就会知道)。
已检查/调试库很好,但它们更适合作为测试工具(例如运行并查看是否存在问题),而不是作为调试特定问题的工具。它们无法检测用户代码中的缺陷。
否则,我使用普通的GDB。它并没有听起来那么糟糕,尽管如果您害怕“print x”打印一堆垃圾,可能会这样。但是,如果您有调试信息,则诸如打印std :: vector 成员之类的事情都可以正常工作,如果出现任何问题,仍然可以通过x命令检查原始内存。但是,如果我知道我在寻找什么,我会使用选项1-记录日志。
请注意,“难以检查”的结构不仅限于STL / Boost,还包括其他库,例如Qt / KDE。

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