核心转储

来自 ArchWiki
(重定向自 Systemd-coredump)

核心转储 是一个文件,其中包含进程意外终止时的进程地址空间(内存)。核心转储可以在需要时生成(例如通过调试器),或在终止时自动生成。核心转储由内核响应程序崩溃而触发,并可能传递给辅助程序(例如 systemd-coredump(8))以进行进一步处理。核心转储通常不被普通用户使用,但开发人员可以将其用作程序崩溃时程序状态的事后快照,特别是当故障难以可靠地重现时。

警告: 核心转储应仅与受信任的方共享,因为它们可能包含敏感数据(例如密码或加密密钥)。

禁用自动核心转储

用户可能希望出于多种原因禁用自动核心转储

  • 性能:为内存密集型进程生成核心转储可能会浪费系统资源并延迟内存清理。
  • 磁盘空间:如果未压缩,内存密集型进程的核心转储可能会消耗与进程内存占用量相等甚至更大的磁盘空间。
  • 安全性:核心转储虽然通常只有 root 用户可读,但可能包含敏感数据(例如密码或加密密钥),这些数据在崩溃后写入磁盘。

使用 sysctl

sysctl 可用于将 kernel.core_pattern 设置为空,以禁用核心转储处理。创建此文件

/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 中的所有进程生成核心转储。可以通过在 /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 限制

此文章或章节的 фактическая точность 被质疑。

原因: limits.conf#core 建议设置软限制,以便可以使用 ulimit -c unlimited 临时启用核心转储。(在 Talk:Core dump 中讨论)

通过 PAM 登录的用户的最大核心转储大小由 limits.conf 强制执行。将其设置为零将完全禁用核心转储。[2]

/etc/security/limits.conf
* hard core 0

使用 ulimit

诸如 bashzsh 之类的命令行 shell 提供了一个内置的 ulimit 命令,该命令可用于报告或设置 shell 和 shell 启动的进程的资源限制。有关详细信息,请参见 bash(1) § SHELL BUILTIN COMMANDSzshbuiltins(1)

要在当前 shell 中禁用核心转储

$ ulimit -c 0

如果系统设置为使用 kernel.core_pattern 将核心转储通过管道传输到诸如 systemd-coredump 之类的程序,则 Linux 内核本身将忽略 ulimit 设置(请参见 core(5)),因此,这取决于转储通过管道传输到的程序是否遵循此设置(systemd-coredump 仍将使用它)。

对于不使用崩溃进程的 ulimit 设置的程序,可以使用 dumpable prctl(2) 为选定的进程禁用核心转储处理。

生成核心转储

此文章或章节需要语言、wiki 语法或样式改进。请参阅 Help:Style 以供参考。

原因: 部分重复 Debugging/Getting traces#Attaching to an existing process,并遗漏了有关 ptrace 范围的信息。(在 Talk: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 的核心转储文件。

它们存储在哪里?

kernel.core_pattern sysctl 决定自动核心转储的存储位置。默认情况下,核心转储被发送到 systemd-coredump,可以在 /etc/systemd/coredump.conf 中配置。默认情况下,所有核心转储都存储在 /var/lib/systemd/coredump 中(由于 Storage=external),并且使用 zstd 压缩(由于 Compress=yes)。此外,还可以配置各种存储大小限制。

注意: kernel.core_pattern 的默认值在 /usr/lib/sysctl.d/50-coredump.conf 中设置。可以按照正常的 sysctl.d(5) 规则屏蔽或覆盖此文件以使用不同的设置。

要从日志中检索核心转储,请参阅 coredumpctl(1)

管理核心转储文件

使用 coredumpctl 查找相应的转储。请注意,普通用户可以运行 coredumpctl 而无需特殊权限来管理其进程的核心转储。

# coredumpctl list

清理核心转储文件

存储在 /var/lib/systemd/coredump/ 中的核心转储文件将由 systemd-tmpfiles --clean 自动清理,该清理每天由 systemd-tmpfiles-clean.timer 触发。核心转储被配置为至少保留 3 天,请参阅 systemd-tmpfiles --cat-config

分析核心转储

首先,您需要唯一地标识相关的转储。这可以通过指定 PID,可执行文件的名称,可执行文件的路径或 journalctl 谓词来实现(有关详细信息,请参见 coredumpctl(1)journalctl(1) )。要查看核心转储的详细信息

# coredumpctl info match

请注意“Signal”行,这有助于识别崩溃原因。对于分析,通常使用调试器检查回溯(默认情况下为 gdb(1)

# coredumpctl debug match

启动 gdb 后,使用 bt 命令打印完整的回溯

(gdb) thread apply all backtrace full

在许多情况下,输出将包含问号作为缺少调试符号的占位符。请参阅 Debugging/Getting traces,了解如何获取它们。

另请参阅