ulimit -c unlimited 仅解除大小限制,能否生成 core 还取决于 core_pattern 路径是否有效可写、core_uses_pid 配置合理、进程有写权限,以及 suid_dumpable 等内核限制未阻止。

为什么程序没生成 core 文件,明明设置了 ulimit -c unlimited?
最常见的情况是:系统默认禁用 core dump,或者进程在非预期目录下写入了 core 文件但被权限或路径问题拦截。Linux 内核通过 /proc/sys/kernel/core_pattern 控制 core 文件的生成位置和命名规则,而不仅仅是靠 ulimit -c 开关。如果该文件内容是 |/usr/share/apport/apport %p %s %c %d %P %E(Ubuntu 默认),那 core 不会落地为文件,而是交给 apport 处理——此时你看不到 core 或 core.xxx 文件。
- 先检查真实生效的限制:
ulimit -c(当前 shell 会话)和cat /proc/<pid>/limits | grep core</pid>(对已运行进程) - 确认内核策略:
cat /proc/sys/kernel/core_pattern;若以|开头,说明被管道接管,需改回普通路径(如/tmp/core.%e.%p)并确保目录可写 - 注意:systemd 服务默认忽略
ulimit,需在 service 文件中显式设置LimitCORE=infinity
如何让特定 C++ 程序一定生成 core 并能被 gdb 正确加载?
关键不是“让程序崩溃”,而是确保崩溃时环境满足 core 生成条件,且生成的 core 包含足够调试信息。编译时未加调试符号、strip 过二进制、或链接了某些库(如 musl)都可能导致 gdb 加载失败或无法显示源码行。
- 编译必须带
-g,避免使用-s或strip处理最终可执行文件 - 验证调试信息存在:
file your_program应含with debug_info;readelf -S your_program | grep debug应有多个.debug_*段 - 触发崩溃建议用明确信号:
kill -SIGSEGV $(pidof your_program),比野指针更可控;也可在代码中调用raise(SIGSEGV) - 生成后用
gdb your_program /tmp/core.your_program.12345验证是否可读——若提示No symbol table info available,基本是编译或 strip 问题
core 文件太大或生成太慢,能限制大小或加速写入吗?
core 文件默认包含进程全部虚拟内存映像(包括堆、共享库、mmap 区域等),动辄数 GB。实际调试往往只需栈和可执行段,没必要全量保存。Linux 提供 /proc/sys/kernel/core_uses_pid 和 coredump_filter 两个机制控制内容范围。
-
echo 1 > /proc/sys/kernel/core_uses_pid让文件名自动附加 PID,避免覆盖 - 更有效的是设置
/proc/<pid>/coredump_filter</pid>(十六进制掩码):例如echo 0x7 > /proc/$(pidof your_program)/coredump_filter只保留私有匿名映射、ELF 文件和堆(跳过共享库、VVAR/VDSO 等),体积通常减少 50%~90% - 注意:该值需在进程启动前设置(可通过
prctl(PR_SET_DUMPABLE, 1)启用),且子进程默认继承父进程的 filter 值 - 磁盘 I/O 是主要瓶颈,把
core_pattern指向 tmpfs(如/dev/shm/core.%e.%p)可显著加快写入速度
容器里跑的 C++ 程序为啥死活不生成 core?
容器默认以 docker run --ulimit core=-1:-1 启动时,ulimit -c 看似生效,但内核 namespace 隔离导致 /proc/sys/kernel/core_pattern 仍沿用宿主机值(常为 |apport),且容器 rootfs 通常无权写宿主机路径。另外,runc 默认将 RLIMIT_CORE 设为 0。
- 启动容器时必须显式启用:
docker run --ulimit core=-1:-1 --cap-add=SYS_ADMIN ...(部分场景需要 CAP) - 挂载自定义
core_pattern:docker run -v /host/coredir:/coredir ... bash -c "echo '/coredir/core.%e.%p' > /proc/sys/kernel/core_pattern" - 推荐方式:在容器 entrypoint 中第一行执行
echo '/tmp/core.%e.%p' > /proc/sys/kernel/core_pattern && ulimit -c unlimited,并确保/tmp可写 - Kubernetes 用户注意:
securityContext: { privileged: true }通常不必要,但需设置runAsUser: 0且 PodSecurityPolicy 允许allowedUnsafeSysctls: ["kernel.core_pattern"]
/proc/<pid>/status</pid> 的 CapBnd 和 Seccomp,比反复改代码更容易定位问题。C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











