我们如何确定导致segmentation fault的代码中的错误在哪里?
在编写了一些代码后,为了确定我的分段错误,我的编译器( gcc )能否显示我程序中的故障位置?
gcc
海湾合作委员会不能这样做,但GDB肯定可以 . 使用 -g 开关编译程序,如下所示:
-g
gcc program.c -g
然后使用gdb:
$ gdb ./a.out (gdb) run <segfault happens here> (gdb) backtrace <offending code is shown here>
Here是一个很好的教程,可以帮助您开始使用GDB .
此外,您可以尝试Valgrind:如果您安装Valgrind并运行valgrind --leak-check = full,那么它将运行您的程序并显示任何段错误的堆栈跟踪,以及任何无效的内存读取或写入以及内存泄漏 . 这真的很有用 .
您还可以使用核心转储,然后使用gdb进行检查 . 要获得有用的信息,还需要使用 -g 标志进行编译 .
每当你收到消息时:
Segmentation fault (core dumped)
核心文件写入当前目录 . 你可以用命令检查它
gdb your_program core_file
该文件包含程序崩溃时的内存状态 . 在部署软件期间,核心转储可能很有用 .
确保您的系统未将核心转储文件大小设置为零 . 您可以将其设置为无限制:
ulimit -c unlimited
虽然小心!核心转储可能会变得巨大 .
卢卡斯关于核心转储的答案很好 . 在我的.cshrc中我有:
alias core 'ls -lt core; echo where | gdb -core=core -silent; echo "\n"'
通过输入'core'来显示回溯 . 和日期戳,以确保我正在查找正确的文件:( .
Added :如果存在堆栈损坏错误,则应用于核心转储的回溯通常是垃圾 . 在这种情况下,根据接受的答案(假设故障很容易重现),在 gdb 内运行程序可以提供更好的结果 . 并且要注意同时倾倒核心的多个进程;某些操作系统将PID添加到核心文件的名称中 .
4 回答
海湾合作委员会不能这样做,但GDB肯定可以 . 使用
-g
开关编译程序,如下所示:然后使用gdb:
Here是一个很好的教程,可以帮助您开始使用GDB .
此外,您可以尝试Valgrind:如果您安装Valgrind并运行valgrind --leak-check = full,那么它将运行您的程序并显示任何段错误的堆栈跟踪,以及任何无效的内存读取或写入以及内存泄漏 . 这真的很有用 .
您还可以使用核心转储,然后使用gdb进行检查 . 要获得有用的信息,还需要使用
-g
标志进行编译 .每当你收到消息时:
核心文件写入当前目录 . 你可以用命令检查它
该文件包含程序崩溃时的内存状态 . 在部署软件期间,核心转储可能很有用 .
确保您的系统未将核心转储文件大小设置为零 . 您可以将其设置为无限制:
ulimit -c unlimited
虽然小心!核心转储可能会变得巨大 .
卢卡斯关于核心转储的答案很好 . 在我的.cshrc中我有:
通过输入'core'来显示回溯 . 和日期戳,以确保我正在查找正确的文件:( .
Added :如果存在堆栈损坏错误,则应用于核心转储的回溯通常是垃圾 . 在这种情况下,根据接受的答案(假设故障很容易重现),在 gdb 内运行程序可以提供更好的结果 . 并且要注意同时倾倒核心的多个进程;某些操作系统将PID添加到核心文件的名称中 .