1、segment fault
segment fault是几乎多有C程序员都会碰到的问题,多为内存问题,因为glibc库中基本所有的函数都默认形参指针是非空的,这样以下原因就可能导致段错误:
(1)引用一个包含非法值的指针(当然包括空指针)。
(2)未得到正确的权限的时候进行访问,例如往只读的内存地址写数据。
(3)内存越界(数组越界,变量类型不一致等)
调试segment fault的几种常见方法:
(1) 打印log,这种方法的前提是你知道在哪行代码附近会出问题;
(2) gdb调试,对于小代码,可以逐行调试,大工程就比较头疼咯;
(3) core dump调试,当一个程序崩溃时,在进程当前工作目录的core文件中复制了该进程的存储图像。core文件仅仅是一个内存映象(同时加上调试信息),主要是用来调试的。
首先,设置core大小
#设置core大小为无限
ulimit -c unlimited
#设置文件大小为无限
ulimit unlimited
使用core文件调试程序
看下面的例子:
/*core_dump_test.c*/
#include <stdio.h>
const char *str = "test";
void core_test(){
str[1] = 'T';
}
int main(){
core_test();
return 0;
}
编译:
gcc–g core_dump_test.c -o core_dump_test
如果需要调试程序的话,使用gcc编译时加上-g选项,这样调试core文件的时候比较容易找到错误的地方。
执行:
./core_dump_test
段错误
调式core文件
core文件是个二进制文件,需要用相应的工具来分析程序崩溃时的内存映像,在Linux下可以用GDB来调试core文件。
gdb core_dump_test core
Loaded symbols for /lib/ld-linux.so.2
#0 0x080482fd in core_test () at core_dump_test.c:7
7 str[1] = 'T';
(gdb) where
#0 0x080482fd in core_test () at core_dump_test.c:7
#1 0x08048317 in main () at core_dump_test.c:12
#2 0x42015574 in __libc_start_main () from /lib/tls/libc.so.6
GDB中键入where,就会看到程序崩溃时堆栈信息(当前函数之前的所有已调用函数的列表(包括当前函数),gdb只显示最近几个),我们很容易找到我们的程序在最后崩溃的时候调用了core_dump_test.c第7行的代码,导致程序崩溃。注意:在编译程序的时候要加入选项-g。您也可以试试其他命令, 如 fram、list等。更详细的用法,请查阅GDB文档。