内核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

猜你喜欢

转载自blog.csdn.net/mingtianyueni/article/details/53248328
今日推荐