簡體   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