core dump 未生成的 kernel.core_pattern 与 systemd-coredump socket

9次阅读

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

core dump 未生成的 kernel.core_pattern 与 systemd-coredump socket

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)可写;若挂载了 noexecnodev,部分版本会静默失败
  • 测试方法:手动触发 dump(如 kill -SEGV $$),再查 coredumpctl listjournalctl -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_patternsystemctl status systemd-coredump.socket 看一眼,省掉八成时间。

text=ZqhQzanResources