10

我今天遇到了我的第一个分段错误(新手程序员)。在阅读了分段错误是什么之后(感谢本网站上的所有有用信息,以及 Wikipedia 的冗长解释),我正在尝试确定查找错误发生位置的最简单方法。它是用 C 语言编写的,错误发生在基于 *NIX 的系统上(我不确定哪个是诚实的...... 99% 肯定它是 Linux)。我不能准确地发布我的代码,因为我有很多我正在编译的文件都很长。我只是希望你们都观察到了一些最佳实践。谢谢你的帮助。

Ps 我认为错误来自取消引用 NULL 指针或使用未初始化的指针。但是,我肯定是错的。

4

4 回答 4

19

使用调试器,gdb或者如果这不适用,则使用strace工具来更好地了解段错误发生的位置。

如果使用gcc,请确保使用-gswitch 进行编译以包含调试信息。然后,gdb将在源代码中显示段错误的确切位置。

例如,如果我们有这个明显的段错误程序:

新的.c

#include <stdio.h>

int main()
{
        int *i = 0x478734;
        printf("%d", *i);
}

我们编译它,gcc -g new.c -o new然后运行gdb会话gdb new

我们在交互式会话中发出run命令,else 很清楚:

(gdb) run
Starting program: /home/Tibor/so/new
[New Thread 9596.0x16a0]
[New Thread 9596.0x1de4]

Program received signal SIGSEGV, Segmentation fault.
0x0040118a in main () at new.c:6
6               printf("%d", *i);
(gdb)

正如 DasMoeh 和 netcoder 所指出的,当发生段错误时,您可以使用backtrace交互式会话中的命令来打印调用堆栈。这可以帮助进一步查明段错误的位置。

于 2012-07-11T18:55:57.263 回答
5

最简单的方法是使用valgrind. 它将精确定位到发生无效访问的位置(以及其他不会导致崩溃但仍然无效的问题)。当然,真正的问题可能在代码中的其他地方(例如:无效指针),所以下一步是检查源代码,如果仍然感到困惑,请使用调试器。

于 2012-07-11T19:07:13.057 回答
2

+1 为 Tibors 的回答。

在较大的程序上,或者如果您使用其他库,使用 gdb 查看回溯也可能很有用:ftp: //ftp.gnu.org/pub/old-gnu/Manuals/gdb/html_node/gdb_42.html

于 2012-07-11T19:53:06.277 回答
0

因为我刚刚更正了我使用 gcc 所做的段错误,所以我为经过这里的人重新打开了这篇文章。

您应该考虑使用标志-fsanitize=address有时可以高精度地突出您的段错误。

于 2020-03-29T16:30:53.010 回答