C++怎么生成core dump_C++故障排查教程【诊断】

4次阅读

core dump未生成主因是三项配置未调优:ulimit -c 非零、/proc/sys/kernel/core_pattern 路径有效且可写、运行目录有写权限及磁盘空间充足;systemd服务需显式设limitcore=infinity。

C++怎么生成core dump_C++故障排查教程【诊断】

core dump 为什么没生成?检查这三项配置

linuxc++ 程序崩溃不产生 core 文件,90% 是因为系统级限制没放开。不是代码问题,是环境没配对。

  • ulimit -c 必须设为非零值(如 ulimit -c unlimited),否则内核直接丢弃 core;临时生效,建议加到 ~/.bashrc 或启动脚本里
  • /proc/sys/kernel/core_pattern 决定 core 文件写哪——默认可能指向 pipe 或空路径;用 cat /proc/sys/kernel/core_pattern 看一眼,想存当前目录就设成 ./core.%e.%p
  • 程序运行目录需有写权限,且磁盘不能满;如果用 systemd 启动,它会重置 ulimit,得在 service 文件里显式加 LimitCORE=infinity

gdb 加载 core dump 的正确姿势

光有 core 文件不够,gdb 必须用**编译时的原始可执行文件**加载,否则符号全丢,全是 ??

  • 确认可执行文件没被 strip 过:file ./myapp 输出里含 not stripped 才行;若已 strip,只能靠带调试信息的版本(如 myapp.debug)配合 set debug-file-Directory
  • 加载命令就是 gdb ./myapp core.12345,别漏掉可执行文件路径;进 gdb 后立刻输 bt,看第一帧是不是你的函数
  • 如果 bt 显示 no stack 或地址乱跳,大概率是 ASLR 干扰——临时关掉:echo 0 | sudo tee /proc/sys/kernel/randomize_va_space(仅调试用)

signal(SIGSEGV, handler) 会阻止 core dump 吗?

会,但只在 handler 里没调 abort()raise(SIGSEGV) 时才真阻止。默认行为被覆盖后,得手动补上。

  • 注册自定义信号处理函数后,内核不再自动产生 core,除非你在 handler 里显式调用 abort()raise(SIGABRT)exit(128 + SIGSEGV)
  • 更稳妥的做法:handler 里记录日志 + 调 signal(SIGSEGV, SIG_DFL)raise(SIGSEGV),把控制权交还给默认行为
  • 注意:sigactionsignal 更可靠,尤其涉及 SA_RESETHANDSA_NODEFER 标志位时

core dump 太大?按需裁剪而不是关掉

动不动几个 GB 的 core 不是必须接受的,Linux 提供了精细控制,关键在 /proc/[pid]/coredump_filter

立即学习C++免费学习笔记(深入)”;

  • 默认值 0x33 包含私有匿名映射和 ELF 文件映射,通常就足够定位问题;若只想保留堆栈和寄存器,设成 0x01(仅私有匿名区)
  • 修改方式:echo 0x01 > /proc/self/coredump_filter(进程启动前)或写入对应 pid 目录(需权限)
  • 注意:此设置只影响后续生成的 core,不影响已存在的;容器环境可能被 seccomp 或 cgroup 限制,得检查 docker run --ulimit core=-1:-1

真正麻烦的是线程下信号触发时机和栈帧错位,这时候 core 里看到的不是崩溃点,而是 signal delivery 的中间状态——得结合 info Threadsthread apply all bt 全局看。

text=ZqhQzanResources