【问题标题】:How to find the line caused segmentation fault in c++ compiled program如何在c ++编译程序中查找导致分段错误的行
【发布时间】:2020-05-09 18:08:26
【问题描述】:

我正在使用vim 进行 C++ 编程。我已将编译命令绑定到 vim 中的 ctrl+c,并通过运行 ./main.out 在另一个 tmux 窗格中运行它。我的问题是当我的 c++ 程序给我segmentation fault 错误时,我不知道是哪一行导致了问题。但是当我在vscode 中编译并运行程序时,它向我显示了导致错误的行。 我正在寻找一种方法来找出导致运行时错误的行,例如在控制台中运行程序的二进制文件时出现segmentation fault 错误。 这是我做./main.out时的示例输出:

[1]    24656 segmentation fault (core dumped)  ./main.out

【问题讨论】:

  • 运行gdb ./main.out。另外,在编译程序时添加-ggdb3
  • 请注意,虽然 gdb 几乎可以立即指出程序崩溃的位置,但通常需要进行一些侦探工作才能找到导致崩溃的错误。一旦您知道程序崩溃的位置,您将需要放置一个断点以在崩溃之前停止程序,以收集有关导致崩溃的原因的信息。使用 step 推进程序并打印以显示变量。使用从 gdb 中学到的知识来隔离错误,因为通常更容易证明对孤立错误的修复是正确的。
  • @user4581301 谢谢,看来我很难弄清楚 gdb 是如何工作的:D
  • 值得花时间学习。调试器的使用是一项重要的编程技能。作为顶级程序员生产力工具,调试器紧随编译器之后。
  • 参见sourceware.org/gdb/current/onlinedocs/gdb 或其他一些 GDB 手册/教程。使用 IDE 可能会更容易。

标签: c++ compiler-errors compilation g++


【解决方案1】:

在编译程序时,添加-g 编译器标志,或者更好的-ggdb3,通过在可执行文件中添加调试符号,这将为您提供更漂亮的输出。此外,请确保使用 -O0 优化级别进行编译。

要实际调试程序,请运行gdb ./main.out 以在调试会话中启动程序。如果您随后运行r,gdb 将开始执行程序,然后在给出段错误的行处停止。

要弄清楚是如何到达那个点的,在调试会话中运行bt,你会得到一个回溯,它会显示所有的函数调用到崩溃的代码行。

您当然可以做更多的事情(而且您可能需要这样做,因为定位错误源通常只是第一步)。您可以使用p 打印变量的值、设置观察点等等。有一段时间,gdb 甚至附带了一个成熟的 python 解释器,所以你甚至可以编写一个 python 脚本来满足你的自定义调试需求。

一开始学习如何使用 gdb 似乎让人不知所措,但要坚持下去,我保证付出的努力会有很大的回报:)

【讨论】:

  • 重要提示:导致崩溃的错误常常不在崩溃现场附近。定位坠机并对其进行调查是非常重要的早期步骤,但这只是一步。
【解决方案2】:

阿丁同上 此外,您的代码可能会由于参数可接受的调用而崩溃,但如果您没有这些调试版本,则会导致某个库的众所周知的超出范围保护错误。如果在那里使用汇编程序,他们可以做一些奇怪的事情。 所以不要害怕添加临时代码来帮助找到一个在 1,000,000 次其他调用没有崩溃时崩溃的调用。 这就是为什么我喜欢在可能的情况下使用大量生成的随机数来测试你修复它的原因。

【讨论】:

  • 这是答案还是评论?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-10-10
  • 1970-01-01
  • 1970-01-01
  • 2017-09-21
  • 1970-01-01
相关资源
最近更新 更多