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

时间:2009-09-03 14:21:29

标签: c++ exception exception-handling

我有一个第三方库,有时会抛出异常。所以我决定将我的代码包装在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 个答案:

答案 0 :(得分:11)

AFAIK访问冲突不会抛出异常...至少不是标准的!

也许捕获特定于Windows的“本机”异常会有所帮助:https://web.archive.org/web/20081022160935/http://www.gamedev.net/reference/articles/article2488.asp

答案 1 :(得分:8)

访问冲突不是C ++异常。这是一个Windows结构化异常。如果你想在catch(...)中捕获它们,你将不得不使用_set_se_translator()。

你可能应该谷歌因为所有原因捕获(...)是邪恶的,并确保你真的想这样做。

答案 2 :(得分:1)

如果您使用的是Windows平台,可以尝试查看__try

但请注意,除非您确定可以隔离并处理异常,否则继续执行的用处不大。

答案 3 :(得分:0)

您所描述的内容非常类似于:C ++运行时正在调用:: terminate()。

这通常是由所谓的双重异常引起的 - 某处抛出异常,堆栈展开开始,并且在堆栈展开期间调用的析构函数之一也会引发异常。在这种情况下,调用了terminate(),你无法真正帮助该程序。

如果是这种情况,那么唯一的方法就是获得一个新版本的库,其中异常不会出现在析构函数之外。您可以非常轻松地验证它 - 在加载库之后调用:: set_terminate()并提供您自己的函数并检查它是否在程序崩溃之前被调用。