当前位置: 技术问答>linux和unix
如何分析段错误
来源: 互联网 发布时间:2016-09-05
本文导语: 我insmod一个模块的时候出错,打印出如下信息: Unable to handle kernel NULL pointer dereference at virtual address 00000010 pgd = ceed0000 [00000010] *pgd=0ee7e031, *pte=00000000, *ppte=00000000 Internal error: Oops: 17 [#1] Modules linked in: e...
我insmod一个模块的时候出错,打印出如下信息:
Unable to handle kernel NULL pointer dereference at virtual address 00000010
pgd = ceed0000
[00000010] *pgd=0ee7e031, *pte=00000000, *ppte=00000000
Internal error: Oops: 17 [#1]
Modules linked in: epl sg sd_mod usb_storage scsi_mod uhci_hcd ehci_hcd usbcore moxa_dio moxa_software_id mxser_uc8400(P) nfs nfs_acl lockd sunrpc ixp400_eth ixp400
CPU: 0 Tainted: P (2.6.23.1 #986)
pc : [] lr : [] psr: 20000093
sp : cf7b3de8 ip : 00000004 fp : cf7b3e08
r10: 00008060 r9 : 00000002 r8 : 34092e16
r7 : c026e260 r6 : 000000d0 r5 : cef30000 r4 : a0000013
r3 : a0000093 r2 : 00000000 r1 : 000000d0 r0 : c026e260
Flags: nzCv IRQs off FIQs on Mode SVC_32 ISA ARM Segment user
Control: 000039ff Table: 0eed0000 DAC: 00000015
Process insmod (pid: 917, stack limit = 0xcf7b225
Stack: (0xcf7b3de8 to 0xcf7b4000)
3de0: bf1d9180 bf1d9180 cef30000 00000024 00008000 cf7b3e3c
3e00: cf7b3e0c bf1d7ddc c00795f4 cf7b3e40 cf7b3e44 bf1d9180 0000803c 00000024
3e20: 00008000 bf1e25f0 00000002 cf7b3e70 cf7b3e6c cf7b3e40 bf1d674c bf1d7d70
3e40: cf7b3e4c c003b2c4 bf1e25f0 cf7b3e70 00000024 000249f0 bf1dd310 bf1dd308
3e60: cf7b3e88 cf7b3e70 bf1ca244 bf1d6704 c003b2c4 cf7b3eac bf1e753c cf7b3e98
3e80: cf7b3e8c bf1ca300 bf1ca214 cf7b3ecc cf7b3e9c bf1d4f60 bf1ca2fc cf7b3ebc
3ea0: cf7b3eac c003b2c4 c003af38 bf1db4b8 bf1db838 bf1db868 00000000 00000064
3ec0: cf7b3f04 cf7b3ed0 bf107184 bf1d4ea4 c0074964 bf1dc590 bf1dc590 bf1dc590
3ee0: bf1dc590 cccccccd d08d8fc0 00000019 bf1dc59c bf1dc590 cf7b3fa4 cf7b3f08
3f00: c005a778 bf10700c 00000000 cf7b2000 00000000 00000000 00000000 00000000
3f20: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
3f40: 0000000c 00000018 d08e4068 cf71c030 00000000 d08d9268 d08c1000 0000000b
3f60: 00000000 000005d6 000005d6 d08d9380 00000017 00000000 00000000 00000028
3f80: beab2e83 beab2dac 00000080 c001dfc4 cf7b2000 401a3048 00000000 cf7b3fa8
3fa0: c001de20 c005a65c beab2e83 beab2dac 00900080 401aa008 00027418 00097008
3fc0: 00000028 beab2e83 beab2dac 4000b10c 00000002 0000c814 401a3048 beab2d24
3fe0: beab2cf0 beab2ce4 0000fa34 40153f00 60000010 00900080 00000000 00000000
Backtrace:
Function entered at [] from []
r7:00008000 r6:00000024 r5:cef30000 r4:bf1d9180
Function entered at [] from []
Function entered at [] from []
Function entered at [] from []
r5:bf1e753c r4:cf7b3eac
Function entered at [] from []
Function entered at [] from []
r5:00000064 r4:00000000
Function entered at [] from []
Function entered at [] from []
Code: e121f003 e590c044 e35c0000 0a000012 (e59c500c)
从此输出的错误信息中,我如何能最快的定位到出错语句?
(用printk(...)一步步定位的方式是能找到错误点,但效率太低,我希望有更高效的找错方法)
谢谢!
Unable to handle kernel NULL pointer dereference at virtual address 00000010
pgd = ceed0000
[00000010] *pgd=0ee7e031, *pte=00000000, *ppte=00000000
Internal error: Oops: 17 [#1]
Modules linked in: epl sg sd_mod usb_storage scsi_mod uhci_hcd ehci_hcd usbcore moxa_dio moxa_software_id mxser_uc8400(P) nfs nfs_acl lockd sunrpc ixp400_eth ixp400
CPU: 0 Tainted: P (2.6.23.1 #986)
pc : [] lr : [] psr: 20000093
sp : cf7b3de8 ip : 00000004 fp : cf7b3e08
r10: 00008060 r9 : 00000002 r8 : 34092e16
r7 : c026e260 r6 : 000000d0 r5 : cef30000 r4 : a0000013
r3 : a0000093 r2 : 00000000 r1 : 000000d0 r0 : c026e260
Flags: nzCv IRQs off FIQs on Mode SVC_32 ISA ARM Segment user
Control: 000039ff Table: 0eed0000 DAC: 00000015
Process insmod (pid: 917, stack limit = 0xcf7b225
Stack: (0xcf7b3de8 to 0xcf7b4000)
3de0: bf1d9180 bf1d9180 cef30000 00000024 00008000 cf7b3e3c
3e00: cf7b3e0c bf1d7ddc c00795f4 cf7b3e40 cf7b3e44 bf1d9180 0000803c 00000024
3e20: 00008000 bf1e25f0 00000002 cf7b3e70 cf7b3e6c cf7b3e40 bf1d674c bf1d7d70
3e40: cf7b3e4c c003b2c4 bf1e25f0 cf7b3e70 00000024 000249f0 bf1dd310 bf1dd308
3e60: cf7b3e88 cf7b3e70 bf1ca244 bf1d6704 c003b2c4 cf7b3eac bf1e753c cf7b3e98
3e80: cf7b3e8c bf1ca300 bf1ca214 cf7b3ecc cf7b3e9c bf1d4f60 bf1ca2fc cf7b3ebc
3ea0: cf7b3eac c003b2c4 c003af38 bf1db4b8 bf1db838 bf1db868 00000000 00000064
3ec0: cf7b3f04 cf7b3ed0 bf107184 bf1d4ea4 c0074964 bf1dc590 bf1dc590 bf1dc590
3ee0: bf1dc590 cccccccd d08d8fc0 00000019 bf1dc59c bf1dc590 cf7b3fa4 cf7b3f08
3f00: c005a778 bf10700c 00000000 cf7b2000 00000000 00000000 00000000 00000000
3f20: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
3f40: 0000000c 00000018 d08e4068 cf71c030 00000000 d08d9268 d08c1000 0000000b
3f60: 00000000 000005d6 000005d6 d08d9380 00000017 00000000 00000000 00000028
3f80: beab2e83 beab2dac 00000080 c001dfc4 cf7b2000 401a3048 00000000 cf7b3fa8
3fa0: c001de20 c005a65c beab2e83 beab2dac 00900080 401aa008 00027418 00097008
3fc0: 00000028 beab2e83 beab2dac 4000b10c 00000002 0000c814 401a3048 beab2d24
3fe0: beab2cf0 beab2ce4 0000fa34 40153f00 60000010 00900080 00000000 00000000
Backtrace:
Function entered at [] from []
r7:00008000 r6:00000024 r5:cef30000 r4:bf1d9180
Function entered at [] from []
Function entered at [] from []
Function entered at [] from []
r5:bf1e753c r4:cf7b3eac
Function entered at [] from []
Function entered at [] from []
r5:00000064 r4:00000000
Function entered at [] from []
Function entered at [] from []
Code: e121f003 e590c044 e35c0000 0a000012 (e59c500c)
从此输出的错误信息中,我如何能最快的定位到出错语句?
(用printk(...)一步步定位的方式是能找到错误点,但效率太低,我希望有更高效的找错方法)
谢谢!
|
从寄存器内容可以看到 出错地址 pc : [] 返回地址lr : []
从Backtrace可以看到 函数入口 Function entered at [] 上层函数 from []
出错的语句和函数的地址都有了,通过检查符号表、反汇编,应该很快就可以定位。
从Backtrace可以看到 函数入口 Function entered at [] 上层函数 from []
出错的语句和函数的地址都有了,通过检查符号表、反汇编,应该很快就可以定位。
|
0x30 = 48
ARM9每条指令长度是4字节,PC就是第12条指令。
硬件是IXP400系列,采用ArmV5TE体系结构,五级流水线,分别为取指,译码,执行,缓存,写回
因为流水线的原因,对于数据访问指令,PC和出错指令相差2条指令。
|
如这位兄弟所说,通过backtrace可以找到错误代码的地方,有时并不是当前指令错误,库函数出现问题的机率较小,但也不能完全说没有问题。大部分是因为前面传入的参数有问题导致。
这需要编译的时候把包含符号表的ELF文件保留,然后可到处符号表以及反汇编
反汇编的命令是objdump,使用-D 和-S参数可以反汇编,汇编代码和源码交替
lr寄存器是函数调用的返回地址,即上一个函数调用当前函数的地方,通过调用关系找错误代码的地方
如楼主所说printk有时并不能准确定位问题所在,字符放在缓存中没有打印出来。有时添加打印会导致编译出来的可执行代码出现大的变化,错误的地方会变化,或者没有了,以前做开发时碰到过。
|
操作步骤如下:
1、在编译源代码的时候加上选项-g -c,生成对应.o文件为hello.o
2、找到对应平台(你用的是ARM的就要找对应ARM的)下的objdump工具,执行objdump -j .text -Sl hello.o > 2.txt
3、打开文件2.txt,搜索上面OOPS中对应最后一行e59c500c或者0a000012 指令
Code: e121f003 e590c044 e35c0000 0a000012 (e59c500c)
4、该指令附近就有你源代码对应的行数。
1、在编译源代码的时候加上选项-g -c,生成对应.o文件为hello.o
2、找到对应平台(你用的是ARM的就要找对应ARM的)下的objdump工具,执行objdump -j .text -Sl hello.o > 2.txt
3、打开文件2.txt,搜索上面OOPS中对应最后一行e59c500c或者0a000012 指令
Code: e121f003 e590c044 e35c0000 0a000012 (e59c500c)
4、该指令附近就有你源代码对应的行数。