使用catch (...)无法捕获C++异常

14
我有一个第三方库有时会抛出异常。因此,我决定用try/catch(...)将我的代码包装起来,以便记录有关发生异常的信息(没有具体细节,只是发生了异常)。
但是由于某种原因,代码仍然崩溃。在客户端计算机上,它会严重崩溃,并且在catch(...)中记录异常的代码永远不会被执行。如果我在调试/开发机器上运行此代码,我会得到弹出窗口询问我是否要调试。当我这样做时,它会报告0xC0000005:访问位置XXX时违反访问权限。
奇怪的是,对于旧版本的第三方库,完全相同的代码确实会捕获异常,并记录异常的代码也会执行。(我在VS中观察相同条件的发生来验证了这一点。)
以下是正在执行的伪代码:
pObject = pSystem->Get_pObject()
pSystem->DoSomethingThatMightDestroy_pObject();
try
{
    /*   Call to third party function that is throwing exception */
    pObject->SetValue(0);
}
catch (...)
{
    __DEBUG_LOG_POSITION__;  // A macro to log the current file line
    //  This code used to run in the older version of third-party library
    //  but the newer version just crashes before running the catch(...)
}

所以我有两个问题:

  1. 第三方是否以某种方式编译了库,导致我的代码无法捕获异常?(如果我知道该告诉他们什么,有机会让第三方进行必要的修复和重新编译)

  2. 假设我无法让第三方进行修复,我该怎么做才能捕获这些异常? 我在考虑... 是否有办法确定 pObject 是否已被释放?

4个回答

12

哇,这篇文章真的非常有用,而且对我来说确实包含了可行的解决方案...旧库必须在VS2003下构建,而新库则是为VS2008设计的——这是关键的区别。将我的库设置为使用编译选项“启用C++异常:使用SEH异常(/EHa)”,现在我的代码可以捕获此实例。因此,我将把这个回答评为正确答案。不过,我想说其他几个答案也提供了有效的有用信息,特别是关于“继续下去没有什么用”的那个答案...所以感谢大家!! - Michael Bray
5
使用 C++ 的 try/catch 捕获 SEH 异常通常不是一个好主意。这就是为什么微软在他们的新编译器中默认禁用了它的原因。一般来说,你应该使用 SEH 结构(例如 __try/__except),而不是启用编译器选项来处理 SEH 异常。 - jalf
Michael Bray> 没问题,我想这里有很多答案可以帮助解决这种问题。我也会投票给其他答案,让它们排在这个答案的下面。jalf> 确实如此。这就是文章中所做的。 - Klaim

8

访问冲突不是C++异常,而是Windows结构化异常。如果您想在catch(...)中捕获它们,您将需要使用_set_se_translator()。

您应该谷歌一下所有原因,了解catch(...)的弊端,并确保您真的想这样做。


这是一些很好的信息... 但在我的情况下,看起来我必须在main()函数中使用_set_se_translator()(至少根据sharptooth引用的文章中的示例)... 我没有提到的一件事是,我的代码实际上是由另一个应用程序(事实上是第三方应用程序)加载的com对象,我无法控制正在使用的main()。否则,我认为这将是最佳选择。 - Michael Bray
哎呀,我的意思是Klaim的文章中提到的引用。对不起! - Michael Bray

1

如果你在Windows平台上,可以尝试查看__try。

然而,请注意,除非你确信能够隔离和处理异常,否则继续执行没有太大的用处。


0

你所描述的情况非常像是 C++ 运行时调用了 ::terminate()。

这通常是由所谓的 双重异常 引起的 - 在某个地方抛出了异常,堆栈展开开始,在堆栈展开期间调用的某个析构函数也抛出了异常。在这种情况下,将调用 ::terminate(),你无法真正帮助程序。

如果是这种情况,唯一的解决方法是获取一个新版本的库,在其中不会让异常从析构函数中逃逸出来。你可以很容易地验证它 - 在库加载后调用 ::set_terminate() 并提供自己的函数,检查它是否在程序崩溃之前被调用。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接