我有一个第三方库,有时会抛出异常。所以我决定将我的代码包装在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(...)
}
所以我有两个问题:
第三方编译库的方式是否有一些变化,以致我的代码无法捕获异常? (是的,如果我知道要告诉他们什么,我有可能让第三方做出必要的修改并重新编译。)
假设我无法让第三方修复它,我该怎么做才能捕获这些异常?我正在考虑......是否有某种方法可以确定pObject是否已取消分配?
答案 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()并提供您自己的函数并检查它是否在程序崩溃之前被调用。