温馨提示×

Linux C++为何异常

小樊
43
2026-07-31 20:06:04
栏目: 编程语言

在 Linux 下用 C++ 程序出现异常,原因很多,不能一概而论。下面按最常见 → 较少见的顺序,系统性地给你梳理一下,并给出排查方法


一、最常见原因(90% 的异常都在这)

1️⃣ 段错误(Segmentation Fault)

这是 Linux 下 C++ 最常见的“异常”。

典型原因:

  • 访问空指针 / 野指针
  • 数组越界
  • 栈溢出
  • 使用已释放的内存(double free / use-after-free)

示例:

int* p = nullptr;
*p = 10;  // 段错误

排查方法:

gdb ./your_program
run
bt

或:

ulimit -c unlimited
./your_program
gdb ./your_program core

2️⃣ 未捕获的 C++ 异常(throw 但没有 catch)

#include <stdexcept>

void foo() {
    throw std::runtime_error("error");
}

int main() {
    foo();  // 没有 catch
}

现象:

terminate called after throwing an instance of 'std::runtime_error'
Aborted (core dumped)

解决:

try {
    foo();
} catch (const std::exception& e) {
    std::cerr << e.what() << std::endl;
}

3️⃣ 内存越界 / 堆破坏

int* a = new int[10];
a[10] = 1;  // 越界

特点:

  • 不一定立刻崩溃
  • 可能在别的地方莫名其妙崩

排查工具:

valgrind ./your_program

二、Linux 特有原因

4️⃣ 动态库问题(ABI / 版本不匹配)

  • glibc 版本不一致
  • C++ ABI 不兼容(gcc 版本不同)
  • 动态库加载失败

现象:

symbol lookup error
undefined symbol
version `GLIBCXX_3.4.20' not found

检查:

ldd ./your_program
nm ./your_program | grep symbol

5️⃣ 多线程问题

  • 数据竞争(race condition)
  • 死锁
  • 在信号中调用不可重入函数

示例:

std::cout << "hello" << std::endl; // 多线程下可能崩

排查:

gdb ./a.out
thread apply all bt

三、编译器 / 系统相关

6️⃣ 编译器优化导致“看起来异常”

  • -O2 / -O3 下未定义行为会被放大
  • 局部变量被优化掉

建议:

g++ -g -O0 -Wall -Wextra

7️⃣ 信号导致的“异常”

Linux 中很多“异常”其实是 信号

信号 含义
SIGSEGV 段错误
SIGABRT abort()
SIGFPE 除 0
SIGPIPE 写已关闭的 socket
SIGBUS 总线错误

示例:

int a = 1 / 0;  // SIGFPE

四、常见“看起来像异常,其实不是”

❌ 程序直接退出

  • exit()
  • _exit()
  • assert() 失败
assert(ptr != nullptr);

五、快速定位异常的方法(强烈推荐)

✅ 1. 用 gdb

gdb ./your_program
run
bt

✅ 2. 打开 core dump

ulimit -c unlimited

✅ 3. 开启所有警告

-Wall -Wextra -Werror

✅ 4. 用 sanitizer(非常强)

g++ -fsanitize=address -g main.cpp

六、如果你愿意,我可以进一步帮你

你可以直接贴:

  1. 异常信息原文
  2. 崩溃时的 backtrace
  3. 相关代码片段
  4. Linux 发行版 + gcc 版本

我可以帮你精确定位是哪一行代码导致的异常

0