You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

未捕获异常触发SIGSEGV而非SIGABRT的原因问询

问题分析:未捕获异常导致SIGSEGV而非SIGABRT

代码示例

#include <iostream>
#include <stdexcept>

class Test {
public:
    Test() { std::cout << "Constructor called" << std::endl; }
    ~Test() { std::cout << "Destructor called" << std::endl; }
};

int main() {
    Test obj1;

    try 
    {
        Test obj2;
        throw std::runtime_error("Exception thrown"); 
    } // Object 2 is destroyed here
    catch (...)
    {
        throw; // std::abort
    }
} // not reached (implementation defined), Object 1 destructor never called

核心疑惑

已知obj2的析构会被执行(栈展开行为),但为何在Linux平台上程序最终以SIGSEGV信号终止,而非预期的SIGABRT?

解答

  • 标准规则基础:当异常传播到main()函数之外时,C++标准规定必须调用std::terminate(),它的默认处理函数是std::abort(),而std::abort()的标准行为是向进程发送SIGABRT信号。
  • Glibc的特殊实现逻辑:在GCC搭配Glibc的Linux环境中,如果std::terminate()是因为栈展开过程中出现未处理的异常(即“双重异常”场景——在处理一个异常的流程里,又抛出了另一个未被捕获的异常),Glibc会跳过常规的std::abort()流程,直接触发SIGSEGV信号终止进程。这是因为此时程序的栈状态可能已经处于混乱状态,执行abort()的常规步骤(比如生成core dump、打印错误信息)可能引发更多问题,不如直接强制终止。
  • 对应代码场景:catch块重新抛出的异常没有被任何上层catch捕获,此时程序刚完成obj2的析构,正处于栈展开的中间阶段。Glibc识别到这是异常处理流程中再次出现未捕获异常的情况,因此触发SIGSEGV而非预期的SIGABRT。

内容的提问来源于stack exchange,提问作者Superlokkus

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 19:04:49