温馨提示×

如何排查linux c++崩溃

小樊
61
2026-10-02 03:21:38
栏目: 编程语言

排查 Linux 下 C++ 程序崩溃,通常遵循“采集现场 → 定位崩溃点 → 分析原因 → 修复验证”的流程。下面按实战顺序给你一套可落地的方案。


一、先确认崩溃现象

  1. 查看退出信号
echo $?

常见信号:

  • 139 → SIGSEGV(段错误)
  • 134 → SIGABRT(assert / abort)
  • 132 → SIGILL(非法指令)
  • 136 → SIGFPE(除零等)
  1. 是否生成 core 文件
ls -l core*
ulimit -c

若为 0,先开启:

ulimit -c unlimited

二、用 core dump 定位崩溃位置(最常用)

1. 编译时加调试信息

g++ -g -O0 -o app app.cpp

2. 崩溃后分析 core

gdb ./app core

常用命令:

bt            # 查看调用栈
bt full       # 查看局部变量
frame 3       # 切换到第3层栈
info locals   # 当前函数变量
p ptr         # 打印变量

✅ 这是最快定位崩溃行的方式。


三、如果没有 core 文件

方法 1:直接用 gdb 运行

gdb ./app
run

崩溃时 gdb 会停住。


方法 2:catch 信号

handle SIGSEGV stop print
run

四、常见崩溃原因 & 排查点

1. 段错误(SIGSEGV)

最常见原因:

  • 空指针解引用
  • 数组越界
  • 使用已 free 的内存(野指针)
  • 多线程竞争

✅ 重点检查:

ptr->xxx
arr[i]
std::vector / map 越界

2. 栈溢出

void f() { f(); }  // 无限递归

✅ 检查:

  • 大对象在栈上
  • 递归深度

3. 多线程问题

  • 未加锁访问共享变量
  • 死锁
  • 线程中使用已销毁对象

✅ 工具:

helgrind
tsan
g++ -fsanitize=thread -g app.cpp

五、使用 Sanitizer(强烈推荐)

AddressSanitizer(内存问题)

g++ -fsanitize=address -g -O1 app.cpp
./a.out

能精准报:

  • 越界
  • use-after-free
  • 内存泄漏

UndefinedBehaviorSanitizer

-fsanitize=undefined

六、日志 & 防御式编程

  1. 关键路径打日志
std::cerr << "before call, ptr=" << ptr << std::endl;
  1. 崩溃前自动打印栈
#include <execinfo.h>

或在 main 中:

signal(SIGSEGV, handler);

七、系统级辅助工具

  • dmesg | tail → 看内核记录
  • strace ./app → 系统调用
  • valgrind ./app → 内存分析(慢但强)

八、典型排查流程总结

1. 加 -g 编译
2. 开 core
3. gdb bt
4. 看变量 / 栈
5. asan 验证
6. 修复 + 单测

如果你愿意,可以把:

  • 崩溃信息(bt 输出)
  • 相关代码片段

发出来,我可以直接帮你定位问题。

0 踩