MS Visual Studio 2005 C ++异常处理

时间:2011-10-21 04:16:20

标签: c++ visual-studio-2005

我有一个在MS Visual Studio 2005中构建的C ++应用程序,它链接到第三方库。对于某个输入,应用程序在第三方库中崩溃(显然在realloc.c中的某个地方;因此必须是某种内存问题)。我在发布时跑了,因为输入很大。所以我跑了直到它崩溃然后选择调试。当我单独调试guilty函数时,我希望使用一些异常处理来防止应用程序崩溃,而是干净地退出。所以我使用了类似的东西:

try {
   //- call 3rd party application function that fails
}
catch(...) {
   //- handle exception or whatever
   Logger::Fatal("Fatal error: Exiting...");
   return false;
}

但令我惊讶的是,应用程序仍然崩溃!我期待看到它显示错误消息,因为我可能已经用省略号(...)捕获了所有异常;我在这里想念的是什么?我甚至尝试在Project Properties中设置/ EHca(was / EHsc) - > C / C ++ - >代码配置 - >启用异常处理。关于可能导致问题的相关说明,以下用法是否正确?

my_class* mc[] = {nil, nil, nil};
for (int i = 0; i < 3; ++i) {
    mc[i] = new my_class();
    //-Do stuff with mc[i]
    if (mc[i] != nil) {
       delete mc[i];
       mc[i] = nil;
    }
}

无法使异常处理工作是令人费解的。我当然会欣赏C ++专家的想法/见解。顺便说一句,在Linux(RHEL5)上也会出现同样的问题,但我目前正试图让异常处理在Windows上运行。

注意:当我在崩溃后让它调试。我确实收到了“访问违规...无法读取位置”的消息。有了这个更新的信息,我希望C ++中的某些东西仍可以在Windows和Windows上运行。 Linux发生此类崩溃。

2 个答案:

答案 0 :(得分:1)

您是否尝试过调用SetUnhandledExceptionFilter

来捕获崩溃

答案 1 :(得分:0)

正如Miguel所说,解决问题的正确方法可能是使用SetUnhandledExceptionFilter。但是我想详细解释你的现象。

首先,并非所有程序“崩溃”都与异常有关。例如,CRT可能在错误时触发程序终止,例如vector中的无效元素访问,或纯虚拟析构函数调用。如果您还要涵盖这些案例 - 请参阅set_unexpectedset_terminate

除此之外,catch块只能捕获从适当的代码块抛出的异常。 OTOH可能存在其他地方调用的函数,例如窗口过程(如果适用),其他线程等等。

现在,关于你的问题。让我们首先意识到为什么像catch(...)这样的东西可能会遇到访问冲突等等,以及为什么这并不总是会发生(就像你的情况一样)。

Windows提供了自己的异常处理机制 - SEH,结构化异常处理。它远远优于C ++异常处理。此外,硬件中断(由CPU引起)会自动“转换”为SEH异常,因此使用SEH的代码可以处理软件异常和硬件故障。

Microsoft C ++编译器实际上通过SEH实现C ++异常。那是throw是通过RaiseException实现的,指定了C ++特定的异常代码和参数,catch__except的特定于C ++的包装器,对于每个具有析构函数的对象,编译器生成类似于__finally块的东西。反之亦然。当引发非C ++异常时 - 执行为C ++异常生成的相同代码。

此外,还有所谓的编译器异常处理选项,它们会影响编译器异常处理代码生成及其在运行时的行为。它们被称为异常处理模型:

  • 同步即可。编译器生成的代码只有在显式引发异常时才能保证正常工作。这包括throw个语句,以及编译器看不到其代码的所有“外部”函数(在某些变体中 - 只有C ++外部函数)。特别是从记忆中读取被认为是“安全的”。
  • 异步即可。不允许编译器假设可能出现异常的地方。因此,即使出现访问内存地址的异常,它也会生成应该正常工作的代码。

此外,在catch (...) 中调用的CRT代码故意忽略非C ++异常,除非选择异步EH模型

因此,如果您希望catch (...)捕获非C ++异常,那么必须选择异步EH模型。

在我遇到驱动程序开发相关问题之后,我写了一个article on the codeproject。它详细解释了这一切。