Linux core dump问题定位

网友投稿 1266 2022-05-29

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.

Linux 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

EI Jupyter notebook ModelArts

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:华为云容灾保障安踏业务永不止步
下一篇:自己动手写Python虚拟机读书会笔记
相关文章