分类: LINUX
2010-08-22 14:16:40
2.4的panic/oops和2.6相比,少了很多信息。不易立马定位出错误发生的位置。
如何定位错误对分析解决问题十分重要,下面这个例子讲如何在2.4内核中定位panic/oops的位置:
-----------------------------------------------------------------------------------------------------------------------
Dec 20 02:40:58 AS-4 kernel: Unable to handle kernel NULL pointer dereference at virtual address 0000000c
Dec 20 02:40:58 AS-4 kernel: printing eip:
Dec 20 02:40:58 AS-4 kernel: f890c2c0 ###my comments: (in user_hold)
Dec 20 02:40:58 AS-4 kernel: *pde = 00000000
Dec 20 02:40:58 AS-4 kernel: Oops: 0002
Dec 20 02:40:58 AS-4 kernel: CPU: 3
Dec 20 02:40:58 AS-4 kernel: EIP: 0010:[
Dec 20 02:40:58 AS-4 kernel: EFLAGS: 00010282
Dec 20 02:40:58 AS-4 kernel: eax: 00000000 ebx: ef27a5e8 ecx: 00000000 edx: c3036000
Dec 20 02:40:58 AS-4 kernel: esi: f5f31054 edi: f6109800 ebp: f5f31054 esp: c3037de4
Dec 20 02:40:58 AS-4 kernel: ds: 0018 es: 0018 ss: 0018
Dec 20 02:40:58 AS-4 kernel: Process swapper (pid: 0, stackpage=c3037000)
Dec 20 02:40:58 AS-4 kernel: Stack: f89269f2 f6109800 00000000 f5f31054 f5f31054 f6109800 f8926525 f6109800
Dec 20 02:40:58 AS-4 kernel: ef27a5e8 f5f31054 f5f31054 00000001 f8925c42 f5f31054 f6109800 f8925b42
Dec 20 02:40:58 AS-4 kernel: f5f31054 00000001 ef27a5e8 f89263ea f5f31054 f5f31054 f5f31054 f6f2c03c
Dec 20 02:40:58 AS-4 kernel: Call Trace: [
Dec 20 02:40:58 AS-4 kernel: [
Dec 20 02:40:58 AS-4 kernel: [
Dec 20 02:40:58 AS-4 kernel: [
Dec 20 02:40:58 AS-4 kernel:
Dec 20 02:40:58 AS-4 kernel: Code: f0 ff 40 0c c3 8d 76 00 53 8b 54 24 0c f0 ff 4a 0c 0f 94 c0
Dec 20 02:40:58 AS-4 kernel: <0>Kernel panic: Aiee, killing interrupt handler!
-----------------------------------------------------------------------------------------------------------------------
找到原模块文件,比如hello.o
insmod -m hello.o > ~/kernel-module.symbol
在输出的文件中我们可以知道hello.o被插入到kernel时的符号表地址。
根据eip我们就可以知道kernel oops发生的大体位置,即是在哪一个函数中出现错误的。
然后根据eip的地址去反汇编代码中寻找错误发生函数的具体位置,这里就是f890c2c0。
Eip减去kernel-module.symbol中的函数起始地址,得到错误发生的偏移量。根据这个偏移量,我们就可以在objdump得到的反汇编代码中查到函数出错时的具体位置。
注:objdump -D *.o得到反汇编代码。 objdump -S *.o得到含有c源码的汇编,这要求之前的编译包含了debug信息(-g)。
如果还不能精确定位函数错误的具体位置。还有一种方法:从panic/oops的信息中我们看到有Dec 20 02:40:58 AS-4 kernel: Code: f0 ff 40 0c c3 8d 76 00 53 8b 54 24 0c f0 ff 4a 0c 0f 94 c0
这是出错地方对应的二进制代码。它们可以帮助我们定位到错误发生处的汇编语言。
Kernel oops后内核是否需要重启,取决于我们的参数配置。
# sysctl -a|grep oops
kernel.panic_on_oops = 1
panic_on_oops的缺省设置是"0",即在Oops发生时不会进行panic()操作,即oops时不panic,系统仍然继续运行。