crash命令
crash是 Linux内核崩溃分析工具用于分析vmcore/var/crash/下的崩溃转储在线调试运行中的内核查看栈、寄存器、结构体、汇编、锁、进程、内存等最常用基础命令crash /usr/lib/debug/lib/modules/$(uname -r)/vmlinux /var/crash/xxx/vmcore核心命令bt当前 CPU 栈回溯最重要bt -a所有 CPU 栈log内核日志dmesgdis反汇编rd查看内存sym查地址对应符号mod查看模块task查看进程files进程打开文件vm进程虚拟内存runqCPU 运行队列spin、mutex锁信息kmem内存信息dev设备信息debuginfocrash 工具本身二进制不需要debuginfo。但分析内核崩溃vmcore必须要有vmlinux带调试信息对应内核版本的kernel-debuginfo没有 debuginfo你只有一堆十六进制地址无法解析函数名无法解析结构体无法看行号无法看栈意义等于 “瞎子分析崩溃”。debuginfo 提供的核心能力符号表地址 ↔ 函数名结构体定义struct、union、enum行号信息崩溃对应源码行变量偏移struct 成员在内存的位置这些是 crash 所有命令的基础bt、log、dis、struct、mod、vm、files、spin没有 debuginfo → 99% 命令不可用。手动指定 debuginfo启动时直接指定最常用crash vmlinux vmcore --debuginfo /path/to/your/debuginfo/file启动后动态指定灵活crash debugfile /path/to/debuginfo典型 Oops/Panic 关键信息一条崩溃里你只需要看这几行RIP: [...] RSP: [...] CR2: [...] # 缺页地址 ERROR: [...] # 错误码 Call Trace:RIP出错指令地址CR2访问的非法地址Call Trace调用栈 → 定位哪个函数崩的常见崩溃原因NULL 指针解引用最常见野指针 / 越界访问双重释放 / UAF栈溢出死锁导致 softlockup/hardlockupRCU 停滞页表错误 / 内存一致性问题驱动操作硬件异常快速定位套路bt看栈 → 找到崩溃函数log看前后日志dis看崩溃指令struct xxx 地址看结构体是否被踩rd -x 地址看内存是否合法判断是内核问题还是驱动 / 模块问题最核心基础命令1. 系统概况sys # 系统版本、崩溃时间、崩溃原因 status # 当前 CPU、寄存器、崩溃位置2. 内核日志找崩溃原因第一命令log # 完整 dmesg包含 Oops/Panic重点看RIP: 出错指令 CR2: 访问的非法地址0NULL指针 Error Code: 错误码 Call Trace: 调用栈3. 栈回溯定位哪个函数崩溃bt # 当前崩溃 CPU 栈 bt -a # 所有 CPU 栈死锁必用 bt -l # 显示行号4. 反汇编定位具体指令dis func # 反汇编函数 dis -l func # 显示行号 dis 0xffffffff... # 反汇编地址看到类似mov 0x0(%rax), %rdx就是NULL 指针解引用。5. 查看数据结构最常用struct task_struct # 查看结构体定义 struct task_struct 地址 # 查看具体结构体内容 struct sk_buff 地址 struct net_device 地址 struct file 地址6. 查看内存rd -x 地址 # 16进制查看内存 rd -32 地址 # 32位 rd -64 地址 # 64位7. 进程信息ps # 所有进程 ps -a|more task 地址 # 查看 task_struct files 地址 # 进程打开的文件 vm 地址 # 进程虚拟内存 runq # CPU 运行队列8. 模块驱动崩溃必查mod # 列出内核模块 mod -s xxx # 查看模块地址范围9. 锁死锁 /softlockupspin # 自旋锁 mutex # 互斥锁 waitq # 等待队列10. 内存信息kmem # 内存概况 buddy # 伙伴系统 slab # slab 信息实战启动命令crash /usr/lib/debug/lib/modules/$(uname -r)/vmlinux /var/crash/xxx/vmcore出现crash就进入实战。第一步看系统基本信息sys能看到崩溃时间崩溃原因Oops/Panic崩溃进程、CPU第二步看内核日志最关键log重点找RIP: 0010:xxxxxxxxxx CR2: xxxxxxxx # 缺页地址 Call Trace:RIP 崩溃指令CR2 访问的非法地址Call Trace 调用栈如果看到CR2: 0000000000000000→NULL 指针90% 崩溃第三步回溯堆栈定位函数bt # 当前崩溃CPU栈 bt -a # 所有CPU栈死锁/锁冲突必用示例Call Trace: [ffffffffabcd1234] xxx_func0x32/0x100 [xxx_driver] [ffffffff81234567] sys_write0x54/0x70直接告诉你xxx_driver 里的 xxx_func 崩溃。第四步看崩溃位置的汇编判断是哪行代码崩的dis -l func_name # 反汇编行号 dis -l ffffffffabcd1234 # 直接反汇编地址看哪一行指令崩溃mov 0x0(%rax), %rdx→ 解引用 NULLcallq *%rbx→ 函数指针被踩第五步查看结构体判断是否内存踩坏struct task_struct 进程地址 struct sk_buff 地址 struct file 地址如果看到magic 0x57575757 next 0xcccccccc→内存越界、野指针、UAF释放后使用第六步查看锁死锁 /softlockup 实战spin # 自旋锁 mutex # 互斥锁 runq # CPU运行队列 ps # 看D状态进程大量 D 状态 锁持有不释放 →死锁。第七步看模块驱动崩溃必查mod mod -s xxx_driver # 查看模块地址范围崩溃地址落在模块范围内 →驱动 BUG。实战总结log→ 找 RIP/CR2/Call Tracebt→ 定位崩溃函数dis→ 看崩溃指令struct→ 看结构体是否被踩判断NULL 指针越界UAF死锁驱动 BUG