互联网服务powerLinuxLinux

理解powerlinux的kernel oops 之二 理解oops信息

现在让我们深入了解一下oops信息的意义。
Unable to handle kernel paging request for data at address 0x00000000
Faulting instruction address: 0xd000000002d30060
Oops: Kernel access of bad area, sig: 11 [#1]
SMP NR_CPUS=1024 NUMA pSeries
Modules linked in: oops(PN+) nfsd nfs fscache lockd auth_rpcgss nfs_acl sunrpc a
f_packet fuse loop dm_service_time dm_multipath dm_mod ipv6 ipv6_lib nx_crypto(X
) be2net sg ses enclosure ext3 jbd mbcache btrfs lzo_compress zlib_deflate crc32
c libcrc32c sd_mod crc_t10dif scsi_dh_rdac scsi_dh_emc scsi_dh_alua scsi_dh_hp_s
w scsi_dh lpfc scsi_transport_fc scsi_tgt ipr(X) libata scsi_mod
Supported: No, Proprietary and Unsupported modules are loaded
NIP: d000000002d30060 LR: d000000002d30050 CTR: 0000000000000001
REGS: c0000002f1963a50 TRAP: 0300   Tainted: P           NX  (3.0.76-0.11-ppc64)
MSR: 8000000002009032   CR: 24002224  XER: 00000020
DAR: 0000000000000000, DSISR: 42000000
TASK = c0000002e57290f0[18970] 'modprobe' THREAD: c0000002f1960000 CPU: 12
GPR00: d000000002d30050 c0000002f1963cd0 d000000002d38158 0000000000000000
GPR04: 0000000000000000 ffffffffffffffff 000000000007ffff c00000000116cd40
GPR08: 000000000007ffff 0000000000000000 0000000000000000 0000000000000001
GPR12: 0000000028002222 c000000003f42400 0000000000000000 0000000000000000
GPR16: 0000000010033250 00000000100400b0 0000000010033250 0000000000000003
GPR20: 0000000010040480 0000000000100000 0000000000000000 0000000010040388
GPR24: 0000000000000000 d000000002d30190 c000000001040080 c0000002f1960000
GPR28: c000000000e7dfc0 0000000000001214 d000000002d38168 d000000002d301a8
NIP [d000000002d30060] .my_oops_init+0x2c/0xd4 [oops]
LR [d000000002d30050] .my_oops_init+0x1c/0xd4 [oops]
Call Trace:
[c0000002f1963cd0] [c00000000000ab68] .do_one_initcall+0x68/0x1e0 (unreliable)
[c0000002f1963d90] [c0000000001056ec] .SyS_init_module+0xcc/0x218
[c0000002f1963e30] [c0000000000098ec] syscall_exit+0x0/0x40
Instruction dump:
4e800020 fbc1fff0 ebc28000 7c0802a6 f8010010 f821ff81 e87e8008 4800002d
e8410028 38210080 39200000 38600000
91290000> e8010010 ebc1fff0 7c0803a6
Sending IPI to other cpus...
Unable to handle kernel paging request for data at address 0x00000000
Faulting instruction address: 0xd000000002d30060

指出错误是NULL地址取值。出错的指令地址是0xd000000002d30060。
Oops: Kernel access of bad area, sig: 11 [#1]

11就是SIGSEGV,段错误。有关信号的定义在arch/powerpc/include/uapi/asm/signal.h里。#1是说这是第一个oops。这里一共只有一个oops,但某些情况可能会有多个连续的oops。
SMP NR_CPUS=1024 NUMA pSeries

系统是多CPU的,最大支持1024个CPU,支持NUMA,power系统。
Modules linked in: oops(PN+) nfsd nfs ...

列出当前已经加载的模块。模块后的括号中字母的意思是

    P 不开源的模块

    N 不被SUSE支持

    X 第三方模块,但SUSE支持

    + 正在加载的模块

    - 正在卸载的模块
NIP: d000000002d30060 LR: d000000002d30050 CTR: 0000000000000001

这里列出了3个寄存器的值。NIP是next instruction pointer,值就是当前指令的地址。LR是link register其值为上一条指令的地址。CTR是count register,其值用于循环指令。
REGS: c0000002f1963a50 TRAP: 0300   Tainted: P           NX  (3.0.76-0.11-ppc64)
MSR: 8000000002009032   CR: 24002224  XER: 00000020
DAR: 0000000000000000, DSISR: 42000000

REGS是保存寄存器信息的pt_regs结构体的地址;TRAP是触发oops的原因,0×300是“Data Access”,0×400是“Instruction Access”,相关信息可从arch/powerpc/xmon/xmon.c中得到。MSR是machine state register,它又分成几个部分,表示机器的一些当前状态。而所有enable的状态都在“<>”中列了出来,如EE为外部中断打开了;ME为机器检查打开了等等。可从arch/powerpc/include/asm/reg.h中得到全部信息,注意都加了一个“MSR_”,如MSR_MM。CR是condition register,它也被分为几个部分,分别表示条件判断的结果,如“等于”或“大于”等。XER为fixed-point exception register。DAR为data address register,其值为造成了内存访问异常的地址,此处正好是0。DSISR是存储着发生内存访问异常原因的寄存器,0×40000000表示“no translation found”,0×02000000表示“access was a store”。详见arch/powerpc/include/asm/reg.h。
TASK = c0000002e57290f0[18970] 'modprobe' THREAD: c0000002f1960000 CPU: 12

这一行给出的是当前进程的task_struct结构体的地址(c0000002e57290f0)及进程号(18970)、程序名(modprobe),进程的内核栈起始地址(THREAD: c0000002f1960000)和当前CPU(12)。

之后是8行共32个通用寄存器的值。由于power的寄存器较多,因此函数调用的参数是直接用寄存器传递的。r3到r11用来传参。

接下来是指令的backtrace。出问题的地方是
NIP [d000000002d30060] .my_oops_init+0x2c/0xd4 [oops]

是.my_oops_init这个函数的从头位移0x2c处的指令出的问题,这个地址也就是NIP的值d000000002d30060,“0xd4”是.my_oops_init这个函数的长度。
Call Trace:
[c0000002f1963cd0] [c00000000000ab68] .do_one_initcall+0x68/0x1e0 (unreliable)

开头的[c0000002f1963cd0]是进程内核栈中的地址,后一个[]中的c00000000000ab68是所调用的.do_one_initcall中的地址。

第三部分准备利用kdump得到的vmcore来分析产生oops的原因,与原文使用的gdb分析的方法作一个比较。
参与0

0同行回答

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

提问者

cstl_hpt
其它IBM

相关问题

相关资料

相关文章

问题状态

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