kernel crash dump 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

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值