轉自:http://blog.chinaunix.net/space.php?uid=24219701&do=blog&id=2876128
核心級的程式,總有死機的時候,如果運氣好,會看到一些所謂“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 <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
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” 說明了出錯原因是對null 指標的非法訪問
4、找到出錯位置:”PC is at D+0x1c/0x28[oops]”說明出錯的位置位於D函數位移的0x1c處。
5、反組譯碼找到出錯位置
# objdump –D –S oops.ko > log
如果在編譯過程中加上選項”-g”調試選項就可以看到相對應的C語言代碼,就很容易找到問題所在
加上調試選項: 在核心中Makefile檔案中使”-g”使能