【问题标题】:Debugging Best Practices for C++ STL/Boost with gdb使用 gdb 调试 C++ STL/Boost 的最佳实践
【发布时间】:2010-09-30 18:15:00
【问题描述】:

使用 gdb 调试,任何使用 STL/boost 的 c++ 代码仍然是一场噩梦。任何使用过 STL 的 gdb 的人都知道这一点。例如,请参阅代码 here 中一些调试会话的示例运行。

我正在尝试通过收集提示来减轻痛苦。您能否评论一下我在下面收集的提示(特别是您一直在使用的提示以及您建议对它们进行的任何更改)-我列出的提示是技术性降序。

  • 有人使用"Stanford GDB STL utils""UCF GDB utils" 吗?是否有一些用于提升数据结构的工具?上面的实用程序似乎不能递归使用,例如用于在一个命令中以清晰的方式打印 boost::shared_ptr 的向量。
  • 编写您的 .gdbinit 文件。例如,包括 C++ 相关的美化器,列在 UCF GDB 实用程序的底部。
  • 使用检查/调试 STL/Boost 库,例如 STLport。
  • 使用日志记录(例如,如here 所述)

更新:GDB 有一个new C++ branch

【问题讨论】:

  • 问过并回答过,但 gdb 7 对 STL 容器有更好的支持 - 我们的开箱即用安装包括对打印它们的支持,例如 "$4 = std::vector of length 4, capacity 4 = {0, 2, 4, 888}”。我还没有看到它对复杂类型或其他容器有什么作用,但这似乎是一个巨大的改进。更多详情请参阅this page...
  • @RobI 谢谢!然而,令我痛苦的是,当我经常使用 boost 指针容器时,我发现仍然缺乏基于 python 的支持。 GDB 只是不停地抱怨而不打印内容。

标签: c++ stl boost gdb


【解决方案1】:

也许不是您正在寻找的那种“小费”,但我不得不说,在从 C++ 和 STL 转向 C++ 和 boost 和 STL 几年后,我的经验是我现在花了很多 在 GDB 中的时间比我以前少了。我把这归结为几件事:

  • 提升智能指针(特别是“共享指针”,以及需要性能时的指针容器)。我不记得上次我必须写一个显式删除(删除是 C++ 恕我直言的“goto”)。 GDB 花费了大量时间来跟踪无效和泄漏的指针。
  • boost 充满了经过验证的代码,您可能会将其作为劣质版本拼凑在一起。例如boost::bimap 非常适合 LRU 缓存逻辑的常见模式。还有一大堆 GDB 时间。
  • 采用单元测试。 boost::test 的 AUTO 宏意味着设置测试用例绝对是轻而易举的事 (easier than CppUnit)。这在它被内置到任何你必须附加调试器的东西之前很久就捕获了很多东西。
  • 与此相关,boost::bind 等工具使测试设计变得更加容易。例如,算法可以更通用,并且与它们所操作的类型的绑定更少;这使得将它们插入测试垫片/代理/模拟对象等变得更容易(而且暴露于 boost 的模板特性将鼓励你“敢于模板化”你以前从未考虑过的东西,从而产生类似的测试好处)。
  • boost::array。 “C 数组”性能,在调试版本中进行范围检查。
  • boost 里有很多很棒的代码,你不禁要学习

【讨论】:

  • > boost 充满了很棒的代码,你不禁要学习我当然同意,但对于初学者来说,这是一座需要攀登的大山。当他们看到半页长的编译器错误消息时,他们会感到害怕。
  • 非常真实!一个有用的提示是将它们粘贴到编辑器中并搜索并替换例如 std::basic_string 与 STRING 并将内容简化为可理解的内容(通常是您感兴趣的“顶级”,不是细节)。
  • 如果您可以使用 C++11,请注意 boost 智能指针现在是 C++11 标准库的一部分
【解决方案2】:

【讨论】:

【解决方案3】:

我认为最简单和最多的选择是使用日志记录(我实际上使用调试打印,但我认为这不是重点)。最大的优势是您可以检查任何类型的数据,每次程序执行多次,然后使用文本编辑器搜索它以查找有趣的数据。请注意,这非常快。缺点很明显,您必须预先选择要记录的数据和记录的位置。但是,这并不是一个严重的问题,因为您通常知道代码中哪里发生了不好的事情(如果没有,您只需在这里和那里添加健全性检查,然后您就会知道)。

检查/调试库很好,但它们作为测试工具更好(例如,运行它并查看我是否做错了什么),并且不擅长调试特定问题。他们无法检测到用户代码中的缺陷。

否则,我使用普通的 GDB。它并不像听起来那么糟糕,尽管如果你被“print x”打印一屏垃圾吓到了,可能会是这样。但是,如果您有调试信息,例如打印 std::vector 的成员之类的工作,并且如果出现任何故障,您仍然可以通过 x 命令检查原始内存。但如果我知道我在寻找什么,我会使用选项 1 - 日志记录。

请注意,“难以检查”的结构不仅来自 STL/Boost,还来自其他库,例如 Qt/KDE。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-24
    • 1970-01-01
    相关资源
    最近更新 更多