日期:2014-05-16  浏览次数:20985 次

linux中Oops信息的调试及栈回溯

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+0×0/0×560) from [<c01bf4e8>] (platform_drv_
probe+0×20/0×24)

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 = 0×1234;
重新编译内核,启动后会出错并打印出如下 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+0×18/0×560
LR is at platform_drv_probe+0×20/0×24
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+0×0/0×560) from [<c01bf4e8>] (platform_drv_
probe+0×20/0×24)
[<c01bf4c8>] (platform_drv_probe+0×0/0×24) from [<c01bd5a8>] (driver_probe_
device+0xe8/0x18c)
[<c01bd4c0>] (driver_probe_device+0×0/0x18c) from [<c01bd788>] (__driver_
attach+0×80/0xe0)
r8:00000000 r7:c0389a3c r6:c01bd708 r5:c036256c r4:c0362644
[<c01bd708>] (_ _driver_attach+0×0/0xe0) from [<c