温馨提示×

怎样排查linux c++崩溃

小樊
43
2026-09-14 06:43:13
栏目: 编程语言

排查 Linux 下 C++ 程序崩溃(crash / segfault / abort)一般按“先拿到现场 → 再定位代码 → 再分析原因”的流程来。下面是一套比较实用、从入门到进阶的排查方法。


一、先确认崩溃现象

常见崩溃表现:

  • Segmentation fault (core dumped)
  • Aborted (core dumped)
  • 程序直接退出,无日志
  • SIGABRT / SIGSEGV / SIGFPE 杀死

先记录:

echo $?

常见信号:

  • 139 → SIGSEGV
  • 134 → SIGABRT

二、开启并获取 Core Dump(最重要)

1. 开启 core dump

ulimit -c unlimited

确认:

ulimit -c

2. 设置 core 文件位置(可选)

cat /proc/sys/kernel/core_pattern

常见:

core.%e.%p

3. 重新运行程序触发崩溃

./your_program

生成类似:

core.12345

三、用 GDB 分析 Core 文件(核心手段)

1. 基本用法

gdb ./your_program core.12345

2. 查看崩溃位置

bt
bt full
  • bt:调用栈
  • bt full:栈 + 局部变量

3. 查看当前代码

frame 0
list

4. 查看变量

print var
p *ptr

四、编译时必须加调试信息

否则 GDB 看不了源码和变量。

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

推荐(生产也可):

-g -O2

不要:

strip

五、常见崩溃原因 & 快速定位

1. 空指针 / 野指针

int* p = nullptr;
*p = 10;

GDB:

p p

2. 数组越界

int a[10];
a[100] = 1;

建议:

  • std::vector
  • 开 AddressSanitizer

六、使用 Sanitizer(强烈推荐)

AddressSanitizer(内存问题)

g++ -fsanitize=address -g -o app main.cpp
./app

能发现:

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

UndefinedBehaviorSanitizer

-fsanitize=undefined

七、用 valgrind(无重编也可)

valgrind ./app

适合:

  • 内存泄漏
  • 非法访问

缺点:慢


八、捕获信号自己打印栈(生产环境)

#include <execinfo.h>
#include <signal.h>

void handler(int sig) {
    void* bt[100];
    int n = backtrace(bt, 100);
    backtrace_symbols_fd(bt, n, STDERR_FILENO);
    exit(1);
}

signal(SIGSEGV, handler);

九、多线程崩溃排查

  • -pthread
  • GDB:
info threads
thread apply all bt

常见问题:

  • 数据竞争
  • 死锁
  • 对象生命周期错误

可用:

-fsanitize=thread

十、查看系统日志

dmesg | tail

或:

journalctl -xe

十一、最小复现原则

如果崩溃难查:

  1. 写最小例子
  2. 二分注释代码
  3. 用日志缩小范围

十二、推荐排查流程总结

  1. ulimit -c unlimited
  2. 重新运行拿 core
  3. gdb 程序 core
  4. bt full
  5. 无头绪 → ASan / Valgrind
  6. 多线程 → thread sanitizer
  7. 生产 → 信号 + 日志 + core

如果你愿意,可以把:

  • 崩溃信息
  • bt 输出
  • 相关 C++ 代码

发出来,我可以帮你精确定位原因

0