分段错误的行号

时间:2009-02-02 23:41:35

标签: debugging gcc gdb segmentation-fault

我可以设置任何gcc选项,它会给出分段错误的行号吗?

我知道我可以:

  1. 逐行调试
  2. 将printfs放入代码中以缩小范围。
  3. 编辑:

      gdb上的
    1. bt / where给出无堆栈。
    2. Helpful suggestion

8 个答案:

答案 0 :(得分:60)

我不知道gcc选项,但是您应该能够使用gdb运行应用程序,然后当它崩溃时,键入where以查看退出时的堆栈,这应该得到你关闭了。

$ gdb blah
(gdb) run
(gdb) where

编辑完整性:

您还应该确保使用-g gcc选项构建带有调试标志的应用程序,以在可执行文件中包含行号。

另一种选择是使用bt(回溯)命令。

答案 1 :(得分:20)

这是一个完整的shell / gdb会话

$ gcc -ggdb myproj.c
$ gdb a.out
gdb> run --some-option=foo --other-option=bar
(gdb will say your program hit a segfault)
gdb> bt
(gdb prints a stack trace)
gdb> q
[are you sure, your program is still running]? y
$ emacs myproj.c # heh, I know what the error is now...

快乐的黑客行为: - )

答案 2 :(得分:10)

当程序获得SEGV信号时,您可以让gcc打印堆栈跟踪,类似于Java和其他更友好的语言处理空指针异常的方式。有关详细信息,请参阅我的答案:

关于这个的好处是你可以把它留在你的代码中;你不需要通过gdb来运行以获得漂亮的调试输出。

如果使用-g进行编译并按照其中的说明进行操作,则可以使用命令行工具(如addr2line)从输出中获取文件/行信息。

答案 3 :(得分:7)

在valgrind下运行。

答案 4 :(得分:4)

您还需要在-g

上使用调试标志进行构建

你也可以用gdb打开核心转储(你需要-g)。

答案 5 :(得分:4)

如果使用调试(-g)编译并在调试器(gdb,run,bt)下运行的所有上述建议都不适合您,那么:

  • 小学:也许你没有在调试器下运行,你只是想分析死后的核心转储。 (如果你启动调试会话,但不运行程序,或者它退出,那么当你要求回溯时,gdb会说“没有堆栈” - 因为根本没有正在运行的程序。不要忘记键入“run”。)如果它是segfaulted,请不要忘记在运行gdb时添加第三个参数(core),否则您将以相同的状态启动,而不是附加到任何特定的进程或内存映像。
  • 困难:如果你的程序正在运行但你的gdb说“没有堆栈”,你的堆栈指针可能会被严重破坏。在这种情况下,您可能在某处出现缓冲区溢出问题,严重到足以将您的运行时状态完全混合。 GCC 4.1支持使用-fstack-protector-all启用的ProPolice“Stack Smashing Protector”。它可以通过补丁添加到GCC 3.x.

答案 6 :(得分:1)

GCC没有提供此信息的方法,您必须依赖GDB等外部程序。

在程序出现故障后,GDB可以为您提供“bt”(“backtrace”的缩写)命令发生崩溃的行。这不仅会给你崩溃的线,而且会给整个程序堆栈(所以你可以看到发生崩溃的函数叫做什么)。

答案 7 :(得分:1)

当程序成功退出时,似乎会发生No stack问题。

为了记录,我遇到了这个问题,因为我忘记了代码中的返回,这使我的程序退出了失败代码。