0

我有一个 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++ 异常都不是问题。

4

5 回答 5

1

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

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

并得到正确的输出:

你好世界

捕获异常

完毕

您的LogMessage功能是否可能存在问题?

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

不是问题,仍然不清楚,你通过抛出一个指针而不是一个值来实现什么。我建议不要使用 catch-by-pointer,请参阅C++-FAQ-lite 中的推理。

于 2009-05-27T07:18:58.350 回答
1

该代码对我来说看起来不错,但我很想在其中添加更多的 catch 子句,看看它是否会碰到其他的一个。也就是说,我会输入:

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

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

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

于 2009-05-27T07:30:03.667 回答
1

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

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

于 2009-05-27T07:44:48.553 回答
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++ 结构化异常。

于 2009-05-27T07:47:24.337 回答
0

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

于 2009-05-28T11:24:02.450 回答