2012年(1008)
分类:
2012-08-01 11:05:56
原文地址:Linux内核异常 作者:luozhiyong131
内核级的程序,总有死机的时候,如果运气好,会看到一些所谓“Oops”信息(在屏幕上或系统日志中)
比如:
Unable to handle kernel paging request at virtual address f899b670
printing eip:
c01de48c
*pde = 00737067
Oops: 0002 [#1]
Modules linked in: bluesmoke_e752x bluesmoke_mc md5 ipv6 parport_pc
lp parport nls_cp936 vfat fat dm_mod button battery asus_acpi ac joydev
CPU: 0
EIP: 0060:[] Not tainted VLI
EFLAGS: 00210286 (2.6.9-11.21AXKProbes)
EIP is at kobject_add+0x83/0xd7
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
Oops 可以看成是内核级的Segmentation Fault。应用程序如果进行了非法内存访问或执行了非法指令,会得到Segfault信号,一般的行为是coredump,应用程序也可以自己截获Segfault信号,自行处理。如果内核自己犯了这样的错误,则会打出Oops信息。
Oops异常分析:编写内核模块,产生内核异常,根据OOPS分析异常原因
异常代码:
#include
#include
#include
void D(void)
{
int *p = NULL;
int a = 6;
printk("Function D\n");
*p = a+5;
}
void C(void)
{
printk("Function C\n");
D();
}
void B(void)
{
printk("Function B\n");
C();
}
void A(void)
{
printk("Function A\n");
B();
}
int oops_init(void)
{
printk("oops init\n");
A();
return 0;
}
void oops_exit(void)
{
printk("oops exit!\n");
}
module_init(oops_init);
module_exit(oops_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("David Xie");
1、编译加载模块
2、加载模块时出现了oops错误信息
3、分析错误原因:“Unable to handle kernel NULL pointer dereference at vitual address 00000000” 说明了出错原因是对空指针的非法访问
4、找到出错位置:”PC is at D+0x1c/0x28[oops]”说明出错的位置位于D函数偏移的0x1c处。
5、反汇编找到出错位置
# objdump –D –S oops.ko > log
如果在编译过程中加上选项”-g”调试选项就可以看到相对应的C语言代码,就很容易找到问题所在
加上调试选项: 在内核中Makefile文件中使”-g”使能