如何确定导致分段错误的代码中的错误在哪里?
我的编译器(gcc)可以显示程序中错误的位置吗?
如何确定导致分段错误的代码中的错误在哪里?
我的编译器(gcc)可以显示程序中错误的位置吗?
当前回答
如果你们中有人(像我一样!)也在寻找同样的问题,但是使用gfortran而不是gcc,那么现在编译器要强大得多,在使用调试器之前,您还可以尝试这些编译选项。对我来说,这准确地确定了发生错误的代码行,以及我访问的哪个变量越界导致了分割错误错误。
-O0 -g -Wall -fcheck=all -fbacktrace
其他回答
Lucas关于核心转储的回答很好。在我的.cshrc中,我有:
alias core 'ls -lt core; echo where | gdb -core=core -silent; echo "\n"'
输入“core”显示反向跟踪。和日期戳,以确保我在看正确的文件:(。
补充:如果存在堆栈损坏错误,那么应用于核心转储的回溯通常是垃圾。在这种情况下,根据接受的答案(假设错误很容易重现),在gdb中运行程序可以得到更好的结果。同时也要注意多个进程同时转储核心;有些操作系统会将PID添加到核心文件的名称中。
如果你们中有人(像我一样!)也在寻找同样的问题,但是使用gfortran而不是gcc,那么现在编译器要强大得多,在使用调试器之前,您还可以尝试这些编译选项。对我来说,这准确地确定了发生错误的代码行,以及我访问的哪个变量越界导致了分割错误错误。
-O0 -g -Wall -fcheck=all -fbacktrace
您还可以使用一个核心转储,然后用gdb检查它。要获得有用的信息,还需要使用-g标志进行编译。
每当你收到这样的信息:
Segmentation fault (core dumped)
一个核心文件被写入当前目录。您可以使用命令检查它
gdb your_program core_file
该文件包含程序崩溃时内存的状态。核心转储在软件部署期间非常有用。
确保您的系统没有将核心转储文件大小设置为零。你可以通过以下方法将其设置为无限:
无限制
不过小心!核心转储可能变得巨大。
GCC不能这样做,但GDB(调试器)肯定可以。使用-g开关编译你的程序,像这样:
gcc program.c -g
然后使用gdb:
$ gdb ./a.out
(gdb) run
<segfault happens here>
(gdb) backtrace
<offending code is shown here>
这里有一个很好的教程,可以帮助您开始使用GDB。
段错误发生的位置通常只是“导致错误”在代码中的位置的线索。给定的位置并不一定是问题所在。
此外,你可以给valgrind一个尝试:如果你安装valgrind并运行
valgrind --leak-check=full <program>
然后它将运行您的程序并显示任何段错误的堆栈跟踪,以及任何无效的内存读写和内存泄漏。它真的很有用。