库使用者是否可以覆盖C ++异常处理?

时间:2009-05-27 07:03:54

标签: c++ windows exception service messagebox

我有一个C ++ DLL,代码如下:

LogMessage( "Hello world" );
try {
    throw new int;
} catch( int* e ) {
    LogMessage( "Caught exception" );
    delete e;
}
LogMessage( "Done" );

此DLL由某些第三方应用程序加载,并调用上面的代码。问题是只调用了第一个LogMessage - 即使有一个异常处理程序,控制流也会被转移到未知。

我看到了这一点,无法决定是否要调查一些模糊不清的错误,或者只是消费者应用程序的邪恶力量。

消费者应用程序是否真的可以覆盖DLL中的C ++异常处理?

编辑:在考虑了答案中列出的所有要检查的内容之后问题得到了解决。在实际代码中,它不仅仅是 throw ,还有一个特殊的函数用于抛出在调试版本中调用MessageBoxW()Win32调用的异常。并且消费者应用程序在显示消息框(它是NT服务)时遇到了麻烦并且有效地挂断了。所以这不是以任何方式处理C ++异常的问题。

5 个答案:

答案 0 :(得分:1)

代码没问题。我用这个函数执行它:

void LogMessage( char* s )
{
  cout << s << endl;
}

得到了正确的输出:

  

Hello world

     

抓到异常

     

完成

LogMessage 功能可能存在问题吗?

我建议调查(通过调试器或添加调试打印),流程是否到达try块,以及它是否到达catch块。

不是问题,它仍然不清楚,通过抛出指针而不是值来实现什么。我建议不要使用catch-by-pointer,在C ++ - FAQ-lite中查看推理here

答案 1 :(得分:1)

代码看起来对我很好,但是我很想再加上一些catch子句来看看它是否正在击中其中一个。即,我投入:

  catch (const std::exception &ex) {
    ... log exception ...
  }
  catch (...) {
    ... log exception ..
  }

我希望它能够点击指针捕获(即使这不是一个好主意,请参阅Igor Oks提供的链接)或std :: exception,以防它无法分配内存。也就是说,它应该击中三个catch子句中的一个,因此异常无法逃脱DLL。

我还会将抛出的对象更改为值类型(即使它是int)并相应地更新catch子句以查看是否以这种方式改变了行为。

答案 2 :(得分:1)

首先,请检查LogMessage调用是否刷新输出(使用<< endl)。

虽然很牵强,但新调用是否可能抛出异常(内存不足)?我认为这是没有新例外的一个原因(只是为了增加伊戈尔所说的)。

答案 3 :(得分:1)

代码看起来还不错。但是,在抛出结构化异常throw new int;之前,您是否可以检查是否存在任何未处理的异常。

LogMessage( "Hello world" );
try {

     //some unhandled exception here 

    throw new int;
} catch( int* e ) {
    LogMessage( "Caught exception" );
    delete e;
}
LogMessage( "Done" );

如果是这种情况,那么您可以使用SetUnhandledExceptionFilter函数检查相同内容。

如果DLL已经提供了未处理的异常过滤器,并且返回EXCEPTION_EXECUTE_HANDLER,则不会调用异常处理程序。

您需要使用_set_se_translator将win32异常转换为c ++结构化异常。

答案 4 :(得分:0)

赠品实际上是在EDIT中。 “MessageBoxW()...... NT服务......有效地挂断了。”这是一个公平的描述。消息框位于与登录用户无关的桌面上。因此,它仍然存在,等待永远不会发生的鼠标点击。