MS Visual Studio 2005 c++异常处理

MS Visual Studio 2005 C++ exception handling

本文关键字:c++ 异常处理 2005 Studio Visual MS      更新时间:2023-10-16

我有一个内置在MS Visual Studio 2005中的c++应用程序,它可以链接到第三方库。对于某个输入,应用程序在第三方库中崩溃(显然在reallocc .c中的某个地方;所以一定是某种记忆问题)。我在release中运行,因为输入量很大。所以我一直运行,直到它崩溃,然后选择调试。当我单独调试错误函数时,我希望使用一些异常处理来防止应用程序崩溃,而不是干净地退出。所以我用的是:

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

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

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和amp上工作;

您是否尝试通过调用SetUnhandledExceptionFilter来捕获崩溃?

正如Miguel建议的那样,解决问题的正确方法可能是使用SetUnhandledExceptionFilter。但我还是想详细解释一下你的现象。

首先,并非所有的程序"崩溃"都与异常有关。例如,CRT可以在错误时触发程序终止,例如在vector中无效的元素访问,或者纯虚析构函数调用。如果您也想涵盖这些情况-参见set_unexpected, set_terminate等。

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

现在,关于你的问题。让我们首先认识到为什么像catch(...)这样的东西可能会捕获访问冲突等事情,以及为什么这种情况并不总是发生(就像你的情况一样)。 Windows提供了自己的异常处理机制——SEH,结构化异常处理。它远优于c++异常处理。此外,硬件中断(由CPU引起)会自动"转换"为SEH异常,因此使用SEH的代码可以同时处理软件异常和硬件故障。

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

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

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

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

因此,如果你想要catch (...)捕获非c++异常-你必须选择异步EH模型。

当我在驱动程序开发中遇到相关问题后,我写了一篇关于代码项目的文章。