54

我可以设置任何 gcc 选项来提供分段错误的行号吗?

我知道我可以:

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

编辑:

  1. bt/ whereon gdb give No stack。
  2. 有用的建议
4

8 回答 8

76

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

$ gdb blah
(gdb) run
(gdb) where

编辑完整性:

您还应该确保使用-ggcc 选项在可执行文件中包含行号时使用调试标志构建应用程序。

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

于 2009-02-02T23:46:35.007 回答
26

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

$ gcc -ggdb myproj.c
$ gdb a.out
gdb> 运行 --some-option=foo --other-option=bar
(gdb 会说你的程序遇到了段错误)
gdb>bt
(gdb 打印堆栈跟踪)
gdb>q
[您确定,您的程序仍在运行]?是的
$ emacs myproj.c # 呵呵,我现在知道错误是什么了...

快乐的黑客:-)

于 2009-02-03T00:06:15.340 回答
11

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

这样做的好处是你可以把它留在你的代码中;您无需通过 gdb 运行即可获得良好的调试输出。

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

于 2009-02-03T00:21:55.980 回答
7

在 valgrind 下运行它。

于 2010-10-04T17:37:03.717 回答
4

您还需要在 -g 上使用调试标志进行构建

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

于 2009-02-02T23:49:14.797 回答
4

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

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

GCC 无法提供此信息,您必须依赖外部程序,例如 GDB。

GDB 可以在程序出现段错误后使用“bt”(“backtrace”的缩写)命令为您提供发生崩溃的行。这不仅会为您提供崩溃的行,还会为您提供程序的整个堆栈(因此您可以看到发生崩溃的函数调用了什么)。

于 2009-02-02T23:50:33.640 回答
1

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

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

于 2015-09-18T11:34:43.300 回答