内核panic后用crash解析vmcore需四步:先确认vmcore与带符号vmlinux匹配;再用bt -a和log定位触发点;接着用rd/dis查寄存器与反汇编聚焦崩溃现场;最后结合ps/lock/log分析进程、锁及RCU上下文。

内核 panic 发生后,若已配置 kdump 并成功捕获 vmcore(通常位于 /var/crash/ 下),就可以用 crash 工具解析它,快速定位崩溃时的调用栈、触发函数和上下文。关键不是“能不能看”,而是“看哪几处最有效”。
确认 vmcore 和 vmlinux 匹配
vmcore 本身不带符号信息,必须搭配对应版本、带调试符号的 vmlinux(不是 /boot/vmlinuz-xxx)才能解析函数名和行号。常见错误是用错内核版本或缺少 debuginfo 包。
- 检查 vmcore 对应的内核版本:
file /var/crash/*/vmcore | grep "Linux version" - 查找匹配的
vmlinux:CentOS/RHEL 用debuginfo-install kernel-$(uname -r);Ubuntu/Debian 安装linux-image-$(uname -r)-dbgsym包,vmlinux 通常在/usr/lib/debug/boot/vmlinux-$(uname -r) - 验证是否可用:
crash /usr/lib/debug/boot/vmlinux-$(uname -r) /var/crash/*/vmcore—— 若无报错且进入交互界面,说明匹配成功
快速定位 panic 触发点:bt -a 和 log
bt -a(backtrace all)列出所有 CPU 的完整调用栈,panic 通常发生在其中一个 CPU 上,重点看标记为 CRASH 或处于 die/oops_enter 调用链中的线程。
- 执行
bt -a,扫描各 CPU 栈底(最顶层)是否出现panic、do_exit、__warn、die等函数 - 运行
log查看内核日志缓冲区内容,常含 panic 前最后一句提示,例如"Kernel panic - not syncing: Fatal exception"或具体原因如"Unable to handle kernel NULL pointer dereference" - 若看到
BUG: unable to handle kernel paging request,结合bt中出问题的栈帧,再用dis -l反汇编对应代码行
聚焦崩溃现场:查看寄存器与内存状态
调用栈只能告诉你“谁调了谁”,但真正原因常藏在寄存器值或非法内存访问地址里。
- 在
bt输出中找到疑似出问题的栈帧(比如包含驱动名、模块名或__do_fault、memcpy等敏感函数),记下其地址(如#5 [)] - 执行
rd -s $pc 10或dis -l ffffffff8123abcd查看该指令附近源码行(需 vmlinux 符号完整) - 若 panic 提示访问了非法地址(如
IP:),用sym查该地址是否属于某个模块,再用mod -s检查模块加载状态和符号表
辅助判断:检查进程上下文与锁状态
很多 panic 源于中断上下文误睡、死锁或 RCU stall,需结合上下文交叉验证。
- 用
ps -m查看所有进程状态,关注标记为 UN(uninterruptible)或 RU(running in kernel)的进程,尤其是持有锁或刚唤醒的 - 运行
lock查当前持有的自旋锁或 mutex,配合bt看是否多个 CPU 卡在同一锁上 - 若怀疑 RCU 问题,执行
rd -f cpu#0 __rcu_pending或查看log中是否有"INFO: rcu_preempt detected stalls"
解析 vmcore 不依赖复杂工具链,核心是找准入口(bt -a + log)、对齐符号(vmlinux)、验证地址(sym/rd/dis),再结合上下文缩小范围。多数硬件驱动、内存越界、锁误用类 panic,靠这四步就能锁定 root cause。








