核心Oops資訊除錯
阿新 • • 發佈:2019-01-01
核心和模組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