ulimit -c unlimited 不能单独保证生成 core 文件,还需确保 core_pattern 路径有效可写、core_uses_pid 配置合理、进程有写权限,且 suid_dumpable 等内核限制未阻止。

ulimit -c unlimited 真的能生成 core 文件吗?
不一定。它只解除 shell 当前会话的 core 文件大小限制,但真正能否生成 core 还取决于三个独立开关是否全开:/proc/sys/kernel/core_pattern 是否指向有效路径、/proc/sys/kernel/core_uses_pid 是否影响命名冲突、以及进程是否有写入目标目录的权限。
常见错误现象:kill -SEGV $$ 后没看到 core 文件,dmesg 却提示 "Failed to write core file" —— 大概率是目标路径不存在或不可写,而非 ulimit 没生效。
-
ulimit -c unlimited必须在启动目标进程前执行,子 shell 或后台任务需显式继承 - 若用
systemd启动服务,ulimit无效,得改LimitCORE=infinity在 service 文件里 - 容器环境(如 Docker)默认禁用 core dump,需加
--ulimit core=-1:-1并挂载可写目录
/proc/sys/kernel/core_pattern 决定 core 文件去哪、叫什么
这个内核参数直接控制 core 文件的存储位置和命名格式,优先级远高于当前工作目录。默认值通常是 core,意味着“当前进程 cwd 下写一个叫 core 的文件”,但一旦被改成带路径或管道形式(如 |/usr/share/apport/apport %p %s %c %d %P),行为就完全不同。
使用场景:调试生产服务时,常设为 /var/crash/core.%e.%p.%t,其中 %e 是程序名、%p 是 PID、%t 是时间戳,避免覆盖,也方便归类。
- 路径必须提前创建且可写,内核不会自动
mkdir;例如设成/var/crash/core.%p,就得先mkdir -m 1777 /var/crash - 若
core_pattern以|开头,表示把 core 数据喂给指定程序处理(如 apport、systemd-coredump),此时不落地为文件 - 修改后无需重启,直接
echo '/tmp/core.%e.%p' > /proc/sys/kernel/core_pattern即刻生效
为什么设置了 ulimit 和 core_pattern,core 还是没权限写?
Linux 对 core dump 有额外权限限制:即使进程有写权限,若启用了 fs.suid_dumpable = 0(默认值),任何 setuid/setgid 程序都不会生成 core;若进程运行在 chroot 或 user namespace 中,目标路径可能根本不可见。
性能 / 兼容性影响:开启 core dump 本身不拖慢正常运行,但崩溃瞬间若目标磁盘满或 IO 堵塞,进程会卡在 exit 阶段几秒甚至更久 —— 这在高可用服务里很危险。
- 检查 suid dump 设置:
cat /proc/sys/fs/suid_dumpable,临时放开用echo 2 > /proc/sys/fs/suid_dumpable - 确认进程实际运行目录:
readlink /proc/<pid>/cwd</pid>,别只信你cd到的地方 - SELinux 或 AppArmor 可能拦截写入,查
ausearch -m avc -ts recent | grep core或dmesg | grep avc
core 文件太大,怎么限制单次大小又不完全禁用?
用 ulimit -c N(N 单位是 KB)比 unlimited 更可控。比如 ulimit -c 1048576 限制为 1GB,既保留调试价值,又防磁盘打爆。
注意:这个限制作用于每个进程单独的 core 文件,不是全局总和;而且它只管“文件大小上限”,不管内存占用 —— 进程崩溃时仍会尝试 dump 全量地址空间,只是超出部分被截断。
- 数值必须是 1024 的整数倍,否则会被向下取整(如
ulimit -c 1000实际生效为 0) - 某些老内核(
- 若用
core_pattern指向管道处理器(如 systemd-coredump),ulimit -c仍有效,但处理器自身可能有二次限制
真正麻烦的是多层隔离环境:容器 + systemd + SELinux + 自定义 core_pattern,任意一层关掉都会静默失败。调的时候别只盯 ulimit,先 cat /proc/<pid>/limits</pid> 看进程实际限制,再顺藤摸到 /proc/sys/kernel/core_pattern 和 dmesg 输出,漏掉哪一环都白忙。










