Bug Report機制的實現

來源:互聯網
上載者:User
   寫程式的人都有這個苦惱,使用者說你的程式總有時會莫名奇妙的崩潰,可是你怎麼也無法重現崩潰的情境,所以也無法找出程式中的Bug,難道就束手無策嗎?    前幾天在一本雜誌(《程式員-遊戲創造》)上看到一篇關於這個主題的文章,非常詳細的論述了怎樣通過代碼和工具實現Bug Report,使得你可以快速定位崩潰的原始碼行數。     要catch未處理的異常,該文中論述了使用全域的try-catch的優缺點,全域的try-catch導致了調試工作的麻煩,不可取。Win32異常的可以通過設定過濾函數來處理,而C++也有set_terminate函數可以設定一個函數來處理任何未catch的異常。    文章還告訴我們,main/WinMain是程式的入口處,但靜態初始化在這之前進行,作業系統裝載我們的程式後,先調用的是CRT提供函數WinMainCRTStartup/mainCRTStartup,可以通過VC開發工具設定程式的入口函數來擷取異常的優先控制權(/ENTRY:函數)(Linker->Advanced->Entry Point)。    1.用minidump進行調試
    這個技術是改進Windows作業系統的錯誤報表機制的關鍵。產生的檔案非常小,適合於網路傳輸。
    有三種方法建立一個minidump檔案:
    a. 在你的應用程式中加入未處理的exception處理函數,函數中建立minidump檔案
    b. Visual Studio .NET整合式開發環境中調試時,Debug菜單中按Save Dump
    c. Windows XP 在一個程式遇到未處理的異常時會自動產生minidump檔案,但直接提交給微軟,你沒機會處理。    要使用該技術,build的時候要產生完全的調試資訊檔(PDB),發布每個版本時要儲存每個可執行檔(exe/dll)以及相對應的pdb檔案,以備將來debug用。為了更好的輔助檔案匹配,注意要正確設定每個可執行檔的組建號,每次發布要使用不同的版本號碼,然而debugger使用的是PE檔案頭中內部時間蹉來匹配的。在發布版本中產生調試資訊有副作用,佔用更多空間並且容易被逆向工程。    寫minidump的API是MiniDumpWriteDump,在PlatformSDK中的DBGHelp.dll,只有XP版本的沒有問題。為了調用這個API,你必須使用SetUnhandledExceptionFilter API來設定一個未處理異常處理器,用來catch崩潰,但在VS2005之前,仍然會無法catch純C++異常。    在你的函數中,注意要匯入正確的DbgHelp.dll,使用LoadLibrary會預設載入System32目錄下的dll,Win2000將會導致錯誤。    分析使用者傳回的minidump檔案,使用Visual Studio .Net開啟(*.dmp,*.mdmp)並建立預設的項目。按F5在Output視窗中顯示載入的模組資訊。重建所有進程狀態,但可能缺少symbols以及調試資訊。所以你需要所有匹配的exe和dll檔案以及pdb檔案,要查看所有的module開啟Modules視窗,找出所有(通常沒必要所有)匹配的dll(DLL Help database: http://support.microsoft.com/servicedesks/fileversion/dllinfo.asp.),或者你需要作業系統的安裝盤或者從報告者的系統中得到所有匹配的dll,拷貝到本地的一個目錄下,例如D:/Mudules。然後設定項目的Debugging頁中的Command參數為MODPATH=D:/Mudules,按F5重新載入minidump。注意你也需要每個dll匹配的pdb檔案,平台的可以在作業系統安裝盤或者http://www.microsoft.com/ddk/debugging中找到。  Operating system  Files required
 Windows NT 4         DBGs
 Windows 2000         DBGs, PDBs
 Windows XP            PDBs
 
    如果你要處理很多minidumps,可能需要所有的dll和pdb/dbg,這時你可以使用Symbol Server來管理所有資源,首先到http://www.microsoft.com/ddk/debugging/symbols.asp下載調試工具,拷貝Symsrv.dll到VS.Net可以訪問的地方,建一個本地目錄,例如:C:/localstore,在項目屬性對話方塊中設定Debugging頁中Symbol路徑為SRV*c:/localstore*http://msdl.microsoft.com/download/symbols。此後,每次F5後就會自動下載必要的檔案。    原文:http://www.codeproject.com/debug/postmortemdebug_standalone1.asp
    例子:http://www.codeproject.com/debug/crash_report.asp    2. map檔案
    產生map檔案來定位崩潰的程式碼
    原文:http://www.codeproject.com/debug/mapfile.asp
   
    3. CrashFinder    John Robbins 寫好的CrashFinder能夠發現VC++/VB的應用程式的崩潰處(程式碼)。Release版本也要產生Debug資訊,在VC中使用/Zi 編譯選項(C/C++ tab中Program Database )和/DEBUG and /PDB:<pdb filename>連結選項(Link tab中打勾Debug info 並選擇Microsoft format),VB中在項目屬性打勾Compile to Native Code 和Create Symbolic Debug Info 選項。    如果你在Debugger的OUtput視窗中看到LDR: Dll xxx base 10000000 relocated due to collision with yyy資訊,可以通過REBASE.EXE(Platform SDK)程式使得你可以重新安排載入dll/ocx地址,因為不同的系統載入dll/ocx的地址不同,如果衝突會導致你找不出到底是哪個dll崩潰。    如果是beta版,你可以讓應用程式產生詳細Dr. Watson 資訊(要很大空間不適合傳輸),你可以在安裝應用程式時檢測系統是否已經安裝Dr. Watson(在註冊表HKEY_LOCAL_MACHINE/SOFTWARE/ Microsoft/Windows NT/CurrentVersion/AeDebug 處),有了這種資訊你可以得到詳細的堆棧空間並遊刃有餘地找出崩潰的地方。    CrashFinder使用IMAGEHLP.DLL符號引擎(Windows NT 4.0首次引入),Windows NT 5.0 SDK已經可以處理源碼行號。(CrashFinder2.1已經升級,使用最新的DBGHelp.dll)    CrashFinder只儲存應用程式和調試資訊檔的目錄資訊,所以無需每次編譯都需要CrashFinder連編。你可以建立多個CrashFinder項目,每個項目針對一種作業系統。    原文:http://www.microsoft.com/msj/0498/bugslayer0498.aspx
    下載:http://www.wintellect.com/about/instructors/robbins/code.aspx     解決方案:    (To be continue)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.