在 Linux 下使用 C++ 捕获异常,通常使用的是 C++ 标准异常机制(try / catch),而不是 Linux 系统调用层面的信号(虽然信号也能“捕获”,但那是另一回事)。
下面分几个层次说明。
#include <iostream>
#include <stdexcept>
int main() {
try {
throw std::runtime_error("something wrong");
}
catch (const std::exception& e) {
std::cerr << "Caught exception: " << e.what() << std::endl;
}
catch (...) {
std::cerr << "Unknown exception" << std::endl;
}
return 0;
}
| 异常类型 | 说明 |
|---|---|
std::exception |
所有标准异常的基类 |
std::runtime_error |
运行时错误 |
std::logic_error |
逻辑错误 |
std::out_of_range |
越界 |
std::bad_alloc |
内存分配失败 |
示例:
throw std::out_of_range("index too big");
#include <exception>
#include <string>
class MyException : public std::exception {
public:
explicit MyException(const std::string& msg) : msg_(msg) {}
const char* what() const noexcept override {
return msg_.c_str();
}
private:
std::string msg_;
};
使用:
throw MyException("custom error");
catch (...) {
// 不知道是什么异常,但不让程序直接崩
}
⚠️ 建议:
例如:
int* p = nullptr;
*p = 1; // SIGSEGV
❌ 无法用 try/catch 捕获
#include <signal.h>
#include <iostream>
void handler(int sig) {
std::cerr << "Received signal: " << sig << std::endl;
exit(1);
}
int main() {
signal(SIGSEGV, handler);
}
常见信号:
| 信号 | 含义 |
|---|---|
| SIGSEGV | 段错误 |
| SIGABRT | abort |
| SIGFPE | 浮点异常 |
| SIGINT | Ctrl+C |
⚠️ 信号处理函数里 不能抛 C++ 异常
| 特性 | C++ 异常 | Linux 信号 |
|---|---|---|
| 可捕获 | ✅ | ⚠️(部分) |
| 可控 | ✅ | ❌ |
| 用于逻辑错误 | ✅ | ❌ |
| 用于崩溃 | ❌ | ✅ |
使用 GCC / Clang:
g++ main.cpp -o main
默认就支持异常
若关闭异常(不推荐):
g++ -fno-exceptions main.cpp
✅ 使用 try/catch 处理可预期错误
✅ 在最外层 catch (...)
✅ 记录日志
❌ 不要用异常代替普通返回值
❌ 不要在析构函数中抛异常
如果你愿意,我可以:
你更想了解哪一块?