【问题标题】:Convert std::exception to EXCEPTION_POINTERS将 std::exception 转换为 EXCEPTION_POINTERS
【发布时间】:2011-07-16 00:17:01
【问题描述】:

我可能完全误解了如何使用 Google Breakpad API,如果是这种情况,我愿意接受 cmets/建议/粗鲁言论。我正在尝试调用以下 C++ 函数:

bool WriteMinidumpForException(EXCEPTION_POINTERS* exinfo);

我参考了std::exception

try {
  return QApplication::notify(receiver, event);
} catch (std::exception &ex) {
  eh_.WriteMinidumpForException(?????);
  // ... do some more stuff and ultimately kill this process
}

eh_google_breakpad::ExceptionHandler。)

我在 ?????

中放了什么

背景: 这是必要的原因(我认为)是 Qt 不支持在事件处理程序中抛出的异常。它不会正确传播,因此 Breakpad 生成的 minidump 完全没有用,因为异常的实际上下文已经丢失。相反,您必须捕获所有异常并在QApplication::notify() 的覆盖中处理它们,这就是我想要做的。在出现异常的情况下,我想立即为该异常编写我的 minidump(听起来像 WriteMinidumpForException 会这样做),然后通知用户并退出应用程序。但我不确定将什么作为EXCEPTION_POINTERS* 参数传递。

【问题讨论】:

    标签: c++ qt winapi exception google-breakpad


    【解决方案1】:

    Windows SEH 和 c++ 异常不会以任何方式交织在一起 - 解决此问题的简单方法是使用您自己的 __try __except 包装,例如空指针的取消引用。

    类似:

    __try {
      * (int *) 0 = 0;
    } 
    __except 
        (
            eh_.WriteMinidumpForException(GetExceptionInformation()), EXCEPTION_EXECUTE_HANDLER
        ) 
    {
    }
    

    【讨论】:

      【解决方案2】:

      在 MSVC 编译器中,C++ 异常搭载到本地 Windows 异常管道(SEH,结构化异常处理)。虽然存在很大的阻抗不匹配,但异常过滤器的概念在 C++ 中没有很好的匹配。当 catch 处理程序捕获异常时,SEH 异常已经被处理并且堆栈被解除。 EXCEPTION_POINTERS 信息是奇闻趣事。异常过滤器实际上存在,这就是它过滤您要捕获的特定类型的方式,但是它们是由编译器自动生成的。不存在使它们有用的合理 C++ 语法。

      您需要深入了解编译器对处理 SEH 异常的支持。使用 __try, __except 关键字(__finally 是可选的)并让您的过滤器捕获 C++ 异常 0xe04d5343 ('MSC') 的异常代码。但是,您确实失去了捕获特定 C++ 异常类型的能力,该管道被埋在没有源代码的 CRT 中。在__try 中放置一个C++ try 来解决这个问题,这样你的__except 只会看到C++ 代码没有过滤的异常。

      使用 SetUnhandledExceptionFilter() 是另一种方式来做到这一点顺便说一句,您确实应该将其视为任何未处理异常的最终支持,与代码位置无关。这是创建崩溃应用程序的小型转储的最佳方法。最后但并非最不重要的一点是,在进程本身内创建崩溃应用程序的小型转储并不是最好的方法。这很可能无法正常工作,进程状态可能会被严重破坏。一种故障模式是锁定进程堆。考虑到堆损坏是一个非常常见的崩溃原因,这并非不可能。使用“保护进程”修复该问题,使用命名事件向其发出信号以进行小型转储。您的异常过滤器只需要设置事件,它总是有效的。

      【讨论】:

      • 谢谢,这是很好的信息。我正在尝试使用 Google breakpad 库,它(据我了解)正在执行您上面描述的事情(利用 SetUnhandledExceptionFilter 等)。但是,当从事件处理程序(在 GUI 应用程序中,这几乎是主要情况)抛出异常时,Qt 表现不佳,因此我必须通过强制 breakpad 按需编写小型转储来解决它。使用 __try,现在我得到“不能在需要对象展开的函数中使用 __try”sigh
      • 使用一个本身不包含任何带有析构函数的 C++ 对象的小辅助函数来调用事件处理函数。
      • 我在制作辅助函数时遇到了麻烦。我需要从MyApplication::notify() 中调用QApplication::notify()(MyApplication 继承自QApplication)。您可以强制从非成员函数调用基类吗? (我假设我需要一个非成员函数,因为我的类使用了析构函数。)
      猜你喜欢
      • 2011-04-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-16
      • 2015-04-17
      • 2020-12-09
      • 2016-01-28
      相关资源
      最近更新 更多