core dump未生成的首要原因是kernel.core_pattern被设为管道模式(以|开头),导致转交systemd-coredump处理;需检查该值、确保systemd-coredump.socket处于active (listening)状态,并确认Storage=external及路径权限正常。

core dump 未生成,先查 kernel.core_pattern 是否被覆盖
Linux 默认把 core dump 写到当前工作目录的 core 文件,但多数发行版(尤其是 systemd 系统)会通过 sysctl 或 init 脚本把 kernel.core_pattern 改成管道形式,例如 |/usr/lib/systemd/systemd-coredump %P %u %g %s %t %c %h %e。一旦走管道,实际写入就交给 systemd-coredump 处理,而不是落盘为普通文件。
检查方式很简单:
- 运行
cat /proc/sys/kernel/core_pattern,看输出是不是以|开头 - 如果是,说明内核把 core 直接发给用户态程序,不生成本地文件
- 注意:该值可能被
/etc/sysctl.d/*.conf、/proc/sys/kernel/core_pattern写入、或systemd-sysctl加载时覆盖,优先级需实测
systemd-coredump socket 是否 active 决定 dump 能否被接收
systemd-coredump 不是常驻进程,而是由 systemd-coredump@.service 按需启动,背后依赖 systemd-coredump.socket 监听 /run/systemd/coredump 这个 AF_UNIX socket。如果 socket 没启用,即使 kernel.core_pattern 指向它,内核也会静默丢弃 core 数据。
验证和修复步骤:
- 运行
systemctl status systemd-coredump.socket,确认状态为active (listening) - 若显示
inactive (dead),执行sudo systemctl enable --now systemd-coredump.socket - 注意:某些最小化系统(如 container、CI runner)默认禁用该 socket,且不会报错,只会“没 dump”
权限与路径限制让 coredump “写进去又消失”
即使 socket 活着、core_pattern 正确,systemd-coredump 仍可能因权限或配额拒绝保存。它默认将 dump 存在 /var/lib/systemd/coredump/,受以下约束:
-
Storage=配置(在/etc/systemd/coredump.conf)决定是否存盘:external(存)、none(丢弃)、journal(仅记日志) -
MaxUse=和MaxSize=可能触发自动清理,老 dump 被删,新 dump 写不进 - 目标目录需对
systemd-coredump用户(通常是root)可写;若挂载了noexec或nodev,部分版本会静默失败 - 测试方法:手动触发 dump(如
kill -SEGV $$),再查coredumpctl list或journalctl -t systemd-coredump
调试时绕过 systemd 直接落盘更可靠
开发或调试阶段,想立刻看到 core 文件,最稳的方式是临时禁用 systemd-coredump 管道,改回传统路径模式:
- 执行
echo "/tmp/core.%e.%p" | sudo tee /proc/sys/kernel/core_pattern - 确保
/tmp可写、且进程没用prctl(PR_SET_DUMPABLE, 0)禁用 dump(常见于 setuid 程序) - 注意:
%e是可执行名,%p是 PID,避免覆盖;别用core单名,否则多进程时会冲突 - 该设置重启后失效,如需持久化,需注释掉
/etc/sysctl.d/*中修改core_pattern的行
真正难排查的,往往不是配置漏了哪一项,而是多个机制叠加后行为不可见——比如 socket 启了但 Storage=none,或者 core_pattern 被某个 init 脚本在 boot 后二次覆盖。动手前,先 cat /proc/sys/kernel/core_pattern 和 systemctl status systemd-coredump.socket 看一眼,省掉八成时间。










