当前位置:首页>Linux>kdump 的“前世”:Linux 为什么需要 Crash Dump

kdump 的“前世”:Linux 为什么需要 Crash Dump

  • 2026-09-10 03:06:04
kdump 的“前世”:Linux 为什么需要 Crash Dump

1. 早期问题背景

在 kdump 出现之前,Linux 面临一个长期痛点:

  • 内核一旦 panic / hang

    • 内存内容不可读

    • 现场状态完全丢失

  • 只能靠:

    • printk 日志(信息有限)

    • 人工复现

    • 猜测性修 bug

而在 商业 UNIX / Mainframe 体系中,crash dump 是标配:

  • AIX / Solaris / HP-UX 都支持

  • 金融、电信必须要“事后取证”

Linux 社区早期对 crash dump 态度是:

“panic 就 panic,重启就好”

但随着 Linux 进入 服务器、金融、电信、云平台,这个态度不可接受,也是不可接受的,一切都要找到问题的原因,这也是我们每个工程师的态度吧!


2. kdump 出现之前的尝试

(1) LKCD(Linux Kernel Crash Dump)

  • 时间:2000 年左右

  • 思路:

    • panic 后尝试把内存写到磁盘

  • 致命问题:

    • panic 时内核状态不可控

    • IO、锁、调度器可能已损坏

    • 不可靠

👉 结论:在“坏掉的内核里做复杂事”是错误路线


二、kdump 的“今生”:kexec + crash kernel 的革命性设计

让一个“干净的小内核”来替已经崩溃的“大内核”收尸

这就是 kdump 的根本设计哲学,也就是系统挂死以后,会有启动用一个小的系统进行内核异常收集方便研发工程师定位问题。


三、kdump 架构全景

1. 三个关键组件

组件
作用
kexec
不经 BIOS/firmware,直接加载并跳转新内核
crash kernel
预留的一块“永不被污染”的内存
vmcore
崩溃内核的完整内存快照

2. 内存视角

+---------------------------+  高地址|       Normal Kernel       ||   (业务 / 网络 / IO)     ||                           |+---------------------------+|   Crash Kernel Reserved   |  ← 启动时预留|   (128M / 256M / ...)     |+---------------------------+  低地址
  • crash kernel 内存

    • 启动时通过 crashkernel= 参数预留

    • 正常运行时 完全不使用

    • panic 后独立运行


四、kdump 的实现原理(核心流程)

1. 正常启动阶段

(1) 预留 crash kernel 内存

Boot 参数: (我自己预留是500M)

crashkernel=500M

内核启动早期:

  • memblock 预留一段连续物理内存

  • 标记为:

    • 不参与 buddy allocator

    • 不参与 CMA

    • 不被 kmalloc / page allocator 使用

(2) 加载 crash kernel

kexec -p /boot/vmlinuz-crash \      --initrd=/boot/initramfs-crash.img \      --command-line="root=/dev/ram0 ..."
  • -p:表示 panic kernel

  • crash kernel 常见特性:

    • 精简驱动

    • 无业务负载

    • 只做一件事:dump 内存


2. panic 发生时(最关键)

当主内核发生:

  • panic()

  • Oops + panic_on_oops

  • NMI watchdog

  • 手工触发:

    echo c > /proc/sysrq-trigger

内核执行:

panic() └─ crash_kexec()     ├─ 停止其他 CPU     ├─ 禁用中断     ├─ 保存 CPU 上下文     └─ 直接跳转到 crash kernel

⚠️ 不走 BIOS、不走 firmware、不做设备 reset


3. crash kernel 阶段

crash kernel 启动后:

  1. 重新初始化:

    • MMU

    • 调度器

    • 驱动(最小集合)

  2. 识别:

    • 崩溃内核的物理内存布局

  3. 生成 /proc/vmcore

    • ELF 格式

    • PT_LOAD 对应原内存段

  4. 用户态工具保存 vmcore:

    makedumpfile /proc/vmcore /var/crash/vmcore

五、kdump 的实际使用(如果你是使用的发行版使用下面的方式就可以安装)

如果你是嵌入式系统可能需要自己的文件系统和内核相互配合才可以实现,这里我使用发行版为例子吧

1. 基本启用步骤

(1) 安装工具

yum install kexec-tools# orapt install kdump-tools

(2) 配置 crashkernel

GRUB_CMDLINE_LINUX="crashkernel=256M"grub2-mkconfig -o /boot/grub2/grub.cfgreboot

(3) 启动 kdump 服务

systemctl enable kdumpsystemctl start kdump

2. 测试 kdump 是否可用

echo 1 > /proc/sys/kernel/sysrqecho c > /proc/sysrq-trigger

检查:

ls /var/crash/

3. vmcore 分析

(1) crash 工具

crash /usr/lib/debug/lib/modules/$(uname -r)/vmlinux vmcore

(2) 常用分析命令

bt          # backtraceps          # 进程状态kmem        # 内存files       # 打开的文件net         # 网络状态

六、资深工程师可能关心的细节

1. 为什么 kdump 比 LKCD 稳定?

点
LKCD
kdump
IO 执行者
崩溃内核
新内核
锁依赖
高
几乎无
调度器
可能坏
全新
可靠性
低
极高

2. SMP / NUMA 处理

  • panic 时:

    • stop_machine / IPI 停止其他 CPU

  • crash kernel:

    • NUMA 感知

    • 按 node dump 内存

  • 支持:

    • x86

    • ARM64

    • POWER


3. makedumpfile 的优化策略

避免 vmcore 过大:

makedumpfile --compress --message-level 1 \             --exclude-user-data \             /proc/vmcore vmcore
  • 跳过 free pages

  • 仅保留 kernel-relevant pages

  • 支持:

    • lzo

    • zstd


七、常见问题与坑

1. crashkernel 预留太小

症状:

  • kdump 启动失败

  • panic 后重启无 vmcore

经验值(x86_64):

内存
crashkernel
≤64G
256M
64–256G
512M
>256G
1G

2. IOMMU / 驱动问题

  • crash kernel 驱动需:

    • SATA / NVMe / 网卡

  • 云环境:

    • 建议 dump 到网络(SSH / NFS)


八、kdump 与相关机制对比

技术
作用
sysrq
触发 panic
kexec
直接跳内核
ftrace
事前追踪
eBPF
运行期观测
kdump
事后取证

👉 kdump 是“事后法医工具”,不是性能工具


九、总结(给潜在成为架构师的你)

kdump 的本质,是在系统彻底失控之前,预留一条“逃生通道”,用一个干净内核来保存失败内核的全部证据。

最新文章

随机文章