[17184178.672000] Bad mode in data abort handler detected
[17184178.672000] Internal error: Oops - bad mode: 0 [#1] PREEMPT
[17184178.672000] CPU: 0 Not tainted (2.6.26.5 #1255)
[17184178.672000] PC is at 0xd201393a
[17184178.672000] LR is at 0xd20132fd
[17184178.672000] pc : [<d201393a>] lr : [
[17184178.672000] sp : d202df68 ip : 00000000 fp : 4021fc34
[17184178.672000] r10: 4003e000 r9 : 00000000 r8 : e0096c0c
[17184178.672000] r7 : e00aa340 r6 : e0096c04 r5 : e009e7c0 r4 : 000000b0
[17184178.672000] r3 : e001a418 r2 : 00000000 r1 : e00a11e8 r0 : 00accbad
[17184178.672000] Flags: nzCv IRQs off FIQs on Mode UND_32 ISA Thumb Segment user
[17184178.672000] Control: 0005317d Table: 21aa4000 DAC: 00000015
[17184178.672000] Stack: (0xd202df68 to 0xd002e800)
[17184178.672000] Code: 6868 0029 2800 d01a (6802)
[17184178.676000] ---[ end trace 31c4d86500000008 ]---
[17179681.444000] Internal error: Oops - bad syscall: ddf04c [#1] PREEMPT
[17179681.444000] Modules linked in: coma_dsr coma_voice coma_ss7 coma_cpi coma_config
[17179681.444000] CPU: 0 Not tainted (2.6.26.5 #659)
[17179681.444000] PC is at __dabt_usr+0x4/0x60
[17179681.444000] LR is at 0x377a4
[17179681.444000] pc : [<b4023884>] lr : [<000377a4>] psr: 80000093
[17179681.444000] sp : 4021fc10 ip : 0000f1b4 fp : 4021fc34
[17179681.444000] r10: 4003e000 r9 : 00000000 r8 : 003d0f00
[17179681.444000] r7 : 00000152 r6 : 400286f8 r5 : 402202b0 r4 : 00000000
[17179681.444000] r3 : 000000e4 r2 : 000000e4 r1 : 000f229c r0 : b428bcec
[17179681.444000] Flags: Nzcv IRQs off FIQs on Mode SVC_32 ISA ARM Segment user
[17179681.444000] Control: 0005317d Table: 21990000 DAC: 00000015
[17179681.444000] Process my_app(pid: 81, stack limit = 0xb5b8a268)
[17179681.444000] Stack: (0x4021fc10 to 0xb5b8c000)
[17179681.444000] fc00: 00000001 000000e4 000f229c 00000004
[17179681.444000] fc20: 402202f8 ffffffff 4021fc54 4021fc38 00035778 00037784 4003e000 00000000
[17179681.444000] fc40: 4021fc60 ffffffff afa66c90 4021fc58 40028788 00035740 00000000 402202b0
[17179681.444000] fc60: 402202f8 402202b0 400286f8 00000152 003d0f00 00000000 4003e000 afa66c90
[17179681.444000] fc80: 4021fc58 40028758 00000000 00000000 00000000 00000000 00000000 00000000
[17179681.444000] fca0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
[17179681.444000] fcc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
上面两种Oops:第一种是UND_32表示是发生了用户空间,第二种SVC_32表示发生在内核空间。pc表示出问题的地址。
几个常识概念:
1.程序计数器PC (R15),可以作为一般的通用寄存器使用,但有一些指令在使用R15时有一些限制。由于ARM采用了流水线处理器机制,当正确读取了PC的值时,该值为当前指令地址值加上8个字节。也就是说,对于ARM指令集来说,PC指向当前指令的下两条指令的地址。由于ARM指令是字对齐的,PC值的第0位和第一位总为 0。
2.寄存器R13(SP),通常用作堆栈指针,每一种模式都有自己的物理R13,程序初始化R13。当进入该模式
时,可以将要使用的寄存器保存在R13所指的栈中,当退出时,将弹出,从而实现了现场保护。
3.寄存器R14被称为链接寄存器(LR),当中存放每种模式下,当前子程序的返回地址或者
发生异常中断的时候,将R14设置成异常模式将要返回的地址。
4.寄存器R12
在给linux内核添加netfilter和iptables配置后,生成内核。下载到开发板的后启动插入网线出现错误提示:
eth1: link up, 100Mbps, full-duplex, lpa 0xCDE1 //插入网线后提示
------------------首先这些打印是kernel的panic函数列出的,具体意义可以直接找到kernel代码去看,很有帮助。
Unable to handle kernel paging request at virtual address 06400040
-----------------------空指针错误,这个一般就是非法地址访问,至于为什么导致非法,请关注PC周围的代码逻辑。有必要的话就printk出来。
pgd = c0004000
[06400040] *pgd=00000000
Internal error: Oops: 5 [#1] //错误提示 ------5代表什么?要在你的手册或kernel代码中查,null pointer??
Modules linked in: zd1211rw rt73usb rt2x00usb rt2x00lib asix usbnet mac80211 inp
ut_polldev
CPU: 0 Not tainted (2.6.30.4-LanxumDomas #19)
PC is at skb_release_data+0x74/0xc4
--------当前pc指针,这个十分有用!可以将kernel反汇编,然后找dequeue_task的相对位置0xc处
LR is at __kfree_skb+0x1c/0xd0
-----------------以下为当前寄存器值,也有帮助
pc : [
sp : c040dd90 ip : c040dda8 fp : c040dda4
r10: 00000001 r9 : c0465fc8 r8 : c3a22000
r7 : c3b54300 r6 : c3b50004 r5 : c3ae1600 r4 : c3ae1600
r3 : 00000000 r2 : c3b50822 r1 : 00000000 r0 : 06400040
Flags: nzCv IRQs on FIQs on Mode SVC_32 ISA ARM Segment kernel
Control: c000717f Table: 33af0000 DAC: 00000017
Process swapper (pid: 0, stack limit = 0xc040c268)
Stack: (0xc040dd90 to 0xc040e000)
dd80: c3ae1600 c3ae1600 c040ddbc c040dda8
dda0: c028266c c0282b04 c3ae19c0 c3ae1600 c040ddcc c040ddc0 c0282794 c0282660
-----------------以下是调用堆栈,可以看到程序的流程,便于跟踪。
Backtrace:
[
0)
r5:c3ae1600 r4:c3ae1600
[
r5:c3ae1600 r4:c3ae19c0
[
/0x18c)
[
me+0x238/0x26c)
r8:c3a22000 r7:c3ae19c0 r6:c3ae1600 r5:c3b50004 r4:80000000
[
1e4/0x380)
r7:00000000 r6:c0465fc8 r5:c3ae1600 r4:c3ae19c0
[
7c/0xd4)
[
194)
[
0)
[
[
[
Exception stack(0xc040df48 to 0xc040df90)
df40: f4100000 00000032 f4100000 60000013 c0084ed8 c040c000
df60: c0084ed8 c04398c4 3001ea00 41129200 3001e9cc c040df9c c040dfa0 c040df90
df80: c008550c c0084f38 60000013 ffffffff
r7:c04398c4 r6:04000000 r5:f4000000 r4:ffffffff
[
[
r7:c04104f0 r6:c0020d34 r5:c0439880 r4:c045d164
[
[
r5:c0439968 r4:c0007175
Code: e3500000 0a000006 e3a03000 e5823018 (e5904000)
Kernel panic - not syncing: Fatal exception in interrupt
Backtrace:
[
r7:c0282b6c r6:c0439ec0 r5:c0282b68 r4:c0282b68
[
[
r3:00000100 r2:00000080 r1:c0439ec0 r0:c03b5a34
[
[
/0x25c)
r7:c040f890 r6:06400040 r5:c040dd7c r4:00000000
[
x78/0x80)
[
8/0x9c)
r7:c041075c r6:00000005 r5:c040dd7c r4:c041070c
[
Exception stack(0xc040dd48 to 0xc040dd90)
dd40: 06400040 00000000 c3b50822 00000000 c3ae1600 c3ae1600
dd60: c3b50004 c3b54300 c3a22000 c0465fc8 00000001 c040dda4 c040dda8 c040dd90
dd80: c028266c c0282b68 20000013 ffffffff
[
0)
r5:c3ae1600 r4:c3ae1600
[
r5:c3ae1600 r4:c3ae19c0
[
/0x18c)
[
me+0x238/0x26c)
r8:c3a22000 r7:c3ae19c0 r6:c3ae1600 r5:c3b50004 r4:80000000
[
1e4/0x380)
r7:00000000 r6:c0465fc8 r5:c3ae1600 r4:c3ae19c0
[
7c/0xd4)
[
194)
[
0)
[
[
[
Exception stack(0xc040df48 to 0xc040df90)
df40: f4100000 00000032 f4100000 60000013 c0084ed8 c040c000
df60: c0084ed8 c04398c4 3001ea00 41129200 3001e9cc c040df9c c040dfa0 c040df90
df80: c008550c c0084f38 60000013 ffffffff
r7:c04398c4 r6:04000000 r5:f4000000 r4:ffffffff
[
[
r7:c04104f0 r6:c0020d34 r5:c0439880 r4:c045d164
[
[
r5:c0439968 r4:c0007175
出现以上错误后,可以根据错误的提示oops;以下介绍根据错误提示进行错误定位。
1.首先在编译生成内核的时候同时生成了一个vmlinux,使用gdb。
在内核配置时,make menuconfig 要打开complie with debug info选项。
注意这行: PC is at skb_release_data+0x74/0xc4
这告诉我们,skb_release_data函数有0xc4这么大,而Oops发生在0x74处。 那么我们先看一下skb_release_data从哪里开始:
# grep skb_release_data ./System.map
c0282af4 t skb_release_data
于是我们知道在系统出现错误时程序指针在 c0282af4+0x74=c0282b68
2.然后用gdb查看,gdb ./vmlinux (在linux目录下执行),进入调试模式。
(gdb) b *0xc0282b68
Breakpoint 1 at 0xc0282b68: file net/core/skbuff.c ,line312
这就是告诉我们在哪个文件,在哪一行。如此知道了错误的位置,具体的原因带解决。
3,反汇编
(gdb) disassemble 0xc0282b68