跳转到内容
来自 Arch Linux 中文维基

核心转储是进程意外终止时包含进程地址空间(内存)的文件。核心转储可以按需生成(例如由 debugger 生成),也可以在进程终止时自动生成。核心转储由内核在程序崩溃时触发,并可能传递给辅助程序(如 systemd-coredump(8))进行进一步处理。普通用户通常不会使用核心转储,但开发人员可以将其用作程序崩溃时的状态快照,尤其是在故障难以可靠重现的情况下。

警告:核心转储可能包含敏感数据(如密码或加密密钥),因此只能与受信方共享。

禁用自动核心转储

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

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

使用 sysctl

可以将 kernel.core_pattern 设置为空值以使 sysctl 不处理核心转储。请创建以下文件:

/etc/sysctl.d/50-coredump.conf
kernel.core_pattern=|/bin/false

要立即应用设置,请执行以下命令:

# sysctl -p /etc/sysctl.d/50-coredump.conf

使用 systemd

/usr/lib/sysctl.d/50-coredump.conf 文件定义了 systemd 的默认行为,该文件将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:核心转储 中讨论)


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

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

使用 ulimit

像是bashzsh这样的 命令行解释器 中提供了内置的 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 设置的崩溃进程的程序,可以使用 dumpableprctl(2) 来禁用特定进程的核心转储处理。

生成核心转储

本文或本章节的语言、语法或风格需要改进。参考:帮助:风格

原因:Partially duplicates Debugging/Getting traces#Attaching to an existing process and misses the info on ptrace scope.(在Talk:核心转储讨论)


要生成任意进程的核心转储,首先要 安装 gdb 软件包。然后查找正在运行的进程的 PID,例如使用“‘pgrep’”:

$ pgrep -f firefox
2071 firefox

关联进程:

$ gdb -p 2071

(gdb) 提示下:

(gdb) generate-core-file
Saved corefile core.2071
(gdb) quit

现在您有了一个名为 core.2071 的 coredump 文件。

核心转储文件去哪儿了?

kernel.core_pattern 内核模式 sysctl 决定自动核心转储的位置。默认情况下,核心转储将被发送到 systemd-coredump ,可以使用 /etc/systemd/coredump.conf 来定义其行为。默认下,所有的核心转储文件储存在 /var/lib/systemd/coredump (因为配置了 Storage=external),它们被 zstd 压缩(因为配置了 Compress=yes)。此外,还可以配置存储的各种大小限制。

注意:/usr/lib/sysctl.d/50-coredump.conf 中配置了 kernel.core_pattern 的默认值, 如果遵循默认的 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

在许多情况下,输出将包含问号作为缺失调试符号的占位符。如何获取这些符号,请参阅 调试/获取跟踪数据

另见