Linux core dump问题定位

举报
山海之光 发表于 2020/06/12 14:54:16 2020/06/12
【摘要】 1、什么是core dump?core dump又叫核心转储, 当程序运行过程中发生异常, 程序异常退出时, 由操作系统把程序当前的内存状况存储在一个core文件中, 叫core dump,报错信息一般是“segmentation fault (core dumped)”。比如linux中内存越界会收到SIGSEGV信号,然后就会core dump。2、什么情况下会出core dump?(1...

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


【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。