[英]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中的堆棧跟蹤,我得到以下堆棧。
我認為這里有一些內在的東西,但它看起來是正確的。
堆棧跟蹤從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
在繼續前進之前已經暫停了進程中的所有線程。 你甚至沒有選擇。 掛起線程的整個實現(包括用於排除輔助線程的過濾器)是多余的。 它需要去。 MiniDumpWriteDump
,以及他們自己的線程掛起實現):線程在任意點被掛起。 如果這些線程中的任何一個持有任何鎖(例如全局堆分配互斥鎖),那么您將立即執行死鎖。 畢竟, MiniDumpWriteDump
也希望從進程堆中分配內存。 這里的解決方案更為復雜:對MiniDumpWriteDump
的調用必須在其自己的進程中執行,並使用適當的IPC。 上述任何一個都是一個相當大的bug,需要解決。 正如已發布的那樣 ,代碼既無用也有危險。 如果您想在此期間實施自己的解決方案,請查看以下資源以獲取可靠信息:
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.