7

我可能完全误解了如何使用 Google Breakpad API,如果是这样的话,我愿意接受评论/建议/粗鲁的言论。我正在尝试调用以下 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*参数传递。

4

2 回答 2

9

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

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

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

于 2011-03-15T18:20:29.930 回答
3

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

就像是:

__try {
  * (int *) 0 = 0;
} 
__except 
    (
        eh_.WriteMinidumpForException(GetExceptionInformation()), EXCEPTION_EXECUTE_HANDLER
    ) 
{
}
于 2011-03-15T17:59:19.237 回答