ulimit -c 是控制 core 文件生成与否及大小的唯一决定因素,内核严格检查该值;/proc/sys/kernel/core_pattern 仅影响存储路径和文件名,systemd-coredump 仍受其约束但有额外限制。

ulimit -c 是控制 core 大小的唯一入口
Linux 中,程序崩溃时能否生成 core 文件、生成多大,**只由 ulimit -c 决定**——不是 /proc/sys/kernel/core_pattern,也不是 systemd-coredump 配置,更不是编译选项。它是一个 shell 级资源限制,内核在写 core 时会严格检查这个值。
常见错误现象:segmentation fault (core dumped) 提示出现了,但当前目录下没 core 文件;或者只生成了几十 KB 的残缺文件。
-
ulimit -c 0:彻底禁用 core 生成(默认值,很多发行版开箱即禁) -
ulimit -c unlimited:允许写入任意大小(注意:不是“不限制”,而是“无硬上限”,仍受磁盘空间和内存可用性制约) -
ulimit -c 102400:限制为 100MB(单位是 512 字节块,100*1024*1024/512 = 204800,别手算错)
/etc/security/limits.conf 的 soft/hard 区别很关键
临时执行 ulimit -c unlimited 只对当前终端及其子进程有效,关掉就失效。要让服务或用户长期生效,必须改 /etc/security/limits.conf ——但这里有两个坑:
-
soft core是用户自己能调高的上限,比如普通用户可运行ulimit -c 50000,但不能超 soft 值 -
hard core是系统强制封顶值,用户无法自行突破,必须 root 修改 - 如果只设了
soft没设hard,某些 PAM 配置下 soft 会被忽略;反之,只设hard不设soft,用户连ulimit -c都看不到值
正确写法(对所有用户):* soft core unlimited* hard core unlimited
改完需重新登录(SSH 重连、GUI 重启会话),systemd 服务则需 sudo systemctl daemon-reload && sudo systemctl restart xxx 才能继承新 limits。
core_pattern 不影响大小,但会影响你找不找得到文件
/proc/sys/kernel/core_pattern 完全不管“能不能写”或“写多大”,它只管“写到哪、叫什么”。很多人配了 /var/crash/core-%e-%p-%t 却找不到文件,第一反应是路径错了——其实更可能是 ulimit -c 还是 0。
- 临时生效:
echo '/tmp/core.%e.%p' | sudo tee /proc/sys/kernel/core_pattern - 永久生效:写入
/etc/sysctl.conf的kernel.core_pattern=...行,再sudo sysctl -p - 务必确认目标目录存在且可写:
sudo mkdir -p /tmp/coredumps && sudo chmod 1777 /tmp/coredumps(1777防止跨用户覆盖)
注意:%t 是 Unix 时间戳秒数,不是可读时间;%e 是 argv[0],若程序用 execve 启动且未设 argv[0],可能为空或显示为 unknown。
systemd-coredump 会绕过 ulimit -c?不,但它有独立开关
在 Ubuntu 22.04+/Fedora/RHEL 8+ 等 systemd 发行版中,systemd-coredump 默认接管了 core 捕获。它**仍然尊重 ulimit -c**,但额外加了一层控制:/etc/systemd/coredump.conf 中的 ProcessSizeMax= 和 ExternalSizeMax=。
-
ProcessSizeMax=:限制单个进程 core 的大小(单位支持1G、500M),默认2G -
ExternalSizeMax=:限制外部存储(如/var/lib/systemd/coredump)总容量,默认2G - 即使
ulimit -c unlimited,若ProcessSizeMax=100M,照样截断
验证是否启用:systemctl is-active systemd-coredump;查看日志:coredumpctl list 或 journalctl -u systemd-coredump。它不生成传统 core 文件,而是存为压缩的 .core,用 coredumpctl dump -o mycore core 导出再用 gdb 分析。
真正容易被忽略的是:systemd 服务默认以 LimitCORE=0 启动(即无视全局 ulimit),必须在 service 文件里显式写 LimitCORE=infinity 才行。这点比普通进程更隐蔽。

















