嵌入式之coredump调试篇

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,可以查看栈的回溯,即段错误发生的地方。
在这里插入图片描述

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值