crash工具不生成vmlinux,仅消费它;vmlinux必须与vmcore完全匹配,来自同一内核RPM包,否则因符号不一致导致“cannot find symbol”或segfault。

crash 工具本身不产生 vmlinux,它只消费 vmlinux —— 你看到的“调试快照”其实是 vmcore(内存镜像),而 vmlinux 是带符号的内核可执行文件,必须手动匹配、提供给 crash 才能解析。
为什么 crash 启动时报 “cannot find symbol” 或直接 segfault
这是最常见也最致命的问题:你手头的 vmlinux 和崩溃时运行的内核版本、构建配置、甚至编译器版本不一致。符号表错一位,整个调用栈就全乱。
-
vmlinux必须来自与vmcore完全相同的内核 RPM 包,不能靠uname -r猜 —— 比如3.10.0-1160.114.2.el7.x86_64和3.10.0-1160.114.2.el7.x86_64.rpm的子版本号差一个补丁,vmlinux就不可用 - CentOS/RHEL 上,
vmlinux不在/boot下,而是在/usr/lib/debug/lib/modules/$(uname -r)/vmlinux,前提是已安装kernel-debuginfo包 - Debian/Ubuntu 上路径是
/usr/lib/debug/boot/vmlinux-$(uname -r),依赖linux-image-$(uname -r)-dbgsym包 - 检查是否真有符号:运行
file /usr/lib/debug/lib/modules/$(uname -r)/vmlinux,输出里必须含with debug_info;若显示stripped,说明符号已被剥离,不能用于crash
怎么确认 vmcore + vmlinux 组合能真正 work
别急着进交互模式,先做最小验证。用 crash -s 启动后立刻执行 sys 和 ps,看是否返回合理结果,而不是报错或卡死。
- 成功表现:
sys显示内核版本、CPU 数、物理内存大小;ps列出几十个进程,状态列(STATE)有R、S、D等真实状态码 - 典型失败信号:
ps返回空或全是???;bt报invalid address;kmem -i输出全是 0 或负数 - 快速验证命令:
crash /usr/lib/debug/lib/modules/$(uname -r)/vmlinux /var/crash/$(ls -t /var/crash | head -n1)/vmcore -s -i /dev/stdin ,一行跑完,有输出即初步可用
分析时哪些命令最容易暴露 vmlinux 不匹配
不是所有命令都对符号敏感,但这几个一试就露馅:
-
bt(backtrace):如果某函数名显示为0xffffffff81abcdef或unknown,说明符号解析失败;正常应看到类似do_page_fault、tcp_v4_do_rcv这样的函数名 -
log:读取内核 ring buffer,若输出为空或大量???,大概率vmlinux缺失log_buf符号或地址偏移错位 -
struct task_struct <pid></pid>:尝试打印具体进程结构体,若字段值全为 0 或地址非法,说明结构体布局和vmlinux描述不一致 -
mod -l:列出模块时若显示unknown module或模块地址乱跳,说明module_core等关键符号位置错误
真正难的从来不是“怎么用 crash”,而是确保 vmlinux 和 vmcore 来自同一构建产物——这个匹配关系一旦出错,后续所有分析都是在错误数据上建空中楼阁。现场没保存好可以重来,但拿错符号分析三天,不如花十分钟验证路径和版本。


















