如何在 Visual Studio 2008 C++ 中捕获被零除错误?
如何在 Visual Studio 2008 C++ 中捕获被零除错误(而不是其他错误;并且能够访问异常信息)?
How can I catch a divide-by-zero error (and not other errors; and to be able to access exception information) in Visual Studio 2008 C++?
我试过了:
try {
int j=0;
int i= 1/j;//actually, we call a DLL here, which has divide-by-zero
} catch(std::exception& e){
printf("%s %s
", e.what());
} catch(...){
printf("generic exception");
}
但这适用于通用的 ... catch 块.我知道特定于 MS 的 __try 在这里可能很有用,但我更喜欢标准 C++,而且无论如何我都有阻止使用 __try 的析构函数.
But this goes to the generic ... catch block. I understand that the MS-specific __try may be useful here, but I'd prefer standard C++, and in any case I have destructors which prevent the use of __try.
澄清:为了讨论目的,上面的代码被简化了.实际上,被零除是一个错误,它发生在我没有源代码的第三方 DLL 深处.错误取决于我传递给库的参数(复杂结构的句柄),但不是以任何明显的方式.所以,我希望能够优雅地恢复.
CLARIFICATION: The code above is simplified for discussion purposes. Actually, the divide-by-zero is a bug which occurs deep in a third-party DLL for which I do not have the source code. The error depends on the parameter (a handle to a complex structure) which I pass to the library, but not in any obvious way. So, I want to be able to recover gracefully.
推荐答案
假设您不能简单地修复异常生成代码的原因(可能是因为您没有该特定库的源代码,也可能是因为您无法在输入参数出现问题之前对其进行调整).
Assuming that you can't simply fix the cause of the exception generating code (perhaps because you don't have the source code to that particular library and perhaps because you can't adjust the input params before they cause a problem).
您必须跳过一些障碍才能按照自己的意愿完成这项工作,但它可以完成.
You have to jump through some hoops to make this work as you'd like but it can be done.
首先,您需要通过调用 _set_se_translator()
安装结构化异常处理翻译函数(请参阅 此处) 然后您可以检查在发生 SEH 异常时传递的代码并抛出适当的 C++ 异常.
First you need to install a Structured Exception Handling translation function by calling _set_se_translator()
(see here) then you can examine the code that you're passed when an SEH exception occurs and throw an appropriate C++ exception.
void CSEHException::Translator::trans_func(
unsigned int code,
EXCEPTION_POINTERS *pPointers)
{
switch (code)
{
case FLT_DIVIDE_BY_ZERO :
throw CMyFunkyDivideByZeroException(code, pPointers);
break;
}
// general C++ SEH exception for things we don't need to handle separately....
throw CSEHException(code, pPointers);
}
然后您可以简单地在 C++ 中以正常方式捕获您的 CMyFunkyDivideByZeroException()
.
Then you can simply catch your CMyFunkyDivideByZeroException()
in C++ in the normal way.
请注意,您需要在要转换异常的每个线程上安装异常转换功能.
Note that you need to install your exception translation function on every thread that you want exceptions translated.
相关文章