Ubuntu Server:内核崩溃转储

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 内核知识。


来源:Ubuntu Server 文档:Kernel crash dump,Copyright © 2026,原页面更新于 2026-06-26。中文翻译;原文与示例归 Canonical 及各位贡献者所有。

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容