繁体   English   中英

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

[英]Qt C++ Unhandled exceptions stack trace

我试图找到一种方法来获取崩溃时部署的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使用当前指令指针运行堆栈跟踪,除非您通过MINIDUMP_EXCEPTION_INFORMATION结构传递SEH异常的EXCEPTION_POINTERS 由于未处理的异常过滤器安装在异常帧的底部,因此从那里调用MiniDumpWriteDump会产生您观察到的堆栈跟踪。

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

这只是您正在使用实现的许多问题之一。 还有更多:

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

上述任何一个都是一个相当大的bug,需要解决。 正如已发布的那样 ,代码既无用也有危险。 如果您想在此期间实施自己的解决方案,请查看以下资源以获取可靠信息:

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM