Linux生成core文件需同时满足ulimit -c unlimited、core_pattern路径存在且权限为1777、fs.suid_dumpable=2(setuid程序)、systemd服务配置LimitCORE=infinity,缺一不可。

Linux默认不生成core文件,不是系统坏了,而是它被层层关掉了——ulimit -c设为0、/proc/sys/kernel/core_pattern指向无效路径、目录权限不对、systemd服务没配LimitCORE,甚至setuid程序还被fs.suid_dumpable拦着。得一层层打开,缺一不可。
ulimit -c unlimited 只对当前 shell 有效
这是第一道关卡,也是最容易忽略的:即使内核允许 dump,进程自己没权限写也不行。ulimit -c输出0表示禁用;输出unlimited或具体数字(单位是512字节块)才表示可用。
- 临时生效:在目标终端中运行
ulimit -c unlimited;但只对当前 shell 及其直接子进程有效 - 永久生效:加到用户级配置(如
~/.bashrc)或系统级配置(/etc/security/limits.conf中写* soft core unlimited和* hard core unlimited),注意后者需重新登录 - 关键点:
systemd服务完全不继承 shell 的ulimit,必须单独在 unit 文件里加LimitCORE=infinity
/proc/sys/kernel/core_pattern 路径必须存在且权限为 1777
core_pattern决定内核将core数据写入何处及如何命名。若路径含目录层级(如/var/crash/),内核绝不会自动创建父目录,且要求目标目录权限必须为1777(sticky bit + full rwx),否则拒绝写入。
- 查看当前设置:
cat /proc/sys/kernel/core_pattern;默认可能是core,意味着只写在进程工作目录,极易被覆盖或找不到 - 临时改写到
/tmp/core.%e.%p.%t:echo '/tmp/core.%e.%p.%t' | sudo tee /proc/sys/kernel/core_pattern - 必须提前建好目录并设权限:
sudo mkdir -p /tmp/coredumps && sudo chmod 1777 /tmp/coredumps;777不够,必须是1777 - 永久生效:写入
/etc/sysctl.conf,如kernel.core_pattern=/var/crash/core.%e.%p.%t,再执行sudo sysctl -p - 若值以
|开头(如|/usr/lib/systemd/systemd-coredump),说明走用户态处理器,要确认systemd-coredump服务已启用且运行正常
setuid 程序需要 fs.suid_dumpable=2
普通程序可能 dump 成功,但sudo、passwd这类setuid程序却静默失败——问题常出在这两个内核开关上。
- 检查当前值:
cat /proc/sys/fs/suid_dumpable;默认很多发行版(如 RHEL/CentOS 8+)是0 - 临时启用:
sudo sysctl -w fs.suid_dumpable=2(2表示允许所有setuid程序生成 core) - 永久生效:在
/etc/sysctl.conf中添加fs.suid_dumpable=2,再sudo sysctl -p - 顺带检查
/proc/sys/kernel/core_uses_pid:设为1会在文件名末尾加.PID,避免多进程同名覆盖,但调试时容易漏看
systemd 服务必须显式配置 LimitCORE
systemd管理的服务完全忽略/etc/security/limits.conf和 shell ulimit,其资源限制由 unit 文件中的Limit*指令控制。若服务崩溃无 core,极大概率是此环节缺失。
- 定位服务 unit 文件:
systemctl cat <service-name></service-name>或检查/etc/systemd/system/或/usr/lib/systemd/system/ - 编辑 unit 文件,在
[Service]段下添加:LimitCORE=infinity - 重载配置:
sudo systemctl daemon-reload,然后重启服务:sudo systemctl restart <service-name></service-name> - 验证是否生效:
systemctl show <service-name> | grep LimitCORE</service-name>,应显示LimitCORE=18446744073709551615(即 infinity)
真正麻烦的从来不是单点配置,而是多个环节的权限叠加效应:比如你改了core_pattern到/var/crash,但忘了chmod 1777;又或者给systemd服务加了LimitCORE,却没调fs.suid_dumpable,结果sudo ./crashy还是静默失败。每个环节都得独立验证,不能靠“应该可以”来推进。


















