九鼎创展论坛

标题: x210ii接USB摄像头后就死机 [打印本页]

作者: kangear    时间: 2012-11-22 10:22
标题: x210ii接USB摄像头后就死机
板子:x210ii
映像:2012年7月份的映像
以下是接上之后的打印信息:
[  752.375870] usb 2-1.1: new full speed USB device using s5p-ohci and address 3
[  752.482112] gspca: probing 0ac8:301b
[  753.695856] zc3xx: probe 2wr ov vga 0x0000
[  753.746852] zc3xx: probe sensor -> 0011
[  753.746893] zc3xx: Find Sensor HV7131R(c)
[  753.751097] input: zc3xx as /devices/platform/s5p-ohci/usb2/2-1/2-1.1/input/input4
[  753.751737] gspca: video3 created
[  753.751774] gspca: found int in endpoint: 0x82, buffer_len=8, interval=10
[  753.751870] kernel BUG at arch/arm/mm/dma-mapping.c:409!
[  753.761250] Unable to handle kernel NULL pointer dereference at virtual address 00000000
[  753.763378] pgd = c0004000
[  753.767827] [00000000] *pgd=00000000
[  753.770921] Internal error: Oops: 817 [#1] PREEMPT
[  753.774341] last sysfs file: /sys/power/state
[  753.778674] Modules linked in:
[  753.781710] CPU: 0    Not tainted  (2.6.35.7 #10)
[  753.786396] PC is at __bug+0x24/0x30
[  753.789945] LR is at schedule+0x280/0x2f8
[  753.793929] pc : [<c00c7ca4>]    lr : [<c04d779c>]    psr: 60000013
[  753.793934] sp : dfca1ba0  ip : dfca1ac8  fp : dfca1bac
[  753.805365] r10: ccc87a88  r9 : dbca0b80  r8 : 00000008
[  753.810565] r7 : 000000d0  r6 : 6f06a000  r5 : dff15000  r4 : ccc87a80
[  753.817064] r3 : 00000000  r2 : 00000000  r1 : 00000002  r0 : 00000042
[  753.823565] Flags: nZCv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment kernel
[  753.830843] Control: 10c5387d  Table: 4a418019  DAC: 00000017
[  753.836561]
[  753.836564] PC: 0xc00c7c24:
[  753.840806] 7c24  e24cb004 e1a0200d e1a01000 e3c23d7f e3c3303f e593000c ebffffc6 e89da800
[  753.848951] 7c44  e1a0c00d e92dd800 e24cb004 e59f3024 e5933000 e5933038 e3530000 0a000003
[  753.857097] 7c64  e12fff33 e3a03ffa e0000093 e89da800 e1a00003 e89da800 c06da5c0 e1a0c00d
[  753.865243] 7c84  e92dd800 e24cb004 e1a03000 e1a02001 e59f0010 e1a01003 eb103d0f e3a03000
[  753.873389] 7ca4  e5833000 eafffffe c060c42c e1a0c00d e92dd800 e24cb004 e59f0004 e30012e1
[  753.881535] 7cc4  ebffffed c060c445 e1a0c00d e92dd800 e24cb004 e1a01000 e59f000c eb103cfe
[  753.889680] 7ce4  e59f0008 e30012c5 ebffffe3 c060c45d c060c445 e1a0c00d e92ddff0 e24cb004
[  753.897826] 7d04  e24dd044 e1a0200d e5917040 e3c23d7f e591803c e3c3303f e3a02000 e2177020
[  753.905973]
[  753.905975] LR: 0xc04d771c:
[  753.910218] 771c  0a000001 e1550004 0a000012 e59f30dc e5932000 e5943170 e0223003 e1b03423
[  753.918364] 773c  0a000001 e1a00004 ebefd715 e59f30c0 e5942184 e5933184 e1520003 0a000001
[  753.926510] 775c  e1a00004 ebefcf3b e5940024 e1a01004 e2800207 ebefd778 e59630dc e1a00006
[  753.934656] 777c  e3530000 058630e0 059f3078 05835440 e5961004 e5972004 ebefb1f6 ebf023df
[  753.942802] 779c  ea000001 e59f005c eb0009af e1a0300d e3c34d7f e3c4403f e594300c e5933014
[  753.950947] 77bc  e3530000 ba000005 eb000a91 e3500000 b59f3030 b5936434 b2868f62 baffff61
[  753.959093] 77dc  e5943004 e2433001 e5843004 e5943000 e3130002 089da9f8 eaffff4b e3a03000
[  753.967239] 77fc  e5863000 eaffff84 c06a1580 c04dbd00 c0694878 c06b0234 e1a0c00d e92dd878
[  753.975386]
[  753.975388] SP: 0xdfca1b20:
[  753.979631] 1b20  5d303738 c04d0020 0000003f 00001000 c092bfe0 ffffffff dfca1b8c 6f06a000
[  753.987777] 1b40  000000d0 00000008 dfca1bac dfca1b58 c00c3a6c c00c321c 00000042 00000002
[  753.995923] 1b60  00000000 00000000 ccc87a80 dff15000 6f06a000 000000d0 00000008 dbca0b80
[  754.004068] 1b80  ccc87a88 dfca1bac dfca1ac8 dfca1ba0 c04d779c c00c7ca4 60000013 ffffffff
[  754.012214] 1ba0  dfca1bbc dfca1bb0 c00c9df8 c00c7c8c dfca1c04 dfca1bc0 c02d45d8 c00c9dc8
[  754.020360] 1bc0  c01441b0 c04d9eb4 c04d88b4 205bb408 33353720 3135372e 5d373337 00000003
[  754.028506] 1be0  00000001 dc388800 db8290ac 00000008 dbca0b80 0000000a dfca1c2c dfca1c08
[  754.036651] 1c00  c02d5414 c02d3f70 ffffffff ccc87a80 dbd09800 dc388800 db8290ac 00000008

。。。。。。。。字数太多,中间略。。。。。。。。。。。。。

[  754.985731] [<c0284348>] (device_attach+0x0/0x78) from [<c0283d00>] (bus_probe_device+0x2c/0x48)
[  754.994477]  r5:dc388870 r4:dc388868
[  754.998037] [<c0283cd4>] (bus_probe_device+0x0/0x48) from [<c0281e44>] (device_add+0x32c/0x49c)
[  755.006703] [<c0281b18>] (device_add+0x0/0x49c) from [<c02d1840>] (usb_new_device+0x74/0xd0)
[  755.015108] [<c02d17cc>] (usb_new_device+0x0/0xd0) from [<c02d214c>] (hub_thread+0x8b0/0xde4)
[  755.023594]  r6:00000000 r5:dc388800 r4:dff52600 r3:00000000
[  755.029238] [<c02d189c>] (hub_thread+0x0/0xde4) from [<c00fdd28>] (kthread+0x8c/0x94)
[  755.037038] [<c00fdc9c>] (kthread+0x0/0x94) from [<c00eb22c>] (do_exit+0x0/0x5d4)
[  755.044479]  r6:c00eb22c r5:c00fdc9c r4:dfc37f18
[  755.049077] Code: e59f0010 e1a01003 eb103d0f e3a03000 (e5833000)
[  755.071021] ---[ end trace 86ba27cdd751d4a7 ]---
[  755.071073] Kernel panic - not syncing: Fatal exception
[  755.071118] Backtrace:
[  755.071165] [<c00c7e60>] (dump_backtrace+0x0/0x110) from [<c04d6fec>] (dump_stack+0x18/0x1c)
[  755.075794]  r6:dfca02f0 r5:dfc92700 r4:c06a1b44 r3:00000000
[  755.081401] [<c04d6fd4>] (dump_stack+0x0/0x1c) from [<c04d7064>] (panic+0x74/0xf0)
[  755.088982] [<c04d6ff0>] (panic+0x0/0xf0) from [<c00c833c>] (die+0x188/0x1cc)
[  755.096066]  r3:00000001 r2:dfca1a18 r1:60000113 r0:c060c630
[  755.101682] [<c00c81b4>] (die+0x0/0x1cc) from [<c00ca7a4>] (__do_kernel_fault+0x6c/0x8c)
[  755.109755]  r8:00000000 r7:dfca1b58 r6:00000000 r5:00000817 r4:00000000
[  755.116412] [<c00ca738>] (__do_kernel_fault+0x0/0x8c) from [<c00ca9a8>] (do_page_fault+0x1e4/0x200)
[  755.125440]  r8:00000817 r7:00000000 r6:dfca1b58 r5:00000000 r4:dfc92700
[  755.131916] r3:dfca1b58
[  755.134530] [<c00ca7c4>] (do_page_fault+0x0/0x200) from [<c00c3248>] (do_DataAbort+0x38/0xa0)
[  755.143040] [<c00c3210>] (do_DataAbort+0x0/0xa0) from [<c00c3a6c>] (__dabt_svc+0x4c/0x60)
[  755.151175] Exception stack(0xdfca1b58 to 0xdfca1ba0)
[  755.156205] 1b40:                                                       00000042 00000002
[  755.164350] 1b60: 00000000 00000000 ccc87a80 dff15000 6f06a000 000000d0 00000008 dbca0b80
[  755.172500] 1b80: ccc87a88 dfca1bac dfca1ac8 dfca1ba0 c04d779c c00c7ca4 60000013 ffffffff
[  755.180637]  r8:00000008 r7:000000d0 r6:6f06a000 r5:dfca1b8c r4:ffffffff
[  755.187297] [<c00c7c80>] (__bug+0x0/0x30) from [<c00c9df8>] (___dma_single_cpu_to_dev+0x3c/0x6c)
[  755.196075] [<c00c9dbc>] (___dma_single_cpu_to_dev+0x0/0x6c) from [<c02d45d8>] (usb_hcd_submit_urb+0x674/0x800)
[  755.206126] [<c02d3f64>] (usb_hcd_submit_urb+0x0/0x800) from [<c02d5414>] (usb_submit_urb+0x25c/0x280)
[  755.215396] [<c02d51b8>] (usb_submit_urb+0x0/0x280) from [<c032c8d4>] (gspca_input_create_urb+0x128/0x18c)
[  755.225009]  r8:00000008 r7:db8290ac r6:dc388800 r5:dbd09800 r4:ccc87a80
[  755.231485] r3:ffffffff
[  755.234094] [<c032c7ac>] (gspca_input_create_urb+0x0/0x18c) from [<c032f3f8>] (gspca_dev_probe+0x2c0/0x3c8)
[  755.243822] [<c032f138>] (gspca_dev_probe+0x0/0x3c8) from [<c0330c20>] (sd_probe+0x24/0x30)
[  755.252139] [<c0330bfc>] (sd_probe+0x0/0x30) from [<c02d85f0>] (usb_probe_interface+0xf4/0x134)
[  755.260807] [<c02d84fc>] (usb_probe_interface+0x0/0x134) from [<c0284538>] (driver_probe_device+0xb0/0x160)
[  755.270508] [<c0284488>] (driver_probe_device+0x0/0x160) from [<c02846b8>] (__device_attach+0x44/0x48)
[  755.279777]  r7:00000000 r6:00000000 r5:ccd0b420 r4:c06ca7b8
[  755.285399] [<c0284674>] (__device_attach+0x0/0x48) from [<c0283454>] (bus_for_each_drv+0x54/0x90)
[  755.294335]  r5:c0284674 r4:ccd0b420
[  755.297872] [<c0283400>] (bus_for_each_drv+0x0/0x90) from [<c02843a0>] (device_attach+0x58/0x78)
[  755.306640]  r6:dc388868 r5:ccd0b420 r4:ccd0b454
[  755.311218] [<c0284348>] (device_attach+0x0/0x78) from [<c0283d00>] (bus_probe_device+0x2c/0x48)
[  755.319982]  r5:ccd0b428 r4:ccd0b420
[  755.323524] [<c0283cd4>] (bus_probe_device+0x0/0x48) from [<c0281e44>] (device_add+0x32c/0x49c)
[  755.332209] [<c0281b18>] (device_add+0x0/0x49c) from [<c02d7718>] (usb_set_configuration+0x538/0x5d4)
[  755.341401] [<c02d71e0>] (usb_set_configuration+0x0/0x5d4) from [<c02dec70>] (generic_probe+0x74/0xc0)
[  755.350666] [<c02debfc>] (generic_probe+0x0/0xc0) from [<c02d7860>] (usb_probe_device+0x1c/0x20)
[  755.359414]  r6:00000000 r5:dc388868 r4:c06c3074
[  755.363992] [<c02d7844>] (usb_probe_device+0x0/0x20) from [<c0284538>] (driver_probe_device+0xb0/0x160)
[  755.373372] [<c0284488>] (driver_probe_device+0x0/0x160) from [<c02846b8>] (__device_attach+0x44/0x48)
[  755.382635]  r7:00000000 r6:00000000 r5:dc388868 r4:c06c3074
[  755.388256] [<c0284674>] (__device_attach+0x0/0x48) from [<c0283454>] (bus_for_each_drv+0x54/0x90)
[  755.397194]  r5:c0284674 r4:dc388868
[  755.400734] [<c0283400>] (bus_for_each_drv+0x0/0x90) from [<c02843a0>] (device_attach+0x58/0x78)
[  755.409503]  r6:dff17468 r5:dc388868 r4:dc38889c
[  755.414097] [<c0284348>] (device_attach+0x0/0x78) from [<c0283d00>] (bus_probe_device+0x2c/0x48)
[  755.422848]  r5:dc388870 r4:dc388868
[  755.426386] [<c0283cd4>] (bus_probe_device+0x0/0x48) from [<c0281e44>] (device_add+0x32c/0x49c)
[  755.435071] [<c0281b18>] (device_add+0x0/0x49c) from [<c02d1840>] (usb_new_device+0x74/0xd0)
[  755.443499] [<c02d17cc>] (usb_new_device+0x0/0xd0) from [<c02d214c>] (hub_thread+0x8b0/0xde4)
[  755.451961]  r6:00000000 r5:dc388800 r4:dff52600 r3:00000000
[  755.457587] [<c02d189c>] (hub_thread+0x0/0xde4) from [<c00fdd28>] (kthread+0x8c/0x94)
[  755.465405] [<c00fdc9c>] (kthread+0x0/0x94) from [<c00eb22c>] (do_exit+0x0/0x5d4)
[  755.472849]  r6:c00eb22c r5:c00fdc9c r4:dfc37f18
[  755.477425] Rebooting in 5 seconds..
[  760.505304] Restarting Linux verOK



作者: kangear    时间: 2012-11-23 11:40
本帖最后由 kangear 于 2012-11-23 14:53 编辑

最新进展,不是hub的原因我将hub屏蔽掉之后,将USB直接当成一个口引出,U盘能用,摄像头同样这个问题。。。
排除hub的原因了.

这几句很重要:
[  753.751870] kernel BUG at arch/arm/mm/dma-mapping.c:409!
[  753.761250] Unable to handle kernel NULL pointer dereference at virtual address 00000000
[  753.763378] pgd = c0004000
[  753.767827] [00000000] *pgd=00000000
[  753.770921] Internal error: Oops: 817 [#1] PREEMPT
[  753.774341] last sysfs file: /sys/power/state
[  753.778674] Modules linked in:
[  753.781710] CPU: 0    Not tainted  (2.6.35.7 #10)
作者: kangear    时间: 2012-11-23 11:41
但愿不是谁动了DMA驱动......
作者: armeasy    时间: 2012-11-23 13:24
哈哈,顶一下
作者: kangear    时间: 2012-11-23 16:44
转一篇文章来看看:
原文地址:http://blog.micro-studios.com/?p=615#comment-1069
linux中Oops信息的调试及栈回溯—Linux人都知道,这是好东西!

Oops 信息来源及格式

Oops 这个单词含义为“惊讶”
,当内核出错时(比如访问非法地址)打印出来的信息被
称为 Oops 信息。
Oops 信息包含以下几部分内容。
1 一段文本描述信息。
比如类似“Unable to handle kernel NULL pointer dereference at virtual address 00000000”
的信息,它说明了发生的是哪类错误。
2 Oops 信息的序号。
比如是第 1 次、第 2 次等。这些信息与下面类似,中括号内的数据表示序号。
Internal error: Oops: 805 [#1]
3 内核中加载的模块名称,也可能没有,以下面字样开头。
Modules linked in:
4 发生错误的 CPU 的序号,对于单处理器的系统,序号为 0,比如:
CPU: 0
Not tainted (2.6.22.6 #36)
5 发生错误时 CPU 的各个寄存器值。
6 当前进程的名字及进程 ID,比如:
Process swapper (pid: 1, stack limit = 0xc0480258)
这并不是说发生错误的是这个进程,而是表示发生错误时,当前进程是它。错误可能发
生在内核代码、驱动程序,也可能就是这个进程的错误。
7 栈信息。
8 栈回溯信息,可以从中看出函数调用关系,形式如下:
Backtrace:
[<c001a6f4>] (s3c2410fb_probe+0x0/0x560) from [<c01bf4e8>] (platform_drv_
probe+0x20/0x24)
...
9 出错指令附近的指令的机器码,比如(出错指令在小括号里)
:
Code: e24cb004 e24dd010 e59f34e0 e3a07000 (e5873000)

配置内核使 Oops 信息的栈回溯信息更直观
Linux 2.6.22 自身具备的调试功能,可以使得打印出的 Oops 信息更直观。通过 Oops 信
息中 PC 寄存器的值可以知道出错指令的地址,通过栈回溯信息可以知道出错时的函数调用
关系,根据这两点可以很快定位错误。
要让内核出错时能够打印栈回溯信息,编译内核时要增加“-fno-omit-frame-pointer”选
项,这可以通过配置 CONFIG_FRAME_POINTER 来实现。查看内核目录下的配置文件.config,
确保 CONFIG_FRAME_POINTER 已经被定义,如果没有,执行“make menuconfig”命令重
新配置内核。CONFIG_FRAME_POINTER 有可能被其他配置项自动选上。
18.3.3
使用 Oops 信息调试内核的实例
1.获得 Oops 信息
本小节故意修改 LCD 驱动程序 drivers/video/s3c2410fb.c,加入错误代码:在 s3c2410fb_
probe 函数的开头增加下面两条代码:
int *ptest = NULL;
*ptest = 0x1234;
重新编译内核,启动后会出错并打印出如下 Oops 信息:
Unable to handle kernel NULL pointer dereference at virtual address 00000000
pgd = c0004000
[00000000] *pgd=00000000
Internal error: Oops: 805 [#1]
Modules linked in:
CPU: 0
Not tainted (2.6.22.6 #36)
PC is at s3c2410fb_probe+0x18/0x560
LR is at platform_drv_probe+0x20/0x24
pc : [<c001a70c>]
lr : [<c01bf4e8>]
psr: a0000013
sp : c0481e64 ip : c0481ea0 fp : c0481e9c
r10: 00000000 r9 : c0024864 r8 : c03c420c
r7 : 00000000 r6 : c0389a3c r5 : 00000000 r4 : c036256c
r3 : 00001234 r2 : 00000001 r1 : c04c0fc4 r0 : c0362564
Flags: NzCv IRQs on FIQs on Mode SVC_32 Segment kernel
Control: c000717f Table: 30004000 DAC: 00000017
Process swapper (pid: 1, stack limit = 0xc0480258)
Stack: (0xc0481e64 to 0xc0482000)
1e60:c02b1f70 00000020 c03625d4 c036256c c036256c 00000000 c0389a3c
1e80: c0389a3c c03c420c c0024864 00000000 c0481eac c0481ea0 c01bf4e8 c001a704
1ea0: c0481ed0 c0481eb0 c01bd5a8 c01bf4d8 c0362644 c036256c c01bd708 c0389a3c
1ec0: 00000000 c0481ee8 c0481ed4 c01bd788 c01bd4d0 00000000 c0481eec c0481f14
1ee0: c0481eec c01bc5a8 c01bd718 c038dac8 c038dac8 c03625b4 00000000 c0389a3c
1f00: c0389a44 c038d9dc c0481f24 c0481f18 c01bd808 c01bc568 c0481f4c c0481f28
1f20: c01bcd78 c01bd7f8 c0389a3c 00000000 00000000 c0480000 c0023ac8 00000000
1f40: c0481f60 c0481f50 c01bdc84 c01bcd0c 00000000 c0481f70 c0481f64 c01bf5fc
1f60: c01bdc14 c0481f80 c0481f74 c019479c c01bf5a0 c0481ff4 c0481f84 c0008c14
1f80: c0194798 e3c338ff e0222423 00000000 00000001 e2844004 00000000 00000000
1fa0: 00000000 c0481fb0 c002bf24 c0041328 00000000 00000000 c0008b40 c00476ec
1fc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
1fe0: 00000000 00000000 00000000 c0481ff8 c00476ec c0008b50 c03cdf50 c0344178
Backtrace:
[<c001a6f4>] (s3c2410fb_probe+0x0/0x560) from [<c01bf4e8>] (platform_drv_
probe+0x20/0x24)
[<c01bf4c8>] (platform_drv_probe+0x0/0x24) from [<c01bd5a8>] (driver_probe_
device+0xe8/0x18c)
[<c01bd4c0>] (driver_probe_device+0x0/0x18c) from [<c01bd788>] (__driver_
attach+0x80/0xe0)
r8:00000000 r7:c0389a3c r6:c01bd708 r5:c036256c r4:c0362644
[<c01bd708>] (_ _driver_attach+0x0/0xe0) from [<c01bc5a8>] (bus_for_each_
dev+0x50/0x84)
r5:c0481eec r4:00000000
[<c01bc558>] (bus_for_each_dev+0x0/0x84) from [<c01bd808>] (driver_attach+
0x20/0x28)
r7:c038d9dc r6:c0389a44 r5:c0389a3c r4:00000000
[<c01bd7e8>] (driver_attach+0x0/0x28) from [<c01bcd78>] (bus_add_driver+
0x7c/0x1b4)
[<c01bccfc>] (bus_add_driver+0x0/0x1b4) from [<c01bdc84>] (driver_register+
0x80/0x88)
[<c01bdc04>] (driver_register+0x0/0x88) from [<c01bf5fc>] (platform_driver_
register+0x6c/0x88)
r4:00000000
[<c01bf590>] (platform_driver_register+0x0/0x88) from [<c019479c>] (s3c2410fb_
init+0x14/0x1c)
[<c0194788>] (s3c2410fb_init+0x0/0x1c) from [<c0008c14>] (kernel_init+0xd4/
0x28c)
[<c0008b40>] (kernel_init+0x0/0x28c) from [<c00476ec>] (do_exit+0x0/0x760)
Code: e24cb004 e24dd010 e59f34e0 e3a07000 (e5873000)
Kernel panic - not syncing: Attempted to kill init!
分析 Oops 信息
(1)明确出错原因。
由出错信息“Unable to handle kernel NULL pointer dereference at virtual address 00000000”
可知内核是因为非法地址访问出错,使用了空指针。
(2)根据栈回溯信息找出函数调用关系。
内核崩溃时,可以从 pc 寄存器得知崩溃发生时的函数、出错指令。但是很多情况下,错
误有可能是它的调用者引入的,所以找出函数的调用关系也很重要。
部分栈回溯信息如下:
[<c001a6f4>] (s3c2410fb_probe+0x0/0x560) from [<c01bf4e8>] (platform_drv_
probe+0x20/0x24)
这行信息分为两部分,
表示后面的 platform_drv_probe 函数调用了前面的 s3c2410fb_probe
函数。
前半部含义为:
“c001a6f4”是 s3c2410fb_probe 函数首地址偏移 0 的地址,这个函数大
小为 0x560。
后半部含义为:
“c01bf4e8”是 platform_drv_probe 函数首地址偏移 0x20 的地址,这个函
数大小为 0x24。
另外,后半部的“[<c01bf4e8>]”表示 s3c2410fb_probe 执行后的返回地址。
对于类似下面的栈回溯信息,其中是 r8~r4 表示 driver_probe_device 函数刚被调用时这
些寄存器的值。
[<c01bd4c0>] (driver_probe_device+0x0/0x18c) from [<c01bd788>] (__driver_
attach+0x80/0xe0)
r8:00000000 r7:c0389a3c r6:c01bd708 r5:c036256c r4:c0362644
从上面的栈回溯信息可以知道内核出错时的函数调用关系如下,
最后在 s3c2410fb_probe
函数内部崩溃。
do_exit ->
kernel_init ->
s3c2410fb_init ->
platform_driver_register ->
driver_register ->
bus_add_driver ->
driver_attach ->
bus_for_each_dev ->
__driver_attach ->
driver_probe_device ->
platform_drv_probe ->
s3c2410fb_probe
(3)根据 pc 寄存器的值确定出错位置。
上述 Oops 信息中出错时的寄存器值如下:
PC is at s3c2410fb_probe+0x18/0x560
LR is at platform_drv_probe+0x20/0x24
pc : [<c001a70c>]
lr : [<c01bf4e8>]
psr: a0000013
...
“PC is at s3c2410fb_probe+0x18/0x560”表示出错指令为 s3c2410fb_probe 函数中偏移为
0x18 的指令。
“pc : [<c001a70c>]”表示出错指令的地址为 c001a70c(十六进制)。
(4)结合内核源代码和反汇编代码定位问题。
先生成内核的反汇编代码 vmlinux.dis,执行以下命令:
$ cd /work/system/linux-2.6.22.6
$ arm-linux-objdump -D vmlinux > vmlinux.dis
出错地址 c001a70c 附近的部分汇编代码如下:
c001a6f4 <s3c2410fb_probe>:
c001a6f4: e1a0c00d mov ip, sp
c001a6f8: e92ddff0 stmdb
c001a6fc: e24cb004 sub fp, ip, #4 ; 0x4
c001a700: e24dd010 sub sp, sp, #16 ; 0x10
c001a704: e59f34e0 ldr r3, [pc, #1248] ; c001abec <.init+0x1284c>
c001a708: e3a07000 mov r7, #0
c001a70c: e5873000 str r3, [r7]
c001a710: e59030fc ldr r3, [r0, #252]
sp!, {r4, r5, r6, r7, r8, r9, sl, fp, ip, lr, pc}
; 0x0
<===========出错指令
出错指令为“str r3, [r7]”
,它把 r3 寄存器的值放到内存中,内存地址为 r7 寄存器的值。
根据 Oops 信息中的寄存器值可知:r3 为 0x00001234,r7 为 0。0 地址不可访问,所以出错。
s3c2410fb_probe 函数的部分 C 代码如下:
static int __init s3c2410fb_probe(struct platform_device *pdev)
{
struct s3c2410fb_info *info;
struct fb_info
*fbinfo;
struct s3c2410fb_hw *mregs;
int ret;
int irq;
int i;
u32 lcdcon1;
int *ptest = NULL;
*ptest = 0x1234;
mach_info = pdev->dev.platform_data;
结合反汇编代码,很容易知道是“*ptest = 0x1234;”导致错误,其中的 ptest 为空。
对于大多数情况,从反汇编代码定位到 C 代码并不会如此容易,这需要较强的阅读汇编
程序的能力。通过栈回溯信息知道函数的调用关系,这已经可以帮助定位很多问题了。




作者: kangear    时间: 2012-11-23 16:45
使用 Oops 的栈信息手工进行栈回溯
前面说过,从 Oops 信息的 pc 寄存器值可知得知崩溃发生时的函数、出错指令。但是错
误有可能是它的调用者引入的,所以还要找出函数的调用关系。
由于内核配置了 CONFIG_FRAME_POINTER,当出现 Oops 信息时,会打印栈回溯信息。如
果内核没有配置 CONFIG_FRAME_POINTER,这时可以自己分析栈信息,找到函数的调用关系。
1.栈的作用
一个程序包含代码段、数据段、BSS 段、堆、栈;其中数据段用来中存储初始值不为 0
的全局数据,BSS 段用来存储初始值为 0 的全局数据,堆用于动态内存分配,栈用于实现函
数调用、存储局部变量。
被调用函数在执行之前,它会将一些寄存器的值保存在栈中,其中包括返回地址寄存器
lr。如果知道了所保存的 lr 寄存的值,那么就可以知道它的调用者是谁。在栈信息中,一个
函数一个函数地往上找出所有保存的 lr 值,
就可以知道各个调用函数,
这就是栈回溯的原理。
2.栈回溯实例分析
仍以前面的 LCD 驱动程序为例,
使用上面的 Oops 信息的栈信息进行分析,
栈信息如下:
Stack: (0xc0481e64 to 0xc0482000)
1e60:c02b1f70 00000020 c03625d4 c036256c c036256c 00000000 c0389a3c
1e80: c0389a3c c03c420c c0024864 00000000 c0481eac c0481ea0 c01bf4e8 c001a704
1ea0: c0481ed0 c0481eb0 c01bd5a8 c01bf4d8 c0362644 c036256c c01bd708 c0389a3c
1ec0: 00000000 c0481ee8 c0481ed4 c01bd788 c01bd4d0 00000000 c0481eec c0481f14
1ee0: c0481eec c01bc5a8 c01bd718 c038dac8 c038dac8 c03625b4 00000000 c0389a3c
...
1 根据 pc 寄存器值找到第一个函数,确定它的栈大小,确定调用函数。
从 Oops 信息可知 pc 值为 c001a70c,
使用它在内核反汇编程序 vmlinux.dis 中可以知道它
位于 s3c2410fb_probe 函数内。
根据这个函数开始部分的汇编代码可以知道栈的大小、lr 返回值在栈中保存的位置,代
码如下:
c001a6f4 <s3c2410fb_probe>:
c001a6f4:
e1a0c00d
mov ip, sp
c001a6f8: e92ddff0 stmdb
c001a6fc: e24cb004 sub fp, ip, #4 ; 0x4
sp!, {r4, r5, r6, r7, r8, r9, sl, fp, ip, lr, pc}
c001a700: e24dd010 sub sp, sp, #16 ; 0x10
e5873000 str r3, [r7]
...
c001a70c:
// pc 值 c001a70c 对应的指令
...
{r4, r5, r6, r7, r8, r9, sl, fp, ip, lr, pc}这 11 个寄存器都保存在栈中,指令“sub sp, sp, #16”
又使得栈向下扩展了 16 字节,所以本函数的栈大小为(11 × 4+16)字节,即 15 个双字。
栈信息开始部分的 15 个数据就是本函数的栈内容,下面列出了它们所保存的寄存器。
1e60:
c02b1f70 00000020 c03625d4 c036256c c036256c 00000000 c0389a3c
r4
r5
r6
1e80: c0389a3c c03c420c c0024864 00000000 c0481eac c0481ea0 c01bf4e8 c001a704
r7
r8
r9
sl
fp
ip
lr
pc
其中 lr 值为 c01bf4e8,表示函数 s3c2410fb_probe 执行完后的返回地址,它是调用函数
中的地址。下面使用 lr 值再次重复本步骤的回溯过程。
2 根据 lr 寄存器值找到调用函数,确定它的栈大小,确定上一级调用函数。
根据上步得到的 lr 值(c01bf4e8)在内核反汇编程序 vmlinux.dis 中可以知道它位于
platform_drv_probe 函数内。
根据这个函数开始部分的反汇编代码可以知道栈的大小、lr 返回值在栈中保存的位置。
代码如下:
c01bf4c8 <platform_drv_probe>:
c01bf4c8: e1a0c00d mov ip, sp
c01bf4cc: e92dd800 stmdb sp!, {fp, ip, lr, pc}
e89da800 ldmia sp, {fp, sp, pc}
...
c01bf4e8:
// lr 值(c01bf4e8)对应的指令
{fp, ip, lr, pc}这 4 寄存器都保存在栈中,本函数的栈大小为 4 个双字。Oops 栈信息中,
前一个函数 s3c2410fb_probe 的栈下面的 4 个数据就是函数 platform_drv_probe 的栈内容,如
下所示:
1ea0: c0481ed0 c0481eb0 c01bd5a8 c01bf4d8
fp
ip
lr
pc
其中 lr 值为 c01bd5a8,表示函数 platform_drv_probe 执行完后的返回地址,它是上一级
调用函数中的地址。使用 lr 值,重复本步骤的查找过程,直到栈信息分析完毕或者再也无法
分析,这样就可以找出所有的函数调用关系。
有些函数很简单,没有使用栈(sp 值在这个函数中没有变化)
,或者没有在栈中保存 lr
值。这些情况需要读者灵活处理,较强的汇编程序阅读能力是关键。
作者: foting    时间: 2012-11-24 23:55
楼上厉害!
作者: yzttt    时间: 2014-11-27 15:32

楼上厉害!
作者: tylorvan    时间: 2015-1-6 11:45
太厉害了 只能说崇拜




欢迎光临 九鼎创展论坛 (http://bbs.9tripod.com/) Powered by Discuz! X3.2