【问题标题】:DUMP in unhandled C++ exception未处理的 C++ 异常中的 DUMP
【发布时间】:2010-06-02 19:18:33
【问题描述】:

在 MSVC 中,如何使任何未处理的 C++ 异常(例如 std::runtime_error)使我的发布编译程序崩溃,以便它从异常抛出位置生成包含完整堆栈的转储?

我已经在 AeDebug 注册表中安装了 NTSD,并且可以为内存访问冲突等问题生成良好的转储,所以这里的问题归结为正确地使程序崩溃,我想。

提前致谢。

【问题讨论】:

    标签: c++ windows visual-c++ exception-handling


    【解决方案1】:

    我终于破解了。

    1. 使用set_terminate() 函数为每个线程注册一个处理程序
    2. 在您的主函数()中,使外部 DLL(事件 Windows')无法成功调用 SetUnhandledExceptionFilter()。一篇关于如何做到这一点的好文章:http://www.debuginfo.com/articles/debugfilters.html#overwrite
    3. 至于手柄本身,就很简单了:
    void Terminate()
    {
      OutputDebugStringA("Terminate\r\n");
      RaiseException(0xE0000010, EXCEPTION_NONCONTINUABLE, 0, 0);
    }
    

    像上面的例子一样调用RaiseException() 足以使进程崩溃并产生我想要的糊状转储。

    您知道,我遇到的问题是:

    1. IPHelper Windows API 动态加载另一个 Windows DLL
    2. 此 DLL 使用 Windows 自己的 C 运行时版本(MSVCRT 而不是 MSVCRT90)
    3. 新的 C++ 运行时在启动时调用 SetUnhandledExceptionFilter() 以捕获 C++ 异常。由于最新的 C++ 异常过滤器是调用由 set_terminate() 设置的句柄的过滤器,因此没有调用我的句柄。

    【讨论】:

      【解决方案2】:

      SetUnhandledExceptionFilterDebugBreak 应该可以完成这项工作。

      编辑:哎呀,重读,你想处理未捕获的 C++ 异常。做好这件事会有点棘手——当您(通常)听到 C++ 异常时,它已经将堆栈展开回处理程序的级别。在调用 catch 之前,您没有任何真正的方法可以知道是否引发了异常,但是到那时堆栈已经展开。

      【讨论】:

      • MSCVRT 的 set_terminate() 函数应该可以解决问题,但我无法让它工作:我的处理程序(它调用 RaiseException() 并导致程序崩溃)永远不会被调用。跨度>
      • SetUnhandledExceptionFilter 确实适用于未处理 C++ 异常,就像它适用于 SEH 异常一样。
      【解决方案3】:

      研究使用 Windows 调试器。
      Windbg – 以体面的 UI 封装 KD 和 NTSD。
      另请查看 Windows 调试器附带的 ADPlus。

      Here 是开始学习如何使用它的好地方。

      【讨论】:

      • 使用调试器没问题,但在程序运行的无人值守环境下就不行了。看,这是一个生产环境:如果出现问题,服务会崩溃并重新启动。我真的需要一个故障转储来稍后执行事后分析。我还需要有关 Windows 错误报告收集的这些信息,稍后我会得到。
      • Windows 调试器附带了一个名为 ADPlus 的实用程序,它使我能够轻松地收集堆栈跟踪以发现发布构建应用程序崩溃的情况。我同意你应该只在尝试追踪崩溃时才应该这样做,而不是持续进行。为此,您需要一个日志系统。查看 ADPlus 的所有命令开关。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-06-01
      • 1970-01-01
      • 1970-01-01
      • 2012-05-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多