将std :: exception转换为EXCEPTION_POINTERS

时间:2011-03-15 17:53:36

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

我可能完全误解了如何使用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*参数。

2 个答案:

答案 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
    ) 
{
}