2011-07-06 157 views
7

我有一大堆小型應用程序通過MiniDumpWriteDump在應用程序的運行時記錄下來的。小型轉儲器是在一臺與我的開發機器不同的操作系統版本的機器上創建的。如何從小轉儲中提取堆棧跟蹤?

現在我正在嘗試編寫一個程序,使用dbghelp.dll從小型轉儲中提取堆棧跟蹤。我正在走MINIDUMP_MODULE_LIST並調用SymLoadModule64,但是無法從公共符號服務器下載pdbs(kernel32等)。如果我添加「C:\ Windows \ System32下」的符號路徑找到的DLL文件並下載符號,但當然他們不匹配從轉儲的dll文件,所以結果是無用的。

那麼我該如何告訴dbghelp.dll下載並使用正確的pdbs?

[編輯]

我忘了指出SymLoadModule64只需要一個文件名,並沒有版本/校驗和信息,所以很明顯與SymLoadModule64唯有它是不可能的DBGHELP找出要下載的PDB。

的信息是在MINIDUMP_MODULE_LIST實際可用的,但我不知道如何將它傳遞迴dbghelp的API。

有SymLoadModuleEx這需要額外的參數,但我不知道如果這就是我需要的還是什麼,我應該通過對其他參數。

[編輯]

至今沒有運氣,但我注意到這裏還有dbgeng.dll與調試SDK dbghelp.dll一起分發。 MSDN看起來有很好的文檔記錄,並表示它與windbg使用的引擎相同。也許我可以使用它來提取堆棧跟蹤。

如果任何人都可以點我的一些介紹如何使用dbgeng.dll處理小型轉儲,可能會幫助過,因爲只有MSDN文檔的各個組件而不是它們如何協同工作。

+0

你可能讓你的minidump太小了。用DumpType參數修補。確保Debug + Windows + Modules列表顯示準確的DLL路徑,版本和時間戳記。 –

+0

不,這不是問題,我可以加載WinDbg中的小型轉儲就好了,它可以正確下載PDB。這只是我想自動執行堆棧檢索,而不是在WinDbg中手動檢查轉儲。 – Zarat

+1

如果你想要去黑客路線,你可以傳遞命令到ntsd並捕獲輸出 –

回答

8

萬一別人想從自動轉儲提取堆棧跟蹤,這是我落得這樣做:

就像我在這是可能的,而不是使用dbghelp.dll dbgeng.dll更新中提到,這似乎成爲WinDbg使用的相同引擎。經過一些試驗和錯誤之後,如何使用與WinDbg相同的符號加載機制來獲得良好的堆棧跟蹤。

  • 呼叫DebugCreate得到調試引擎
  • 查詢IDebugClient4,IDebugControl4的一個實例,IDebugSymbols3
  • 使用IDebugSymbols3.SetSymbolOptions配置符號如何加載(見MSDN爲WinDbg中使用的選項)
  • 使用IDebugSymbols3.SetSymbolPath設置符號路徑,就像您在WinDbg中做
  • 使用IDebugClient4.OpenDumpFileWide打開轉儲
  • 使用IDebugCo ntrol4.WaitForEvent等到轉儲裝載
  • 使用IDebugSymbols3.SetScopeFromStoredEvent選擇存儲在轉儲
  • 使用IDebugControl4例外。的getStackTrace獲取最後幾幀堆棧
  • 使用IDebugClient4.SetOutputCallbacks註冊一個偵聽器接收解碼後的堆棧跟蹤
  • 使用IDebugControl4.OutputStackTrace處理堆棧幀
  • 使用IDebugClient4.SetOutputCallbacks註銷回調
  • 釋放接口

對WaitForEvent的調用似乎很重要,因爲沒有它,以下調用將無法提取堆棧跟蹤。

此外,似乎仍然存在一些內存泄漏,不能分辨是否我沒有正確清理或dbgeng.dll內部的東西,但我可以每20次左右重新啓動進程,所以我沒有調查更多。

相關問題