利用gdb调试core文件
什么是core dump
core dump又叫核心转储, 当程序运行过程中发生异常, 程序异常退出时, 由操作系统把程序当前的内存状况存储在一个core文件中, 叫core dump。
(linux中如果内存越界会收到SIGSEGV信号,然后就会core dump)
在程序运行的过程中,有的时候我们会遇到Segment fault(段错误)这样的错误。
这种看起来比较困难,因为没有任何的栈、trace信息输出。
该种类型的错误往往与指针操作相关。
往往可以通过这样的方式进行定位。
造成segment fault,产生core dump的可能原因
1、内存访问越界
a) 由于使用错误的下标,导致数组访问越界
b) 搜索字符串时,依靠字符串结束符来判断字符串是否结束,但是字符串没有正常的使用结束符
c) 使用strcpy, strcat, sprintf, strcmp, strcasecmp等字符串操作函数,将目标字符串读/写爆。
应该使用strncpy, strlcpy, strncat, strlcat, snprintf, strncmp, strncasecmp等函数防止读写越界。
2、多线程程序使用了线程不安全的函数。
3、多线程读写的数据未加锁保护。
对于会被多个线程同时访问的全局数据,应该注意加锁保护,否则很容易造成core dump
4、非法指针
a) 使用空指针
b) 随意使用指针转换。
一个指向一段内存的指针,除非确定这段内存原先就分配为某种结构或类型,或者这种结构或类型的数组,否则不要将它转换为这种结构或类型的指针,而应该将这段内存拷贝到一个这种结构或类型中,再访问这个结构或类型。
这是因为如果这段内
存的开始地址不是按照这种结构或类型对齐的,那么访问它时就很容易因为bus error而core dump.
5、堆栈溢出
不要使用大的局部变量(因为局部变量都分配在栈上),这样容易造成堆栈溢出,破坏系统的栈和堆结构,导致出现莫名其妙的错误。
配置操作系统使其产生core文件
首先通过ulimit命令查看一下系统是否配置支持了dump core的功能。
通过ulimit -c或ulimit -a,可以查看core file大小的配置情况,如果为0,则表示系统关闭了dump core。
可以通过ulimit -c unlimited来打开。
若发生了段错误,但没有core dump,是由于系统禁止core 文件的生成。
解决方法:
$ulimit -c unlimited(只对当前shell进程有效)
或在~/.bashrc的最后加入:ulimit -c unlimited(一劳永逸)
# ulimit -c
$ ulimit -a
core file size (blocks, -c) 0
dataseg size (kbytes, -d) unlimited
file size (blocks, -f) unlimited
用gdb查看core文件
发生core dump之后, 用gdb进行查看core文件的内容, 以定位文件中引发core dump的行.
gdb [exec file] [core file]
如: gdb ./test test.core
然后使用bt查看调用堆栈。