互联网服务powerLinuxLinux

理解powerlinux的kernel oops 之三 用gdb查找oops原因

接下来研究一下如何找出oops的原因。x86版原文使用了gdb,非常漂亮地找出了原因所在。但是存在一个问题:这个方法需要用“add-symbols-file”命令把“symbol file”加载到gdb中。add-symbol-file的第二个参数是oops.ko的text section的地址,而这个地址呢,原文说需要从
/sys/module/oops/sections/.init.text中得来。可是,一加载oops.ko,系统就oops了,无法能过查看其.init.text文件来得到地址。我想不出原文是如何做到的。后来通过尝试,发现可以用crash和kdump捕捉到的vmcore来找出这个地址,我们将在第4部分研究如何用crash找出oops的原因,这里只是简单地给出这个地址:0xd000000002d301a8。

好了,有了oops的text section的地址后,让我们来使用gdb找出oops的原因。
kitlp1:/home/hpt/oops # gdb oops.ko
GNU gdb (GDB) SUSE (7.5.1-0.7.29)
Copyright (C) 2012 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "ppc64-suse-linux".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /home/hpt/oops/oops.ko...done.
(gdb) add-symbol-file oops.o 0xd000000002d301a8
add symbol table from file "oops.o" at
        .text_addr = 0xd000000002d301a8
(y or n) y
Reading symbols from /home/hpt/oops/oops.o...done.
(gdb)

加载完毕。回想oops信息中
NIP [d000000002d30060] .my_oops_init+0x2c/0xd4 [oops]

可知问题出在.my_oops_init中从开头算起的位移0x2c处。让我们在gdb中对my_oops_init作反汇编:
(gdb) disassemble my_oops_init
Dump of assembler code for function my_oops_init:
   0x0000000000000034 <+0>:     std     r30,-16(r1)
   0x0000000000000038 <+4>:     ld      r30,0(r2)
   0x000000000000003c <+8>:     mflr    r0
   0x0000000000000040 <+12>:    std     r0,16(r1)
   0x0000000000000044 <+16>:    stdu    r1,-128(r1)
   0x0000000000000048 <+20>:    ld      r3,-32760(r30)
   0x000000000000004c <+24>:    bl      0x4c
   0x0000000000000050 <+28>:    nop
   0x0000000000000054 <+32>:    addi    r1,r1,128
   0x0000000000000058 <+36>:    li      r9,0
   0x000000000000005c <+40>:    li      r3,0
   0x0000000000000060 <+44>:    stw     r9,0(r9)
   0x0000000000000064 <+48>:    ld      r0,16(r1)
   0x0000000000000068 <+52>:    ld      r30,-16(r1)
   0x000000000000006c <+56>:    mtlr    r0
   0x0000000000000070 <+60>:    blr
End of assembler dump.
(gdb)

可知,my_oops_init开头地址是0×34,于是出问题的地址是0×34+0x2c=0×60:
(gdb) list *0x60
0x60 is in my_oops_init (/home/hpt/oops/oops.c:6).
1       #include
2       #include
3       #include
4
5       static void create_oops() {
6               *(int *)0 = 0;
7       }
8
9       static int __init my_oops_init(void) {
10              printk("oops from the modulen");
(gdb)

gdb非常精确地指出了问题所在的行。

以上方法非常漂亮。但是由于有一开头说的问题,我们还是要借助crash和kdump得到的vmcore。在第四部分将对此说明。
参与0

0同行回答

“答”则兼济天下,请您为题主分忧!

提问者

cstl_hpt
其它IBM

相关问题

相关资料

相关文章

问题状态

  • 发布时间:2013-07-15
  • 关注会员:0 人
  • 问题浏览:1444
  • X社区推广