Ubuntu Server:内核崩溃转储
内核崩溃转储(kernel crash dump)是在内核运行中断时,将一部分易失性内存(RAM)内容复制到磁盘的过程。可能引发内核中断的事件包括:
- 内核恐慌(kernel panic)。
- 不可屏蔽中断(NMI)。
- 机器检查异常(MCE)。
- 硬件故障。
- 人工干预。
某些事件,例如内核恐慌和 NMI,会使内核自动通过 kexec 触发转储机制;其他情况则需要人工捕获内存。无论哪种情况,分析保存下来的内存内容都有助于找出根因,防止问题再次发生。
内核崩溃转储的机制
发生内核恐慌时,内核借助 kexec,在系统启动时预留的一块内存中快速启动新的内核实例。原内存区域保持不变,新的捕获内核便能安全地把内容复制到存储设备。
安装
多数 Ubuntu 环境默认安装内核崩溃转储工具,尤其是面向裸机运行的环境。其他环境可以安装:
sudo apt install kdump-tools
安装时会出现如下配置对话框:
|------------------------| Configuring kdump-tools |------------------------|
| |
| |
| If you choose this option, the kdump-tools mechanism will be enabled. A |
| reboot is still required in order to enable the crashkernel kernel |
| parameter. |
| |
| Should kdump-tools be enabled be default? |
| |
| <Yes> <No> |
| |
|---------------------------------------------------------------------------|
选择 Yes 启用 kdump-tools。如果想重新选择,运行 dpkg-reconfigure kdump-tools,再回答 Yes 或 No。
符合条件时默认启用 kdump
手动安装时,是否启用取决于交互式问题的回答。自动预装时,需要在默认可用和内存成本之间取舍:发生故障后再启用转储已经太迟,但捕获内核必须预留内存,小系统或设备很多的系统可能受到明显影响。
从 Oracular Oriole(Ubuntu 24.10)开始,标准 Ubuntu Desktop 或 Server 安装会在满足以下条件时默认启用:
- 至少四个 CPU 线程。
- RAM 至少 6 GB,且小于 2 TB。
/var中的可用空间超过 RAM 与交换空间总和的五倍。- CPU 架构为 amd64 或 s390x;或使用 UEFI 的 arm64。
安装时由 /usr/share/kdump-tools/kdump_set_default 判断这些条件。不符合条件的机器,以及早于 24.10 的版本,可以按安装说明手动启用。
禁用 kdump
无论通过何种方式启用,都可以卸载软件包来禁用:
sudo apt remove kdump-tools
也可以修改 /etc/default/kdump-tools:
USE_KDUMP=0
让配置更改生效
安装或移除 kdump-tools 后,如果尚未重启,需要重启系统,才能重新评估启动参数 crashkernel=。
检查 kdump 是否就绪
重启后,系统会预留 crashkernel 内存,kdump-tools 服务应启用并运行。如果重启之后才启用工具,只需运行 kdump-config load 来激活机制。
查看状态:
kdump-config show
原文的示例输出:
DUMP_MODE: kdump
USE_KDUMP: 1
KDUMP_COREDIR: /var/crash
crashkernel addr: 0x60000000
/var/lib/kdump/vmlinuz: symbolic link to /boot/vmlinuz-6.18.0-8-generic
kdump initrd:
/var/lib/kdump/initrd.img: symbolic link to /var/lib/kdump/initrd.img-6.18.0-8-generic
current state: ready to kdump
crashkernel suggested size: 417M
kexec command:
/sbin/kexec -p -s --command-line="BOOT_IMAGE=/vmlinuz-6.18.0-8-generic root=UUID=0a86b691-f733-4cb0-9c5c-b88e0ef9e212 ro console=tty1 console=ttyS0 reset_devices systemd.unit=kdump-tools-dump.service nr_cpus=1 irqpoll usbcore.nousb" --initrd=/var/lib/kdump/initrd.img /var/lib/kdump/vmlinuz
转储文件将保存在 /var/crash。
预留内存
kdump 需要预先分配一块专用、隔离的物理内存,让主操作系统不去使用。发生内核恐慌后,原系统已经不稳定,内存也可能损坏,不能依赖它来保存诊断数据。
启动时预留内存,使第二个小型“捕获内核”能在这块干净的区域运行,不依赖损坏内核的资源。它随后读取冻结的崩溃内存并写入磁盘,类似在已崩溃系统中运行一个新的操作系统。
首先确认启动参数中存在 crashkernel:
cat /proc/cmdline
BOOT_IMAGE=/vmlinuz-6.18.0-8-generic
root=UUID=0a86b691-f733-4cb0-9c5c-b88e0ef9e212 ro console=tty1 console=ttyS0
crashkernel=2G-4G:320M,4G-32G:512M,32G-64G:1024M,64G-128G:2048M,128G-:4096M
参数语法为:
crashkernel=<range1>:<size1>[,<range2>:<size2>,...][@offset]
range=start-[end] 'start' is inclusive and 'end' is exclusive.
其中范围的起点包含在内,终点不包含在内。上例使用:
crashkernel=2G-4G:320M,4G-32G:512M,32G-64G:1024M,64G-128G:2048M,128G-:4096M
含义是:
- RAM 小于 2 G 时不预留,避免对小系统造成过大影响。
- RAM 在 2 G(含)到 4 G(不含)时预留 320 M。
- 其余范围依次类推。
- 最后一段从 128 G 起预留 4096 M。
然后检查内核是否确实预留了内存:
dmesg | grep -i crash
[ 0.004623] crashkernel reserved: 0x0000000060000000 - 0x0000000074000000 (320 MB)
这里是 3 GB 内存系统,对应 320 MB,符合配置。
软件包的默认值较保守,以免浪费过多内存。但少数情况下,预留不足会导致转储初始化失败。所需内存只能在系统正常运行时估算。kdump-config show 中的 crashkernel suggested size: 417M,依据当前内核启动时消耗的内存给出建议。
如果建议值高于默认值,可以考虑增加预留量,避免转储因内存耗尽(OOM)失败。编辑 /etc/default/grub.d/kdump-tools.cfg 中的 crashkernel= 参数,运行 sudo update-grub,重启后再次测试。
配置
除了本地保存,也可以通过 SSH 或 NFS 将内核崩溃转储发送到远程服务器。
本地转储
本地转储会自动配置,除非选择远程协议,否则一直使用本地模式。/etc/default/kdump-tools 中详细说明了多种配置项。
通过 SSH 远程转储
修改 /etc/default/kdump-tools:
# ---------------------------------------------------------------------------
# Remote dump facilities:
# SSH - username and hostname of the remote server that will receive the dump
# and dmesg files.
# SSH_KEY - Full path of the ssh private key to be used to login to the remote
# server. use kdump-config propagate to send the public key to the
# remote server
# HOSTTAG - Select if hostname of IP address will be used as a prefix to the
# timestamped directory when sending files to the remote server.
# 'ip' is the default.
SSH="ubuntu@kdump-netcrash"
唯一必填变量是 SSH,格式为 {username}@{remote server},同时包含远程账户和主机名。
SSH_KEY 可以指定已有私钥。未指定时,kdump-config propagate 会创建新的密钥对。HOSTTAG 可以将远程目录前缀由 IP 地址改为主机名。
以下是原文创建密钥对并将公钥传送到服务器的示例:
sudo kdump-config propagate
Need to generate a new ssh key...
The authenticity of host 'kdump-netcrash (192.168.1.74)' can't be established.
ECDSA key fingerprint is SHA256:iMp+5Y28qhbd+tevFCWrEXykDd4dI3yN4OVlu3CBBQ4.
Are you sure you want to continue connecting (yes/no)? yes
ubuntu@kdump-netcrash's password:
propagated ssh key /root/.ssh/kdump_id_rsa to server ubuntu@kdump-netcrash
要发送公钥,需要输入远程服务器上相应账户的密码。
用 kdump-config show 确认 SSH 模式配置:
DUMP_MODE: kdump
USE_KDUMP: 1
KDUMP_SYSCTL: kernel.panic_on_oops=1
KDUMP_COREDIR: /var/crash
crashkernel addr: 0x2c000000
/var/lib/kdump/vmlinuz: symbolic link to /boot/vmlinuz-4.4.0-10-generic
kdump initrd:
/var/lib/kdump/initrd.img: symbolic link to /var/lib/kdump/initrd.img-4.4.0-10-generic
SSH: ubuntu@kdump-netcrash
SSH_KEY: /root/.ssh/kdump_id_rsa
HOSTTAG: ip
current state: ready to kdump
通过 NFS 远程转储
在 /etc/default/kdump-tools 中配置:
# NFS - Hostname and mount point of the NFS server configured to receive
# the crash dump. The syntax must be {HOSTNAME}:{MOUNTPOINT}
# (e.g. remote:/var/crash)
#
NFS="kdump-netcrash:/var/crash"
与 SSH 模式一样,HOSTTAG 可以将远程目录前缀由 IP 地址改为主机名。使用 kdump-config show 确认配置:
DUMP_MODE: kdump
USE_KDUMP: 1
KDUMP_SYSCTL: kernel.panic_on_oops=1
KDUMP_COREDIR: /var/crash
crashkernel addr: 0x2c000000
/var/lib/kdump/vmlinuz: symbolic link to /boot/vmlinuz-4.4.0-10-generic
kdump initrd:
/var/lib/kdump/initrd.img: symbolic link to /var/lib/kdump/initrd.img-4.4.0-10-generic
NFS: kdump-netcrash:/var/crash
HOSTTAG: hostname
current state: ready to kdump
故障排查
kdump-config show 会显示配置状态。内存不足的系统,例如只有 1 GB RAM 的系统,不会按默认规则预留内存,因而初始化失败。重点检查 current state。
原文展示的失败状态如下:
DUMP_MODE: kdump
USE_KDUMP: 1
KDUMP_COREDIR: /var/crash
crashkernel addr:
/var/lib/kdump/vmlinuz: symbolic link to /boot/vmlinuz-6.18.0-8-generic
kdump initrd:
/var/lib/kdump/initrd.img: symbolic link to /var/lib/kdump/initrd.img-6.18.0-8-generic
current state: Not ready to kdump
crashkernel suggested size: 329M
kexec command:
no kexec command recorded
也可以查看日志或服务状态:
systemctl status kdump-tools
...
... kdump-tools[5348]: Memory for crashkernel is not reserved
... kdump-tools[5348]: Please reserve memory by passing"crashkernel=Y@X" parameter to kernel
... kdump-tools[5348]: Then try to loading kdump kernel
测试崩溃转储机制
测试会导致系统重启。系统负载较高时还可能丢失数据。测试前应确认系统空闲或负载很低。
检查 SysRQ 是否启用:
cat /proc/sys/kernel/sysrq
返回 0 时,转储并重启功能很可能已关闭。大于 1 表示只启用了部分 SysRq 功能。各选项与默认值详见 /usr/lib/sysctl.d/55-magic-sysrq.conf。
在 Ubuntu 24.10 及更早版本中,该文件位于 /etc/sysctl.d/10-magic-sysrq.conf。
若已禁用,可启用:
sudo sysctl -w kernel.sysrq=1
接下来必须成为 root 用户,仅在命令前加 sudo 不够。以 root 身份执行以下命令,会主动触发内核崩溃:
echo c > /proc/sysrq-trigger
如果通过网络连接操作,将失去与系统的连接。因此原文建议在系统控制台测试,也便于观察转储过程。串口控制台可能显示:
[ 977.208267] sysrq: Trigger a crash
[ 977.209313] Kernel panic - not syncing: sysrq triggered crash
[ 977.210684] CPU: 0 UID: 0 PID: 1567 Comm: bash Kdump: loaded Not tainted 6.18.0-8-generic #8-Ubuntu PREEMPT(voluntary)
[ 977.215248] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009)/LXD, BIOS unknown 2/2/2022
[ 977.216319] Call Trace:
...
后续输出可能被截断,但应能看到系统重启,并在日志中出现类似:
[ 5.171504] kdump-tools[740]: Starting kdump-tools:
[ 5.174084] kdump-tools[747]: * running makedumpfile --dump-dmesg /proc/vmcore /var/crash/202601210724/dmesg.202601210724
[ 5.185243] kdump-tools[765]: The kernel version is not supported.
[ 5.188411] kdump-tools[765]: The makedumpfile operation may be incomplete.
[ 5.191528] kdump-tools[765]: The dmesg log is saved to /var/crash/202601210724/dmesg.202601210724.
[ 5.196300] kdump-tools[765]: makedumpfile Completed.
[ 5.199056] kdump-tools[747]: * kdump-tools: saved dmesg content in /var/crash/202601210724
[ 5.204580] kdump-tools[747]: * running makedumpfile -F -c -d 31 /proc/vmcore | compress > /var/crash/202601210724/dump-incomplete
[ 5.210935] kdump-tools[769]: The kernel version is not supported.
[ 5.214499] kdump-tools[769]: The makedumpfile operation may be incomplete.
Copying data : [100.0 %] \ eta: 0 s
[ 7.000839] kdump-tools[769]: The dumpfile is saved to STDOUT.
[ 7.003347] kdump-tools[769]: makedumpfile Completed.
[ 7.006824] kdump-tools[747]: * kdump-tools: saved vmcore in /var/crash/202601210724
完成后,系统再次重启,恢复正常工作模式。内核转储与相关子目录位于 /var/crash。查看:
ll /var/crash
drwxr-xr-x 2 root root 4096 Jan 21 07:31 202601210724/
-rw-r--r-- 1 root root 28838 Jan 21 07:24 linux-image-6.18.0-8-generic-202601210724.crash
再查看本例的子目录:
ll /var/crash/202601210724
-rw------- 1 root root 82264 Jan 21 07:24 dmesg.202601210724
-rw-r--r-- 1 root root 51753823 Jan 21 07:24 dump.202601210724
分析转储
调试需要未压缩、未剥离且带调试符号的内核信息。请按获取 -dbgsym.ddeb 软件包说明,使系统识别相应仓库与密钥。
分析不一定要在发生崩溃的机器上进行,可以把文件复制到其他系统。但本例使用 uname -r 自动选择当前内核;在另一台机器上分析时,需要按实际崩溃内核调整。
如果发生崩溃的内核与当前运行内核相同,可安装:
apt-get install linux-image-$(uname -r)-dbgsym
内核二进制很大,调试符号更大,下载需要时间,也会占用较多磁盘空间。本例获得 linux-image-unsigned-6.18.0-8-generic-dbgsym,调试信息位于 /usr/lib/debug/lib/modules/6.18.0-8-generic。
准备好后打开转储:
crash /usr/lib/debug/boot/vmlinux-6.18.0-8-generic /var/crash/202601210724/dump.202601210724
...
KERNEL: /usr/lib/debug/boot/vmlinux-6.18.0-8-generic
DUMPFILE: /var/crash/202601210724/dump.202601210724 [PARTIAL DUMP]
CPUS: 1
DATE: Thu Jan 1 00:00:00 UTC 1970
UPTIME: 00:16:16
LOAD AVERAGE: 0.00, 0.00, 0.00
TASKS: 157
NODENAME: r-vm
RELEASE: 6.18.0-8-generic
VERSION: #8-Ubuntu SMP PREEMPT_DYNAMIC Wed Dec 17 16:14:24 UTC 2025
MACHINE: x86_64 (3792 Mhz)
MEMORY: 3 GB
PANIC: "Kernel panic - not syncing: sysrq triggered crash"
PID: 1567
COMMAND: "bash"
TASK: ffff89cd07908000 [THREAD_INFO: ffff89cd07908000]
CPU: 0
STATE: TASK_RUNNING (PANIC)
crash>
本例的恐慌原因就是前面主动触发的测试:
PANIC: "Kernel panic - not syncing: sysrq triggered crash"
后续分析步骤取决于具体要调查的问题。
延伸阅读
内核崩溃转储是一个很大的主题,需要较扎实的 Linux 内核知识。
- Linux 内核 kdump 文档。
- Analyzing Linux Kernel Crash:基于 Fedora,但仍是很好的转储分析指南。
来源:Ubuntu Server 文档:Kernel crash dump,Copyright © 2026,原页面更新于 2026-06-26。中文翻译;原文与示例归 Canonical 及各位贡献者所有。











暂无评论内容