3

你好,

我通常是一名 C 程序员。我经常使用 gdb、dbx 等工具在 unix 环境中调试 C 程序。我从未调试过 C++ 的大型应用程序。这与我们在 C 中调试的方式有很大不同吗?理论上我在 C++ 中相当出色,但从未有机会调试 C++ 程序。我也不确定我们在 c++ 中面临什么样的技术问题,这将导致开发人员打开调试器以找出问题。我们在 C++ 中遇到的常见问题是什么会导致调试器启动

ac 程序员在调试 C++ 程序时可能面临哪些挑战?与 C 相比,它是否困难和复杂?

4

6 回答 6

5

基本上是一样的。

请记住,当手动设置断点时,您需要使用命名空间和类来完全限定方法名称(结果,我发现使用行号来定义断点更容易)

不要忘记对析构函数的调用在源代码中是不可见的,但您仍然可以在块的末尾进入它们。

于 2010-06-15T14:13:40.290 回答
2

几个小区别:

foo::bar::fum(args)在 gdb shell 中键入完全限定符号时,您必须以单引号开头,以便 gdb 识别它并计算完成。

正如其他人所说,库模板在调试器中公开了它们的内部结构。你可以很容易地四处寻找std::vector,但戳穿std::map可能不是消磨时间的明智方式。

C++ 程序中常见的激进而丰富的内联可以使单行代码看起来有无穷无尽的步骤。shared_ptr 之类的东西可能特别烦人,因为对指针的每次访问都会内联扩展到模板内部。你永远不会真正使用它。

如果您有大量重载的符号名称,那么从 readline 完成中选择您想要的名称可能会令人不快。(你想要哪个“foo”?全部?只有这两个?)

于 2010-06-15T15:47:52.373 回答
1

GDB 在调试 c++ 方面有一段坎坷的过去。有一段时间它无法有效地破坏构造函数/析构函数。

在 gdb 中检查 stl 容器也非常困难。 std::string很痛苦,但通常是可行的。 std::map太难了,除非没有其他方法,否则我通常会添加打印语句。

构造函数/析构函数问题已经修复了几年。

stl 支持在 gdb 7.0 中得到修复。

您可能仍然对 boost 的库有疑问。我有时很难让 gdb 给我评估 a 的内容shared_ptr

所以我想调试你自己的 C++ 并没有那么难,它调试 3rd 方类和模板代码可能是一个问题。

于 2010-06-15T15:10:09.857 回答
1

确实有很多问题,但这也取决于您使用的调试器、它的版本控制等:

  1. 访问模板化类的单个成员并不容易
  2. 异常处理是一个问题——我已经看到调试器使用 setjmp/longjmp 做得更好
  3. 使用 obj1 == obj2 之类的东西设置断点,其中这些不是 POD 类型可能不起作用

我喜欢调试器的好处是访问私有/受保护的类成员我不必调用 get 例程;只要 [obj-name].[var-name] 就足够了。

阿潘

于 2010-06-15T14:30:45.833 回答
1

GDB 也可用于调试 C++,因此,如果您了解 C++ 的工作原理(并了解可能源于面向对象方面的问题),那么您就不应该遇到那么多麻烦(至少, 并不比你调试 C 程序多)。我认为...

于 2010-06-15T14:07:18.790 回答
0

C++ 对象有时可能更难分析。此外,由于数据有时嵌套在多个类中(跨多个层),“展开”它可能需要一些时间(正如本线程中的其他人已经说过的那样)。通常很难这么说,因为它在很大程度上取决于所使用的 C++ 特性和编程风格以及要分析的问题的复杂性(实际上这与语言无关)。

IMO:如果有人发现自己需要经常调试,他应该重新考虑他的编程风格。通常对我来说,最后都是关于错误处理的。如果一个程序的行为出乎意料,你的错误日志应该显示足够的信息来重建任何阶段发生的事情。

这还为您带来了好处,即您可以在程序交付给最终用户后离线“调试”问题。

于 2010-06-15T16:20:22.653 回答