Coredump简介
Coredump叫做核心转储,它是进程运行时在突然崩溃的那一刻的一个内存快照。操作系统在程序发生异常而异常在进程内部又没有被捕获的情况下,会把进程此刻内存、寄存器状态、运行堆栈等信息转储保存在一个文件里。
该文件是二进制文件,可以使用gdb、elfdump、objdump或者windows下的windebug、solaris下的mdb进行打开分析里面的具体内容。
当系统收到异常信号ARORT/SEGV时,系统会终止当前进程,并保留下来手机当时出现异常时的现场数据,类似于照相机按下快门的一瞬间,得到的照片即为我们的coredump。通常情况下coredmp包含了程序运行时的内存,寄存器状态,堆栈指针,内存管理信息等。可以理解为把程序工作的当前状态存储成一个文件。许多程序和操作系统出错时会自动生成一个core文件。
如果从浅层次的原因上来讲,Coredump的出现意味着当前进程存在BUG,需要程序员修复。从深层次的原因上讲,是当前进程触犯了某些OS层级的保护机制,逼迫 OS向当前进程发送诸如SIGSEGV(即signal 11)之类的信号, 例如访问空指针或数组越界,实际上是触犯了OS的内存管理,访问了非当前进程的内存空间,OS需要通过发出终止信号,产生Coredump来进行警示
可以使用ulimit命令查看 ulimit –c 输出结果为0表示没有开启,当程序异常终止也不会产生core dump文件
ulimit –c unlimited 来开启功能,并且不限制core dump文件大小;如果需要限制,在后面增加文件最大大小,单位是KB,根据实际测试限制大小,有时候coredump文件会损坏
Linux系统调用–getrlimit()与setrlimit()函数详解
功能描述:
获取或设定资源使用限制。每种资源都有相关的软硬限制,软限制是内核强加给相应资源的限制值,硬限制是软限制的最大值。非授权调用进程只可以将其软限制指定为0~硬限制范围中的某个值,同时能不可逆转地降低其硬限制。授权进程可以任意改变其软硬限制。RLIM_INFINITY的 值表示不对资源限制。
#include <sys/resource.h>
int getrlimit(int resource, struct rlimit *rlim);
int setrlimit(int resource, const struct rlimit *rlim);
resource:可能的选择有
RLIMIT_CORE //内核转存文件的最大长度。
rlim:描述资源软硬限制的结构体,原型如下:
struct rlimit {
rlim_t rlim_cur;//软限制
rlim_t rlim_max;//硬限制
};
coredump生成的测试例程
效果:发生段错误,将会在路径
/home/chenjg/share/chen下生成coredump文件
#include <sys/resource.h>
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#define CORE_SIZE 1024*1024*1024
/* enable为1表示是能cpredump 反之不使能*/
int CoreDump_Set(unsigned int enable, char* processName)
{
struct rlimit rlmt;
if(enable >1)
return -1;
if(enable == 1)
{
if(getrlimit(RLIMIT_CORE, &rlmt) == 0)
{
rlmt.rlim_cur = (rlim_t)CORE_SIZE;
rlmt.rlim_max = (rlim_t)CORE_SIZE;
if (setrlimit(RLIMIT_CORE, &rlmt) == -1)
{
return -1;
}
}
char buffer[512] = {0};
sprintf(buffer, "echo \'/home/chenjg/share/chen/corefile.%s-%s\' %s", "1.1.1", "%e-%s-%t", "> /proc/sys/kernel/core_pattern");
printf("buffer: %s\n", buffer);
system(buffer);
}
else
{
system("rm -f /home/chenjg/share/chen/corefile*");
if (getrlimit(RLIMIT_CORE, &rlmt) == 0)
{
rlmt.rlim_cur = (rlim_t)0;
rlmt.rlim_max = (rlim_t)0;
if (setrlimit(RLIMIT_CORE, &rlmt) == -1)
{
return -1;
}
}
}
return 0;
}
void add()
{
char *p = "chen";
*p='y';
}
int main()
{
int num = 1;
CoreDump_Set(num, "chen");
add();
return 0;
}
注:
/proc/sys/kernel/core_pattern
作用:设定core dump文件的文件名及路径
core_pattern模板中使用变量见下面的列表:
%%单个%字符
%p所dump进程的进程ID
%u所dump进程的实际用户ID
%g所dump进程的实际组ID
%s导致本次core dump的信号
%t core dump的时间 (由1970年1月1日计起的秒数)
%h主机名
%e程序文件名
调试coredump文件
调试方式为: gdb program coredump文件
例如我的可执行文件为coredump 生成的coredump文件为corefile.1.1.1-coredump-11-1599007800 ,则命令如下:
gdb coredump /home/chenjg/share/chen/corefile.1.1.1-coredump-11-1599007800
然后输入`backtrace或者bt,可以查看栈的回溯,即段错误发生的地方。