systemd-coredump 默认将完整 core 文件以 zstd 无损压缩存于 /var/lib/systemd/coredump/,完整性取决于 ProcessSizeMax=0、LimitCORE=infinity、Storage=external 及合理 MaxUse=/KeepFree= 设置,而非禁用压缩。

coredump 存储路径和保留策略由 systemd-coredump.conf 控制
默认情况下,systemd-coredump 会将 core 文件写入 /var/lib/systemd/coredump/,并自动压缩(zstd)、限制数量和大小。要保留完整未截断的 core 文件(即不被 ProcessCoreDump 信号处理截断、也不被 ulimit -c 限制),关键不是改压缩行为,而是确保内核生成完整 core,且 systemd 不丢弃或裁剪它。
- 确认内核允许生成完整 core:
sysctl kernel.core_pattern应为|/usr/lib/systemd/systemd-coredump %P %u %g %s %t %c %h %e(即走 systemd-coredump 管道),且kernel.core_pipe_limit未设为 0 - 关闭 ulimit 截断:应用启动前确保
ulimit -c unlimited;若用 systemd service,需在 unit 文件中加LimitCORE=infinity - 检查
/proc/sys/kernel/core_uses_pid是否为 1(避免覆盖,非必需但推荐)
启用 zstd 压缩但保留原始完整内容
systemd-coredump 默认就用 zstd 压缩存储,且压缩是「无损」的——解压后就是原始内存镜像,不会丢失任何字节。所谓“保留完整 core 文件”,本质是确保没被截断、没被过滤、没被提前删除,而不是禁用压缩。
- 压缩行为由
Compress=yes(默认)控制,无需关闭;禁用它反而浪费磁盘空间,且不解决“是否完整”的问题 - 真正影响完整性的是:
Storage=external(存文件系统)+MaxUse=和KeepFree=设置过小会导致旧 core 被删,但不会损坏当前保存的 core - 验证是否完整:用
file /var/lib/systemd/coredump/core.*.zst看是否识别为 “zstd compressed data”;再用zstd -dcq /path/to/core.zst | head -c 128 | hexdump -C检查开头是否含 ELF magic(7f 45 4c 46)
修改 /etc/systemd/coredump.conf 实现长期保留
核心配置项集中在 /etc/systemd/coredump.conf,改完需运行 sudo systemctl kill --signal=SIGUSR2 systemd-coredump 或重启 systemd-coredump.socket 生效(后者更稳妥)。
-
Storage=external:必须设为external(默认),才能落地为文件;none或journal会丢弃原始 core -
MaxUse=2G:调大,例如MaxUse=10G,防止因空间不足触发自动清理 -
KeepFree=5G:留足缓冲,避免磁盘写满导致新 core 写入失败 -
ProcessSizeMax=0:设为 0 表示不限制 core 大小(默认是 2G,超限会被丢弃) -
ExternalCompression=zstd:保持默认即可,zstd 比 gzip 压缩率高、解压快,且coredumpctl debug原生支持
调试时如何还原和使用压缩后的 core
不需要手动解压:所有标准工具(gdb、coredumpctl、eu-stack)都直接支持 .zst 后缀的 core 文件,底层自动调用 zstd 解压流式读取。
- 用
coredumpctl debug your-program直接进 gdb,无需解压 - 用
coredumpctl info your-program查看元数据和路径,路径里显示的就是 .zst 文件 - 若非要解压出来(如给其他工具用):
zstd -dcq /var/lib/systemd/coredump/core.*.zst > core.full,注意确保磁盘空间足够(可能数 GB 到数十 GB) - 常见误操作:把
Compress=no当作“更完整”,其实只是省了压缩步骤,对内容完整性零影响,反而更快占满磁盘导致后续 core 被丢弃
最容易被忽略的是 ProcessSizeMax=0 和 LimitCORE=infinity 的配合——前者管 systemd 层接收上限,后者管内核层生成上限,缺一不可。只调大一个,另一个仍会截断。










