加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

kernel crash dump info 保存

发布时间:2020-12-15 19:50:14 所属栏目:百科 来源:网络整理
导读:Kernelcrash dump 1.??????在系统运行过程中,如果系统发生了crash,那么开发人员需要通过crash信息来进行debug. 并进一步定位问题。而crash信息存在于内核ring buffer中,系统重启后就丢失了,所以需要一种方法,可以在系统发生crash时,将crash info保存于

Kernelcrash dump

1.??????在系统运行过程中,如果系统发生了crash,那么开发人员需要通过crash信息来进行debug. 并进一步定位问题。而crash信息存在于内核ring buffer中,系统重启后就丢失了,所以需要一种方法,可以在系统发生crash时,将crash info保存于非易失存储器中,那么下面就来介绍一种方法实现这种功能。

2.??????预备:

a)????????当kernel crash发生时,crash dump info会被flush 到kernel ring buffer中,这个是kernel主动的行为。

b)????????当kernel crash发生时, 可以主动调用do_sysinfo(),将系统的一些内存与进程信息flush至kernel ring buffer,(即利用printk(),将获取的信息打印出来)。

c)????????当kernel crash 发生时,可以主动的将进程的调用栈信息flush到kernel ring buffer,这样很有利于调试和定位问题。

Notice: b,c 属于一个主动的行为,也可以不做。

3.kernel ring buffer?

?????? Kernel为系统打印kmalloc了一块内存,一般大小为128K,即将所有的printk的打印信息输出这个buffer,在console,可能通过dmesg来查看这个ring buffer的所有内容,可以用dmesg –c将这个ring buffer全部清空。

???????? 执行dmesg命令,你可以看到,系统从启动到现在完整的log信息。一般来说128k,足够保存所有的log信息,如果你在内存中打印很多信息,那么也有可能比较的信息会被覆盖掉。

4.下面写了一个框架来保存ring buffer信息。(存储设备:nor flash,其他类弄的设备都很类似)

static int apanic(struct notifier_block *this,unsigned long event,void *ptr)
{
	...
	...
	/*
	* 打印系统内存相关信息
	*/
	do_sysinfo(&si);
	printk(si);
	...
	/*其他相的打印的信息......*/
	...
	/*
	* 打印线程调用栈信息
	*/
	show_state_filter(0);
	
	/*
	* 最后一步,也是最重要的一步,保存所有信息到flash
	*/
	
	/* Return log buffer address */
	start = log_buf_addr_get();
	
	/* Return log buffer size */
	len = log_buf_len_get();
	
	/*这个是最简单的一种方法,直接把ring buffer拷贝到flash
	* 如果想要实现更好的,那么可以调用syslog_print_all(),即
	* 自己kmalloc一个buffer,所翻译之后的内容写入到flash.具体
	* 自行分析printk运行机制。
	*/
	mtd->_write(mtd,off,len,&wlen,start);
}

static void mtd_panic_notify_remove(struct mtd_info *mtd)
{
	/*这里并没有什么特别的操作,如果分配的特别的资源,那么需要进行释放*/
}

static void mtd_panic_notify_add(struct mtd_info *mtd)
{
	    if (strcmp(mtd->name,"crash"))
        return;
		获取crash 分区的mtd信息。
		/*
		* 这里可以做一些实始化的操作,比如erase crash 分区。识别并
		* 标志这个分区。等等,所有设计及功能,都可以来设计。
		*/
}
/*panic notifier callback*/
static struct notifier_block panic_blk = {
    .notifier_call  = apanic,};

/*mtd notifier callback*/
static struct mtd_notifier mtd_panic_notifier = {
    .add    = mtd_panic_notify_add,.remove = mtd_panic_notify_remove,};

int __init apanic_init(void)
{
	/*
	* 注册mtd 通知链回调,目的为了获取保存kernel crash info的分区信息。
	*  比如分区名为"crash"
	*  (kernel 创建一个分区,就会调用mtd_notifier.add回调。
	*	删除一个分区,就会调用mtd_notifier.remove回调)
	*/
    register_mtd_user(&mtd_panic_notifier);
	/*
	* 注册panic 回调。目的是为了在发生panic时,可以做一些想做的操作。
	* 比如保存信息到flash,做一些恢复操作。。。
	* panic_blk是一个回调函数,所有操作可以在这个函数里做。
	*/
    atomic_notifier_chain_register(&panic_notifier_list,&panic_blk);
    return 0;
}

Notice:

?echo c > /proc/sysrq-trigger //这个命令可以让kernel crash

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读