c++ - Qt C++ 未处理的异常堆栈跟踪

标签 c++ qt winapi exception-handling dump

我正在尝试找出一种方法来在发生崩溃时获取已部署的 C++ 应用程序的堆栈跟踪。我尝试了几种方法,我认为我的问题与发生异常后的堆栈有关。

我在 Qt 中创建了一个测试应用程序。这是代码。

void miniDumpFunc()
{
    MiniDump dump;
    dump.Create(L"C:\\dmp\\dmp.dmp");
}

void anotherFunc()
{
    miniDumpFunc();
}

LONG WINAPI OurCrashHandler(EXCEPTION_POINTERS * /*ExceptionInfo*/)
{
    miniDumpFunc();

    return EXCEPTION_EXECUTE_HANDLER;
}

void badFunc()
{
    int *myNull = NULL;
    *myNull = 42;
}

int main(int argc, char *argv[])
{
    QGuiApplication app(argc, argv);

    QQmlApplicationEngine engine;
    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));

    ::SetUnhandledExceptionFilter(OurCrashHandler);

    anotherFunc();

    return app.exec();
}

如果我调用 anotherFunc() 然后查看 WinDbg 中的堆栈跟踪,我会得到以下堆栈。

我认为这里有一些内联,但它看起来是正确的。

如果我调用 badFunc() 然而这就是我得到的结果。

堆栈跟踪从 UnhandledExceptionFilter 开始。堆栈似乎被异常弄乱了。

这是我获得生成小型转储的代码的地方。 http://blog.aaronballman.com/2011/05/generating-a-minidump/

最佳答案

您为 badFunc 发布的堆栈跟踪非常好,并且是预期的结果,考虑到您正在使用的实现。 MiniDumpWriteDump使用当前指令指针运行堆栈跟踪,除非您传递 SEH 异常的 EXCEPTION_POINTERS通过MINIDUMP_EXCEPTION_INFORMATION结构体。由于未处理的异常过滤器安装在异常帧的底部,因此从那里调用 MiniDumpWriteDump 会产生您观察到的堆栈跟踪。

要获得更有用的堆栈跟踪,您需要将 EXCEPTION_POINTERS 传递给 MiniDumpWriteDump

这只是 implementation you are using 的众多问题之一.还有更多:

  • 作者似乎很清楚,他们可以为 ExceptionParam 参数传递 nullptr,但随后又决定总是传递 nullptr。该接口(interface)实际上应该提供两种重载:一种接受 EXCEPTION_POINTERS 参数,另一种不接受。这允许从任何地方调用该功能,但在从未处理的异常过滤器调用时也保留堆栈跟踪(后者是迄今为止最常见的用例)。
  • 作者提出了一个“有趣的问题:应用程序中的其他线程应该做什么?”目前,MiniDumpWriteDump 已经挂起所有 进程中的线程在前进之前。你甚至没有选择。暂停线程的整个实现(包括排除辅助线程的过滤器)是多余的。它需要去。
  • 作者未能解决一个真正的问题( Vanilla MiniDumpWriteDump,以及他们自己的线程挂起实现):线程在任意点挂起。如果这些线程中的任何一个持有任何锁(比如全局堆分配互斥锁),您就会立即陷入死锁。毕竟,MiniDumpWriteDump 也需要从进程堆中分配内存。这里的解决方案涉及更多:对 MiniDumpWriteDump 的调用必须在其自己的进程中执行,并使用适当的 IPC。

以上任何一个都是相当严重的错误,需要解决。作为published ,该代码既无用又危险。如果您想同时实现自己的解决方案,请查看以下资源以获取可靠信息:

关于c++ - Qt C++ 未处理的异常堆栈跟踪,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41292143/

相关文章:

java - 如何以编程方式启用侧音/麦克风直通

c++ - 如何将 float 转换为长度为 4 的字节数组(char* 数组)?

c++ - 构建 64 位静态库

c++ - C/C++ 覆盖数组边界

c++ - QXmlStreamReader (Qt5) : get all sub-elements inside a tag

c++ - 在 QTextEdit 或 Qt-Creator 的 connect() 中使用指针

c++ - 质量差,在 qt4 中渲染来自相机的图像时

c++ - 如何使用 FormatMessage 函数填充系统错误消息的 va_list?

windows - 获取线程信息/环境 block (TIB/TEB)的官方方式

c++ - 无法在 32 位服务中使用 RegLoadKey 加载 64 位 key