研究分段故障和调试工具

时间:2016-12-07 22:20:33

标签: bash c++11 segmentation-fault gdb gnu-make

使用make和gcc编译C ++程序后,我在运行时遇到了分段错误。该程序刚刚退出,没有任何错误消息。

即使我没有在调试模式下编译程序,通过使用gdb运行它我实际上收到一条错误消息,以查看segfault发生的位置。

我想知道的是:

  • 为什么gdb显示导致错误的行,但常规bash没有?
  • 当程序未在调试模式下编译时,gdb如何显示该行?
  • 过去我总是在调试模式下重新编译(将符号表附加到二进制文件)并使用ddd调查核心转储的回溯。这是修复分段错误的正确方法,或者通常的方法是什么?

1 个答案:

答案 0 :(得分:1)

  

为什么gdb显示导致错误的行,但常规bash没有?

因为gdb是为了这样做而构建的。捕获段错误并将其报告给您是其工作的一部分,以帮助您进行调试。例如,您可以获得回溯,检查各种堆栈帧等,以确定错误的性质和可能原因。 Bash不是为此而构建的,并且没有免费提供此类行为。

  

当程序未在调试模式下编译时,gdb如何显示该行?

显然,默认情况下会将某种调试信息插入到二进制文件中,即使您没有要求它也是如此。至少足以为代码提供行号。如果您正在使用GCC,则可能与-g1相对应,而-g相当于-g2。如果您有点好奇,可以使用-g0进行编译,看看是否会删除行号信息。

  

在过去,我总是在调试模式下重新编译(将符号表附加到二进制文件)并使用ddd调查核心转储的回溯。这是修复分段错误的正确方法,或者通常的方法是什么?

没有"正确"超越"无论如何工作"。

我确实发现它更容易调试已禁用优化编译的程序,当然调试信息最有帮助 - 只要您可以使用这样的二进制文件重现错误。每当我正在处理段错误的程序时,我也倾向于使用valgrind。当调试信息可用时,这也是更有用的信息,并且如果存在内存问题(segfault几乎总是指示),那么即使程序的调试版本没有崩溃,valgrind也可能会识别它。至于ddd,这只是几个UI选择中的一个,包括支持的工具'原生的。在这方面使用对你有用的东西。

哦,在几十年的编程中,我从来没有必须求助于分析核心转储。当然,我的时间最终会到来,但我很满意推迟。