2009-12-04 49 views
0

我試圖在收到SIGSEGV時使用DbgHelp.dll中的StackWalk64函數獲取堆棧跟蹤,但獲取的堆棧跟蹤與訪問的實際站點無關違反:在Windows上訪問衝突後獲取堆棧跟蹤

[0] sigsegv_handler() e:\hudson\jobs\ide-nightly-trunk\workspace\ide-nightly-trunk\core\ide\cspyserver\src\stackwalker\cssstackwalker.cpp:31 
[1] XcptFilter() C:\Windows\WinSxS\x86_microsoft.vc90.crt_1fc8b3b9a1e18e3b_9.0.30729.4148_none_5090ab56bcba71c2\MSVCR90.dll 
[2] __tmainCRTStartup() f:\dd\vctools\crt_bld\self_x86\crt\src\crtexe.c:603 
[3] seh_longjmp_unwind4() C:\Windows\WinSxS\x86_microsoft.vc90.crt_1fc8b3b9a1e18e3b_9.0.30729.4148_none_5090ab56bcba71c2\MSVCR90.dll 
[4] BaseThreadInitThunk() C:\Windows\syswow64\kernel32.dll 
[5] RtlCreateUserProcess() C:\Windows\SysWOW64\ntdll.dll 
[6] RtlCreateProcessParameters() C:\Windows\SysWOW64\ntdll.dll 

我懷疑怪異的窗口異常處理和setjmp/longjmp的參與,但我真的不知道我應該尋找。

回答

2

請注意,在訪問衝突之後獲得可靠的堆棧錯誤總是很有挑戰性。根據定義,當AV發生時該過程是損壞的,因此可能無法檢索到實際的堆棧跟蹤後綴(例如,如果導致異常的錯誤也破壞了您的堆棧行走邏輯所使用的某些結構會發生什麼情況)?

在這種情況下,您似乎試圖捕獲異常過濾器中的堆棧跟蹤,該異常過濾器將無法工作 - 異常過濾器在部分展開的堆棧上運行。你可以找到異常記錄和與GetExceptionInformation API失敗的背景記錄(所以你需要做的是這樣

__try 
    { 
    <stuff> 
    } 
    __except(MyExceptionFilter(GetExceptionInformation()) 
    { 
    <stuff> 
    } 

你應該能夠獲取準確的堆棧跟蹤這個API只能從過濾器表達式工作與上下文記錄和例外信息

+0

是的,我知道我沒有任何保證,我可以得到一個完整的堆棧跟蹤,但這是關於獲取儘可能多的信息,當系統崩潰,所以部分或破碎stacktrace總比沒有好。 – JesperE

0

我在Windows上沒有任何使用C運行時支持的經驗。但是,使用向量化異常處理程序功能取得了很好的成功(請參閱MSDN AddVectoredExceptionHandler)。傳遞給處理程序的EXCEPTION_POINTERS結構可與MiniDumpWriteDump API一起使用,以生成用戶模式轉儲文件,您可以使用WinDbg打開該文件以檢查異常。

備註:
- 您需要在打開轉儲以切換到異常上下文後運行.excr。
- 向異常過濾器調用所有異常,所以一定要通過查看傳遞給過濾器的EXCEPTION_RECORD :: ExceptionCode來過濾那些您感興趣的異常。