core文件生成需同时满足五项条件:1. core_pattern含%e.%p.%t唯一标识;2. ulimit -c unlimited在应用父进程生效;3. suid程序需suid_dumpable=2;4. 关闭systemd-coredump;5. /var/crash目录权限为1777。

core_pattern 配置必须带 %p 和 %t,否则多进程崩溃会覆盖
默认的 core 命名方式在多线程或多实例场景下极易覆盖,调试时根本分不清哪个 core 对应哪次崩溃。必须用带唯一标识的模板,比如 /var/crash/core.%e.%p.%t。
其中 %e 是程序名,%p 是 PID,%t 是 Unix 时间戳——三者组合基本杜绝重名。别用 %u 或 %g,它们在容器或 suid 场景下可能不可靠。
- 执行
sudo sysctl -w kernel.core_pattern=/var/crash/core.%e.%p.%t临时生效 - 创建目录并设权限:
sudo mkdir -p /var/crash && sudo chmod 1777 /var/crash(注意是1777,不是755) - 确认生效:
cat /proc/sys/kernel/core_pattern输出应与设置一致
ulimit -c unlimited 必须在应用启动前生效,而非仅 shell 中运行
很多开发者只在终端里敲了 ulimit -c unlimited,然后直接跑程序,结果仍没 core 文件——因为应用若由 systemd、supervisord 或 Docker 启动,它继承的是服务管理器的限制,不是你当前 shell 的。
例如 systemd 服务需显式放开:LimitCORE=infinity,否则即使 ulimit 设了 unlimited,systemd 也会强制截断为 0。
- 对 systemd 服务:在
.service文件中加入LimitCORE=infinity,再sudo systemctl daemon-reload - 对 Docker:启动时加
--ulimit core=-1:-1,镜像内不能只靠ulimit命令 - 对普通二进制:确保启动它的父进程(如脚本、init 进程)已设好 ulimit,
ps -o pid,comm,rlimit | grep yourapp可查实际限制
setuid 程序崩溃不生成 core?检查 suid_dumpable 值是否为 2
sudo、passwd、sshd 等 setuid 程序默认禁止生成 core,这是内核安全策略。若你的诊断模块需捕获这类程序崩溃,/proc/sys/fs/suid_dumpable 必须为 2,而非 1 或 0。
2 表示“允许 dump,只要进程未显式关闭 dumpable 标志”,这是最实用的值;1 仅允许 root 用户 dump,0 完全禁用。
- 临时启用:
echo 2 | sudo tee /proc/sys/fs/suid_dumpable - 永久生效:向
/etc/sysctl.conf追加fs.suid_dumpable = 2,再运行sudo sysctl -p - 验证:
cat /proc/sys/fs/suid_dumpable输出应为2
systemd-coredump 不是替代项,而是干扰源,该关就关
systemd-coredump 默认接管所有 core 文件,把它们压缩存进 /var/lib/systemd/coredump/,并改名、加元数据。这对自动化诊断模块是灾难——路径不可控、文件名不一致、解压步骤额外增加。
如果你的应用诊断模块要自己解析 core、上传、关联符号表,systemd-coredump 就是多余中间层,且容易和自定义 core_pattern 冲突。
- 停用:
sudo systemctl stop systemd-coredump.socket && sudo systemctl disable systemd-coredump.socket - 屏蔽(推荐):
sudo systemctl mask systemd-coredump.socket - 确认未运行:
systemctl is-active systemd-coredump.socket应返回inactive
真正麻烦的不是配置本身,而是各层级限制叠加:shell ulimit、systemd Limit、内核 suid_dumpable、core_pattern 路径权限、磁盘空间、SELinux 上下文——漏掉任意一环,core 就静默消失。建议每次部署后,用最小 segv 程序实测,别只看配置是否写入。











