我可能完全误解了如何使用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*
参数。
答案 0 :(得分:7)
在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()是执行此操作的另一种方法,你应该认为它可以作为任何未处理异常的终极支持,独立于代码位置。这是创建崩溃应用程序的minidump的最佳方法。最后但并非最不重要的一点是,在流程内部创建崩溃应用程序的minidump并不是最好的方法。有很多可能性不会很好,过程状态可能会被严重损坏。一种失败模式是将进程堆锁定。考虑到堆损坏是一种非常常见的崩溃原因,这并非不可能。使用“保护进程”修复此问题,使用命名事件来发出信号以生成小型转储。您的异常过滤器只需要设置始终有效的事件。
答案 1 :(得分:3)
Windows SEH和c ++异常不会以任何方式交织在一起 - 解决此问题的简单方法是使用您自己的__try __except包装,例如:取消引用空指针。
类似的东西:
__try {
* (int *) 0 = 0;
}
__except
(
eh_.WriteMinidumpForException(GetExceptionInformation()), EXCEPTION_EXECUTE_HANDLER
)
{
}