Catch(…)没有捕获异常,我的程序仍然崩溃



我有一个测试程序的问题,我的应用程序在初始化时崩溃。我添加了更多的日志记录和异常处理,但它仍然崩溃与通用的"这个程序已经停止工作"的消息,而不是触发我的错误处理。

给定我的main()看起来像这样,并且在什么情况下不会触发catch(...) ?

try{
    simed::CArmApp app(0, cmd);
    for(bool done = false;!done;) 
    {
        done = !app.frame();
    }
} catch(const std::runtime_error &e){
    handleApplicationError(e.what());
    return -1;
} catch(...) {
    handleApplicationError("Unknown Error");
    return -999;
}

我的代码调用到一个库做OpenGL渲染,这是我认为事情是错误的。

如果c++ catch(...)块没有捕获错误,可能是因为Windows错误。

在Windows上有一个叫做结构化异常处理的概念,它是操作系统引发"异常"的地方。当不好的事情发生时,比如对一个无效的指针解引用,除以零等。我说"例外";因为这些不是c++异常;相反,这些是Windows用C风格定义的严重错误——这是因为Win32是用C编写的,所以c++异常是不可行的。

参见:

    c++异常与结构化异常的区别<
  • try-except声明/gh>从EXCEPTION_POINTERS结构体获取堆栈跟踪的方法

基于注释更新

如果你想要c++异常处理和SEH,也许你可以尝试以下(未经测试的)代码:

__try
{
    try
    {
        // Your code here...
    }
    catch (std::exception& e)
    {
        // C++ exception handling
    }
}
__except(HandleStructuredException())
{
    // SEH handling 
}

如果对象的析构函数抛出异常,该对象由于堆栈展开以处理不同的异常而被销毁,则程序将退出,无论是否为catch(...)

据我所知,至少有两种情况catch(...)实际上不能捕获

  1. 多于1个未处理的异常:当一个异常在先前发生的异常被处理之前被引发时,那么c++无法处理它,并且应用程序将崩溃。
  2. 抛出不在异常说明列表中的异常:如果任何方法抛出不在异常说明列表中的异常(在任何中),则将调用unexpected并调用abort

是否声明任何全局对象?如果你在主循环之外创建了任何对象,这就可以解释为什么它没有被捕获(它不在你的try-catch中)。

如果您正在使用多线程并且抛出异常,提示线程的析构函数,则可能会忽略异常并调用abort。std::jthread (c++ 20)解决了这个问题,但是如果你不能访问c++ 20,那么你将需要一个清理函数/lambda来在抛出异常之前终止线程。

最新更新