关键词:mdb/kmdb/panic/hung/crashdump/dump/kernel debug/Solaris/OpenSolaris
事后分析(Postmortem Debug)是目前主流的商业操作系统支持的特性之一,windows, Aix, Freebsd都支持CrashDump及事后分析,最近Linux也逐渐加入了Crashdump和分析工具的支持。了解内核开发的人都知道,很多内核的bug都是很难重现,或者说,是在某个特定条件下,在一个微小的时间窗口内才可以重现;另外,在重要的商业客户的生产环境中,不大可能提供给内核程序员调试这类crash或者hung的机会,因此,在客户提供crash dump文件基础上,进行事后分析就成了解决此类问题的唯一途径。
内核开发,测试甚至使用中可能会遇到以下两类极端情况:
系统crash - 例如,Windows的蓝屏,Unix的panic,Linux的opps;
系统hung - 例如,大家通常说的死机;
1. 系统Crash的分类
System panics & bad traps
Watchdog resets
Dropping out (to boot PROM or bootstrap level)
关于Panic
1. 为保证数据完整性,避免系统进入不可预知的错误,系统会panic()
2. panic()只会在内核空间调用,用户程序触发panic是可能的,但是只是触发而已。
3.系统也会因为检测到硬件不应该进入某种状态而panic(),叫bad trap.
panic()的主要工作
1.dump内存到device(缺省是swap区).
2.dump CPU的所有寄存器到device.
3.重新启动.
panic的过程包括
1. 打印实际panic的消息
2. 打印调用栈的backtrace
3. 内存Dump的消息
4. 尝试Reboot
2. 关于hung
系统hung的分类
1. 死锁(deadlock)问题
2. 系统资源耗尽
3. 硬件问题
发生hung怎么办?
1. 确认hung的现象,网络服务/ping/console/是否可用?
2. 尝试产生一个Crash Dump
如何产生Crash Dump?
1. SPARC系统下,尝试激活OBP用sync命令产生crash dump;
2. x86系统如果启动时加载了kmdb,可以激活kmdb产生crash dump;
x86上如何设置启动时加载kmdb?
有两种方法:
1. 修改grub的设置,加上 "-k", 然后reboot
# vi /boot/grub/menu.lst
#---------- ADDED BY BOOTADM - DO NOT EDIT ----------
title Solaris 10 11/06 X86
root (hd0,0,a)
kernel /platform/i86pc/multiboot -k
module /platform/i86pc/boot_archive
#---------------------END BOOTADM--------------------
2.或者在启动后,退到console模式,运行如下命令:
# mdb -K
Welcome to kmdb
kmdb: unable to determine terminal type: assuming `vt100'
Loaded modules: [ crypto uppc ufs unix zfs krtld s1394 sppp nca uhci lofs
genunix ip usba specfs pcplusmp nfs random sctp cpu.AuthenticAMD.15 ]
[2]> :c
进入kmdb后,内核陷入断点,要用:c来恢复系统运行。
x86下如何激活kmdb并产生crash dump?
kmdb如果已经加载,可以用SHIFT+F1+a通过键盘来激活;
如果console重定向到SP或者tip line,需要查一下发送break信号的字符序列;
# kmdb: target stopped at:
kaif_enter+7: popfl
[3]>
出现提示符后,可以用$<systemdump命令产生crash dump:
[3]> $<systemdump
nopanicdebug: 0 = 0x1
panic[cpu3]/thread=c29b9de0: BAD TRAP: type=e (#pf Page fault) rp=c29d9f1c addr=0 occurred in module "<unknown>" due to a
NULL pointer dereference
sched: #pf Page fault
Bad kernel fault at addr=0x0
pid=0, pc=0x0, sp=0x202, eflags=0x10002
cr0: 8005003b<pg,wp,ne,et,ts,mp,pe> cr4: 6f8<xmme,fxsr,pge,mce,pae,pse,de>
cr2: 0 cr3: 1238c000
gs: 1b0 fs: 0 es: 160 ds: 160
edi: c22e0c80 esi: 20 ebp: c29d9f6c esp: c29d9f54
ebx: f9 edx: 0 ecx: c22e0c11 eax: fec8b7b0
trp: e err: 10 eip: 0 cs: 158
efl: 10002 usp: 202 ss: c29d9f74
c29d9e7c unix:die+a7 (e, c29d9f1c, 0, 3)
c29d9f08 unix:trap+1058 (c29d9f1c, 0, 3)
c29d9f1c unix:cmntrap+9a (1b0, 0, 160, 160, c)
c29d9f6c 0 (c29d9f7c, fe813ced,)
c29d9f74 genunix:kdi_dvec_enter+a (c29d9f88, fe813c8f,)
c29d9f7c unix:debug_enter+32 (0)
c29d9f88 unix:abort_sequence_enter+27 (0)
c29d9fb0 asy:async_rxint+1eb (c19c3d00, f9)
c29d9fd4 asy:asyintr+97 (c19c3d00, 0)
c29b9d5c unix:cmnint+1f7 (c29b01b0, c1600000,)
c29b9db8 unix:cpu_halt+f6 (0, 0, c29b9dd8, fe8)
c29b9dc8 unix:idle+dc (0, 0)
c29b9dd8 unix:thread_start+8 ()
syncing file systems... done
dumping to /dev/dsk/c0t0d0s1, offset 860356608, content: kernel
100% done: 182452 pages dumped, compression ratio 6.00, dump succeeded
rebooting...
3. 关于savecore
savecore - 启动时将panic()例程存在dump device(swap区)上的image保存成文件,存在指定的文件系统的目录上。
用dumpadm(1M)可以查看dump device和crash dump的保存路径;
在/var/crash/<hostname>下,可以看到以下几类文件:
unix.X 和 vmunix.X - crash dump文件,其中X是数字,是dump文件的序号
bounds - 用来记录序号,确定下一次dump的序号
