Core dump
core dump 是一个文件,其中包含进程意外终止时的进程地址空间(内存)。Core dump 可以按需生成(例如通过调试器),或在终止时自动生成。Core dump 由内核响应程序崩溃而触发,并可能传递给辅助程序(例如 systemd-coredump(8))以进行进一步处理。Core dump 通常不被普通用户使用,但开发人员可以将其用作程序崩溃时程序状态的事后快照,尤其是在故障难以可靠地重现时。
禁用自动 Core dump
用户可能希望出于多种原因禁用自动 core dump
- 性能:为内存密集型进程生成 core dump 可能会浪费系统资源并延迟内存清理。
- 磁盘空间:如果未压缩,内存密集型进程的 core dump 可能会消耗等于甚至大于进程内存 footprint 的磁盘空间。
- 安全性:core dump 虽然通常只有 root 用户可读,但可能包含敏感数据(例如密码或加密密钥),这些数据会在崩溃后写入磁盘。
使用 sysctl
可以使用 sysctl 将 kernel.core_pattern
设置为空以禁用 core dump 处理。创建此文件
/etc/sysctl.d/50-coredump.conf
kernel.core_pattern=|/bin/false
要立即应用设置,请使用 sysctl
# sysctl -p /etc/sysctl.d/50-coredump.conf
使用 systemd
systemd 的默认行为在 /usr/lib/sysctl.d/50-coredump.conf
中定义,它将 kernel.core_pattern
设置为调用 systemd-coredump
。它为 /var/lib/systemd/coredump
中的所有进程生成 core dump。可以通过在 /etc/systemd/coredump.conf.d/
目录中创建具有以下内容的配置片段来覆盖 systemd-coredump
的行为(参见 coredump.conf(5) § DESCRIPTION,[1])
/etc/systemd/coredump.conf.d/custom.conf
[Coredump] Storage=none ProcessSizeMax=0
[Coredump]
节名称,否则此选项将被忽略。然后使用 daemon-reload 重新加载 systemd 管理器配置。
参见 systemd-coredump(8) § Disabling coredump processing。
使用 PAM 限制
通过 PAM 登录的用户的最大 core dump 大小由 limits.conf 强制执行。将其设置为零将完全禁用 core dump。[2]
/etc/security/limits.conf
* hard core 0
使用 ulimit
诸如 bash 或 zsh 之类的命令行 shell 提供了一个内置的 ulimit 命令,该命令可用于报告或设置 shell 以及 shell 启动的进程的资源限制。有关详细信息,请参见 bash(1) § SHELL BUILTIN COMMANDS 或 zshbuiltins(1)。
要在当前 shell 中禁用 core dump
$ ulimit -c 0
如果系统设置为使用 kernel.core_pattern
将 core dump 管道传输到诸如 systemd-coredump 之类的程序,则 Linux 内核本身会忽略 ulimit 设置(请参见 core(5)),因此,这取决于 core dump 管道传输到的程序是否遵守此设置(systemd-coredump 仍然会使用它)。
对于不使用崩溃进程的 ulimit 设置的程序,可以使用 dumpable
prctl(2) 为选定的进程禁用 core dump 处理。
生成 Core dump
要生成任意进程的 core dump,首先安装 gdb 软件包。然后找到正在运行的进程的 PID,例如使用 pgrep
$ pgrep -f firefox
2071 firefox
附加到进程
$ gdb -p 2071
然后在 (gdb)
提示符下
(gdb) generate-core-file Saved corefile core.2071 (gdb) quit
现在您有了一个名为 core.2071
的 core dump 文件。
它们保存在哪里?
kernel.core_pattern
sysctl 决定了自动 core dump 的保存位置。默认情况下,core dump 会发送到 systemd-coredump,可以在 /etc/systemd/coredump.conf
中配置它。默认情况下,所有 core dump 都存储在 /var/lib/systemd/coredump
中(由于 Storage=external
),并且使用 zstd
压缩(由于 Compress=yes
)。此外,还可以配置存储的各种大小限制。
kernel.core_pattern
的默认值在 /usr/lib/sysctl.d/50-coredump.conf
中设置。可以按照正常的 sysctl.d(5) 规则屏蔽或覆盖此文件以使用不同的设置。要从日志中检索 core dump,请参见 coredumpctl(1)。
管理 Core dump 文件
使用 coredumpctl 查找相应的 dump。请注意,普通用户可以运行 coredumpctl 而无需特殊权限来管理其进程的 core dump。
# coredumpctl list
清理 Core dump 文件
存储在 /var/lib/systemd/coredump/
中的 core dump 文件将由 systemd-tmpfiles --clean
自动清理,后者每天通过 systemd-tmpfiles-clean.timer
触发。Core dump 配置为至少保留 3 天,请参见 systemd-tmpfiles --cat-config
。
分析 Core dump
首先,您需要唯一地标识相关的 dump。这可以通过指定 PID
、可执行文件的名称、可执行文件的路径或 journalctl 谓词来实现(有关详细信息,请参见 coredumpctl(1) 和 journalctl(1))。要查看 core dump 的详细信息
# coredumpctl info match
请注意“Signal”行,这有助于识别崩溃原因。对于分析,通常使用调试器检查回溯(默认情况下为 gdb(1))
# coredumpctl debug match
启动 gdb 后,使用 bt
命令打印完整的回溯
(gdb) thread apply all backtrace full
在许多情况下,输出将包含问号作为缺少调试符号的占位符。有关如何获取它们,请参见 Debugging/Getting traces。
参见
- american fuzzy lop - 用于内核和程序自动化测试的工具
- Filesystem fuzzing - 关于测试文件系统 bug 的 LWN 文章