1. 程式人生 > >核心Oops資訊除錯

核心Oops資訊除錯

核心和模組oops資訊除錯

模組載入後出錯,列印資訊:

Unable to handle kernel NULL pointer dereference at virtual address 00000014  //指標引起的問題
pgd = c3ae8000
[00000014] *pgd=33adb831, *pte=00000000, *ppte=00000000
Internal error: Oops: 817 [#1] ARM
Modules linked in: usb_mouse1(O+)
CPU: 0    Tainted: G           O  (3.4.2 #8)
PC is at usb_mouse_probe+0x124
/0x610 [usb_mouse1] //PC的值,這裡表示PC指向的是usb_mouse_probe函式偏移的0x124處,一共0x610 LR is at usb_mouse_probe+0x530/0x610 [usb_mouse1] pc : [<bf000428>] lr : [<bf000834>] psr: 60000013 //各個暫存器的值 sp : c3a83e40 ip : c3a127a0 fp : 00000001 r10: 00000034 r9 : 00000001 r8 : 00000158 r7 : c3a85e00 r6 : c3a97c00 r5 : 00000001 r4 : c3a12832 r3 : 00000000 r2 : 00000001
r1 : c068b588 r0 : c3a13000 Flags: nZCv IRQs on FIQs on Mode SVC_32 ISA ARM Segment user Control: c000717f Table: 33ae8000 DAC: 00000015 Process insmod (pid: 973, stack limit = 0xc3a82270) //發生錯誤的程序 Stack: (0xc3a83e40 to 0xc3a84000) //下面是棧裡的值 3e40: c3b08b88 c01e2978 00000000 c3a96148 c3a83e70 c3b08b88 00000000
000000d0 3e60: c3a85e20 c3a85e00 c3a85e20 bf001050 c3a85e20 c3a97c00 bf001020 bf000984 3e80: 00000000 c0379af4 c3a85e20 c3a85e20 bf001050 bf001050 c06ac854 c068ab80 3ea0: 00000000 c02e0420 c3a85e20 c3a85e54 bf001050 c02e05b0 c3a10260 c02e063c 3ec0: 00000000 c3a83ed0 bf001050 c02deec0 c385c618 c3a10410 bf001020 bf001020 3ee0: bf001050 bf001050 c067de44 c02df600 bf000fec 00000000 00000000 bf001020 3f00: bf001050 bf000fec bf001050 c067de44 bf003000 c02e0bfc bf001020 bf0010a0 3f20: bf000fec bf001050 c067de44 c0379888 00019c44 000e2e38 bf0010a0 c3a82000 3f40: c0115668 bf003014 00019c44 c0108750 00000000 00000000 00000000 c0192ad4 3f60: 00019c44 00019c44 000e2e38 bf0010a0 00000000 c0115668 c3a82000 00000000 3f80: befc0e84 c015b6a8 c381dc88 c381dc80 c3842da0 00000001 00000000 befc0e88 3fa0: 00000080 c01154c0 00000001 00000000 000ef040 00019c44 000e2e38 00000000 3fc0: 00000001 00000000 befc0e88 00000080 befc0e84 befc0e88 00000001 befc0e84 3fe0: 00000069 befc0b44 000220a0 b6e2ac24 60000010 000ef040 00000000 00000000 [<bf000428>] (usb_mouse_probe+0x124/0x610 [usb_mouse1]) from [<c0379af4>] (usb_probe_interface+0xc8/0x15c) //棧回溯 [<c0379af4>] (usb_probe_interface+0xc8/0x15c) from [<c02e0420>] (driver_probe_device+0x84/0x214) [<c02e0420>] (driver_probe_device+0x84/0x214) from [<c02e063c>] (__driver_attach+0x8c/0x90) [<c02e063c>] (__driver_attach+0x8c/0x90) from [<c02deec0>] (bus_for_each_dev+0x64/0x90) [<c02deec0>] (bus_for_each_dev+0x64/0x90) from [<c02df600>] (bus_add_driver+0x180/0x248) [<c02df600>] (bus_add_driver+0x180/0x248) from [<c02e0bfc>] (driver_register+0x58/0x130) [<c02e0bfc>] (driver_register+0x58/0x130) from [<c0379888>] (usb_register_driver+0x6c/0x120) [<c0379888>] (usb_register_driver+0x6c/0x120) from [<bf003014>] (usb_mouse_init+0x14/0x40 [usb_mouse1]) [<bf003014>] (usb_mouse_init+0x14/0x40 [usb_mouse1]) from [<c0108750>] (do_one_initcall+0x34/0x17c) [<c0108750>] (do_one_initcall+0x34/0x17c) from [<c015b6a8>] (sys_init_module+0x84/0x19c) [<c015b6a8>] (sys_init_module+0x84/0x19c) from [<c01154c0>] (ret_fast_syscall+0x0/0x2c) Code: e3530002 03a02001 02433002 13a03000 (05832014) ---[ end trace 182099cc61be0d99 ]--- Segmentation fault

從PC的值,可以定位錯誤發生的地方,這裡可以從

PC is at usb_mouse_probe+0x124/0x610 [usb_mouse1]

看出PC發生在usb_mouse_probe函式偏移0x124的位置
在板子上執行

# cat /proc/kallsyms    // 核心函式、載入的函式的地址,t是靜態函式,T是全域性函式

擷取對我們有用的結果:

00000000 a usb_mouse1.c [usb_mouse1]
bf000000 t usb_mouse_read       [usb_mouse1]
bf000000 t $a   [usb_mouse1]
bf000914 t usb_mouse_exit       [usb_mouse1]
bf000914 t $a   [usb_mouse1]
bf00091c t $d   [usb_mouse1]
bf000008 t usb_mouse_irq        [usb_mouse1]
bf0000dc t $d   [usb_mouse1]
bf0000f0 t usb_mouse_release    [usb_mouse1]
bf0000f0 t $a   [usb_mouse1]
bf000144 t $d   [usb_mouse1]
bf000148 t usb_mouse_open       [usb_mouse1]
bf000148 t $a   [usb_mouse1]
bf00028c t $d   [usb_mouse1]
bf0002a8 t usb_mouse_disconnect [usb_mouse1]
bf0002a8 t $a   [usb_mouse1]
bf0002fc t $d   [usb_mouse1]
bf000304 t usb_mouse_probe      [usb_mouse1]
bf000304 t $a   [usb_mouse1]
bf00037c t $d   [usb_mouse1]
bf000390 t $a   [usb_mouse1]
bf000844 t $d   [usb_mouse1]
bf003000 t usb_mouse_init       [usb_mouse1]
bf003000 t $a   [usb_mouse1]
bf003030 t $d   [usb_mouse1]
bf000984 r usb_mouse_id_table   [usb_mouse1]
bf000984 r $d   [usb_mouse1]
bf0009ac r usb_mouse_fops       [usb_mouse1]
c4868a88 ? __mod_description389 [usb_mouse1]
c4868a9f ? __mod_license388     [usb_mouse1]
bf001020 d usb_mouse_driver     [usb_mouse1]
bf001020 d $d   [usb_mouse1]
bf001090 d usb_mouse_class      [usb_mouse1]
bf0011e8 b $d   [usb_mouse1]
bf0011e8 b devmap       [usb_mouse1]
00000000 a usb_mouse1.mod.c     [usb_mouse1]
c4868aac ? __module_depends     [usb_mouse1]
c4868ab5 ? __mod_vermagic5      [usb_mouse1]
bf00115c d $d   [usb_mouse1]
c4873573 n $d   [usb_mouse1]
c0376f88 u usb_alloc_urb        [usb_mouse1]
c0376ce8 u usb_free_urb [usb_mouse1]
c02dfeec u dev_get_drvdata      [usb_mouse1]
c02851d0 u _clear_bit   [usb_mouse1]
bf0010a0 d __this_module        [usb_mouse1]
c02876a0 u _set_bit     [usb_mouse1]
c011a4dc u __aeabi_unwind_cpp_pr0       [usb_mouse1]
c037981c u usb_register_driver  [usb_mouse1]
bf000914 t cleanup_module       [usb_mouse1]
c018de08 u kfree        [usb_mouse1]
bf003000 t init_module  [usb_mouse1]
c036f110 u usb_find_interface   [usb_mouse1]
c018eab8 u kmem_cache_alloc     [usb_mouse1]
c03768e0 u usb_submit_urb       [usb_mouse1]
c037ba10 u usb_register_dev     [usb_mouse1]
c04cfa24 u printk       [usb_mouse1]
c037969c u usb_deregister       [usb_mouse1]
c0290a60 u sprintf      [usb_mouse1]
c037b974 u usb_deregister_dev   [usb_mouse1]
c03767f4 u usb_kill_urb [usb_mouse1]
c066f5d4 u malloc_sizes [usb_mouse1]
c02e00bc u dev_set_drvdata      [usb_mouse1]
c018e9e0 u __kmalloc    [usb_mouse1]
c02863c4 u _find_next_zero_bit_le       [usb_mouse1]

usb_mouse_probe的基地址是bf000304,偏移0x124後,位置就是bf000408,這與錯誤資訊中的

pc : [<bf000428>]    lr : [<bf000834>]    psr: 60000013 

一樣,有時會顯示pc:[],就可以用上面資訊確定位置。在這裡又可以看出模組的絕對位置是從bf000000開始,那麼模組的反彙編檔案需要找的位置要減去偏移量,算出錯誤的相對偏移,也就是bf000408減去bf000000等於408
確定了位置後,就可以反彙編二進位制檔案找到對應程式碼。
如果錯誤是發生在核心檔案中,反彙編vmlinux檔案定位,直接尋找絕對位置就可以,不需要找相對偏移的地方
如果錯誤發生在模組裡,反彙編模組的檔案後,尋找相對偏移量的位置。
這裡的錯誤發生在了載入的模組中,所以反彙編載入的模組進行分析:

arm-linux-objdump -S usb_mouse1.ko > objdump_mouse1.txt

-S引數表示反彙編的時候帶上原始碼,-D引數表示純反彙編。

反彙編後找到相對偏移量是408位置的程式碼查看出錯的程式碼:

        else if(intf->cur_altsetting->desc.bInterfaceProtocol == USB_INTERFACE_PROTOCOL_MOUSE) {
                usb_mouse_dev->dev_type = USB_DEV_TYPE_MOUSE;
 428:   05832014        streq   r2, [r3, #20]

這裡實際上usb_mouse_dev指標指向了NULL,dev_type成員偏移量是20,十六進位制是0x14,和錯誤資訊匹配

Unable to handle kernel NULL pointer dereference at virtual address 00000014