linux crash工具详解
crash
是 Linux 系统中用于分析内核转储文件(如 vmcore
或 kdump
生成的 dump
文件)的核心工具。它结合了调试符号和内核数据结构,能够直观地查看崩溃时的系统状态。以下是其详细使用方法及核心功能解析:
一、安装与准备
1. 安装 crash
-
Debian/Ubuntu:
sudo apt install crash
-
CentOS/RHEL/OpenEuler:
sudo yum install crash
2. 安装调试符号
必须安装与内核版本完全匹配的调试符号包,否则无法解析内核数据结构:
-
Debian/Ubuntu:
sudo apt install linux-image-$(uname -r)-dbg
-
CentOS/RHEL:
sudo yum install kernel-debuginfo-$(uname -r)
3. 验证文件
确保以下文件存在:
-
vmlinux:内核的未压缩符号文件(通常位于
/usr/lib/debug/lib/modules/$(uname -r)/vmlinux
)。 -
vmcore:内核转储文件(默认在
/var/crash
目录下)。
二、启动 crash
基本语法
crash [vmlinux] [vmcore] [options]
示例:
crash /usr/lib/debug/lib/modules/5.4.0-80-generic/vmlinux /var/crash/20231010/vmcore
常用选项
选项 | 说明 |
---|---|
-s | 启动后直接进入交互式命令行(默认行为) |
-d | 显示调试信息(用于排查工具自身问题) |
-i [script] | 启动时自动执行预定义的脚本文件 |
三、核心功能与命令
1. 基本状态查看
命令 | 说明 |
---|---|
help | 查看所有支持的命令及简要说明 |
sys | 显示系统基本信息(内存、CPU、内核版本等) |
kmem -i | 查看内存使用统计(类似 free 命令的输出) |
mod | 列出已加载的内核模块 |
示例:
crash> sysKERNEL: /usr/lib/debug/lib/modules/5.4.0-80-generic/vmlinuxDUMPFILE: /var/crash/20231010/vmcoreCPUS: 4DATE: Thu Oct 10 15:30:00 2023UPTIME: 02:15:00
LOAD AVERAGE: 0.12, 0.08, 0.06TASKS: 512NODENAME: server01RELEASE: 5.4.0-80-genericVERSION: #91-Ubuntu SMP Thu Jul 15 19:09:17 UTC 2021MACHINE: x86_64 (2194 Mhz)MEMORY: 8 GB
2. 崩溃上下文分析
命令 | 说明 |
---|---|
bt | 显示崩溃时的调用栈(Backtrace) |
bt -a | 显示所有 CPU 的调用栈 |
ps | 列出崩溃时的所有进程状态 |
log | 查看内核日志(dmesg 的崩溃前内容) |
irq | 查看中断状态 |
示例:
crash> bt
PID: 0 TASK: ffff88807c0a0000 CPU: 0 COMMAND: "swapper/0"#0 [ffff88807e4c3e10] crash_nmi_callback at ffffffff810e3d20#1 [ffff88807e4c3e60] nmi_handle at ffffffff810e3a80#2 [ffff88807e4c3eb0] default_do_nmi at ffffffff810e3c10#3 [ffff88807e4c3ed0] do_nmi at ffffffff810e3d40#4 [ffff88807e4c3ef0] end_repeat_nmi at ffffffff82000b50[exception RIP: native_safe_halt+18]RIP: ffffffff810c1b32 RSP: ffff88807e4c3fa0 RFLAGS: 00000246RAX: 0000000000000000 RBX: 0000000000000000 RCX: 0000000000000000RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000000RBP: ffff88807e4c3fa0 R8: 0000000000000000 R9: 0000000000000000R10: 0000000000000000 R11: 0000000000000000 R12: ffffffff8223d200R13: 0000000000000000 R14: 0000000000000000 R15: 0000000000000000CS: 0010 SS: 0018
--- <NMI exception stack> ---
3. 内存与数据结构分析
命令 | 说明 |
---|---|
struct [name] [addr] | 查看指定地址的内核结构体内容(如 struct task_struct ) |
rd [addr] [length] | 以十六进制格式读取内存数据 |
search [-u] [value] | 在内存中搜索特定值(-u 表示按无符号整数搜索) |
vm -p [PID] | 查看指定进程的虚拟内存布局(类似 /proc/[PID]/maps ) |
示例:
crash> struct task_struct ffff88807c0a0000
struct task_struct {state = 0,stack = 0xffffc900001bc000,usage = {counter = 2},flags = 69238894,ptrace = 0,...
}
4. 进程与线程分析
命令 | 说明 |
---|---|
ps -a | 列出所有进程(包括内核线程) |
task [addr] | 查看指定任务的详细信息 |
set [PID] | 切换到指定进程的上下文 |
files [PID] | 查看进程打开的文件描述符 |
示例:
crash> ps -aPID PPID CPU TASK ST %MEM VSZ RSS COMM0 0 0 ffff88807c0a0000 RU 0.0 0 0 [swapper/0]1 0 1 ffff88807c0a0140 IN 0.0 19356 3208 systemd2 0 2 ffff88807c0a0280 IN 0.0 0 0 [kthreadd]...
5. 硬件相关分析
命令 | 说明 |
---|---|
bt -f | 显示调用栈及函数参数 |
dis [addr] | 反汇编指定地址的代码 |
regs | 查看寄存器状态 |
kmem -s | 检查内存泄漏或损坏 |
四、实战案例:分析内核 panic
步骤 1:定位崩溃点
crash> log | grep "Kernel panic"
[ 1234.567890] Kernel panic - not syncing: Fatal exception
步骤 2:查看调用栈
crash> bt
#5 [ffff88807e4c3e10] panic at ffffffff810e3d20
#6 [ffff88807e4c3e60] oops_end at ffffffff810e3a80
...
步骤 3:检查相关进程
crash> ps | grep -E "PID|1234"PID PPID CPU COMMAND1234 567 2 faulty_driver
步骤 4:分析驱动代码
crash> dis ffffffffc0123456 # 反汇编崩溃地址的代码
0xffffffffc0123456 <faulty_func+22>: mov 0x0(%rbp),%rax
0xffffffffc012345a <faulty_func+26>: test %rax,%rax
0xffffffffc012345d <faulty_func+29>: je 0xffffffffc0123470
五、注意事项
-
符号一致性
必须保证vmlinux
和vmcore
的内核版本完全一致,否则crash
会报错"cannot determine file type"
。 -
权限问题
分析vmcore
需要 root 权限,或用户属于crash
组。 -
调试符号路径
如果vmlinux
不在默认路径,需通过-S
选项指定搜索路径:crash -S /path/to/debuginfo ...
-
自动化分析
可通过编写脚本批量执行命令:crash -i analyze.crashscript vmlinux vmcore
六、扩展工具
-
GDB:适合用户态程序分析,但对内核支持有限。
-
makedumpfile:压缩转储文件,减少存储占用。
-
drgn:新一代内核调试工具,支持 Python 脚本化分析。
通过 crash
工具,开发者可以深入分析内核崩溃的根本原因(如空指针解引用、内存越界等),快速定位问题代码。熟练掌握其命令和调试技巧,是 Linux 系统故障排查的核心能力之一。