【问题标题】:Investigating Segmentation Faults and Debugging Tools调查分段错误和调试工具
【发布时间】:2017-04-23 01:03:46
【问题描述】:

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

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

我想知道的是:

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

【问题讨论】:

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


    【解决方案1】:

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

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

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

    很明显,在二进制文件中默认插入了某种调试信息,即使您不要求它也是如此。至少,足以为代码提供行号。如果您使用的是 GCC,那么它可能对应于-g1,而-g 等效于-g2。如果你好奇,你可以用-g0 编译,看看是否消除了行号信息。

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

    这里没有“合适的”,除了“任何有效的”。

    我确实发现调试禁用优化编译的程序更容易,当然调试信息是最有帮助的——只要您可以使用这样的二进制文件重现错误。每当我正在处理段错误的程序时,我也倾向于使用 valgrind。当调试信息可用时,这也会提供更多信息,并且如果存在内存问题(段错误几乎总是表明),那么即使程序的调试版本没有崩溃,valgrind 也可能会识别它。至于 ddd,这只是几个 UI 选择之一,包括支持的工具的本机选项。在这方面使用适合您的方法。

    哦,在几十年的编程生涯中,我从未不得不求助于分析核心转储。当然,我的时间最终可能会到来,但我满足于推迟它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-05-11
      • 2015-02-18
      • 2013-02-10
      • 1970-01-01
      • 1970-01-01
      • 2012-07-06
      • 2023-03-23
      • 1970-01-01
      相关资源
      最近更新 更多