Linux core dump问题定位
1、什么是core dump?
core dump又叫核心转储, 当程序运行过程中发生异常, 程序异常退出时, 由操作系统把程序当前的内存状况存储在一个core文件中, 叫core dump,报错信息一般是“segmentation fault (core dumped)”。比如linux中内存越界会收到SIGSEGV信号,然后就会core dump。
2、什么情况下会出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)堆栈溢出。不要使用大的局部变量(因为局部变量都分配在栈上),这样容易造成堆栈溢出,破坏系统的栈和堆结构,导致出现莫名其妙的错误。
3、怎样查看core dump保存的core文件?
(1)查看系统是否配置了core dump的功能
ulimit -c,使用该命令可查看core file大小的配置情况。
如果为0,则表示关闭了此功能,即使发生了core dump,也不会保存core文件;
如果为unlimited,则表示core文件的大小不收限制。如果占用了超大内存的应用程序发生了core dump,完整的core文件可能需要较长时间才能写到硬盘上;
如果为一个数值,则表示超过多少kb的文件将会被裁剪,最终生成一个不超出指定大小的、不完整的core文件,在调试此core文件时,gdb会提示错误。
可以使用ulimit -c xxx设置core文件的大小,可以设为unlimited或一个数值,设为0则关闭保存core文件。注意,这种设置只对当前shell有效,
(2)core文件的保存路径和名称
一般默认情况下,core文件会保存在发生了segmentation fault的可执行程序所在的同意路径下,文件名就是“core”,新的core文件会覆盖旧的
vi /proc/sys/kernel/core_pattern,可修改core文件保存位置和文件名格式,此处不详细描述修改方法
vi /proc/sys/kernel/core_uses_pid,文件内容为0时,表示core文件命名就是"core",设为1,将添加pid为扩展名,比如core.xxxx
(3)查看core文件及错误定位
查看core文件需要gdb工具,如果没有安装,则使用sudo apt-get install gdb安装
使用gdb 可执行文件名 core文件名,打开core文件,再输入bt命令,即可看到程序出错的地方
对于结构复杂的程序,如涉及模板类或复杂的调用,gdb得出了出错位置,似乎这还不够,还需要进一步做内存分析,则需要使用更为专业的工具——valgrind
(4)实例演练
复制以下代码段,保存为core_dump_test.c
#include "stdio.h"
int main(){
int stack_of[100000000];
int b=1;
int* a;
*a=b;
}
使用gcc -g core_dump_test.c -o core_dump_test编译,再执行./core_dump_test,直接会出现segmentation fault (core dumped)
使用gdb core_dump_test core,查看core文件,输入bt,查看错误行在这行:
int stack_of[100000000];
原因很明显,直接在栈上申请如此大的数组,导致栈空间溢出,触犯了OS对于栈空间大小的限制,所以出Core(这里是否出Core还和OS对栈空间的大小配置有关,一般为8M)。但是这里要明确一点,真正出Core的代码不是分配栈空间的int stack_of[100000000], 而是后面这句int b=1, 为何?出Core的一种原因是因为对内存的非法访问,在上面的代码中分配数组stack_of时并未访问它,但是在其后声明变量并赋值,就相当于进行了越界访问,继而出Core。
参考资料:
https://www.cnblogs.com/jefree/p/4439034.html
https://www.cnblogs.com/bodhitree/p/5850212.html
- 点赞
- 收藏
- 关注作者
评论(0)