| 使用 Visual Studio .NET 讀入一個 Minidump 文章的這一部分使用了一個例子,在 Windows 2000 系統(tǒng)下手工創(chuàng)建了 Notepad 的一個 minidump,然后在 Windows XP 系統(tǒng)下調(diào)試。 啟動 Visual Studio .NET,單擊“文件”菜單上的“打開解決方案”,在“文件類型”下拉列表框中選擇“轉(zhuǎn)儲文件(*.dmp; *.mdmp)”(555~~~為什么我在 Visual Studio .NET 2003 中找不到這一項(xiàng)……不過還好,可以直接雙擊 .dmp 文件打開——譯者注),找到 minidump 文件,然后點(diǎn)擊“打開”創(chuàng)建一個缺省工程。 按 F5 在調(diào)試器中啟動這個 dump,這一步將為你開始調(diào)試提供一些信息。調(diào)試器將創(chuàng)建一個假的進(jìn)程;在輸出窗口中顯示了很多模塊加載的消息。此時調(diào)試器僅僅是在重建崩潰時的進(jìn)程狀態(tài)。在顯示了一條 EXE 不包含調(diào)試信息的警告消息之后,調(diào)試器停在了用戶崩潰的地方,諸如一個非法訪問什么的。這時候如果你查看調(diào)用棧窗口,你會發(fā)現(xiàn)缺少符號和很多有用的信息。 為了讀取一個 minidump,你通常需要相關(guān)的二進(jìn)制拷貝。為了找到正確的二進(jìn)制文件,打開模塊窗口。 圖 2 展示了 Notepad 的例子,并且說明了兩個情況。首先,二進(jìn)制所在的路徑名前標(biāo)上了一個星號,這表示這些是在用戶機(jī)器上的模塊路徑,但是在本地卻找不到對應(yīng)的二進(jìn)制文件。其次,在“Information”一列中全都寫著“No matching binary found”。找到對應(yīng)的二進(jìn)制文件的關(guān)鍵是注意“Version”字段和文件名。在這個例子中,大多數(shù)系統(tǒng)文件的版本號都是 2195,也就是 Windows 2000。雖然無法從這些信息上立即得知確切的 service pack (SP) 或者 quality fix engineering (QFE),但這些信息可以從微軟的 DLL 幫助數(shù)據(jù)庫中查詢到:http://support.microsoft.com/servicedesks/fileversion/dllinfo.asp。 現(xiàn)在,你需要找到一張 Windows 操作系統(tǒng)的 CD 或者已經(jīng)安裝了正確版本的機(jī)器,然后將所需要的文件復(fù)制到一個目錄。通常情況下沒有必要把進(jìn)程中每個模塊的二進(jìn)制文件都找出來,但是找出那些在每個調(diào)用棧上的關(guān)鍵模塊是很重要的。這通常包括操作系統(tǒng)的二進(jìn)制文件(例如 Kernel32.dll)和你自己的二進(jìn)制模塊(在這個例子中就是 Notepad.exe)。 在你找到這些二進(jìn)制文件、并把它們拷貝到一個本地目錄之后,單擊“調(diào)試”菜單中的“停止調(diào)試”命令。然后在解決方案資源管理器中,右鍵單擊工程圖標(biāo),在快捷菜單上單擊“屬性”,你將看到“調(diào)試”屬性頁。在“命令參數(shù)”中填入“MODPATH”,跟上一個等號,然后輸入二進(jìn)制文件所在的位置,如果有多個位置,可以用分號分隔。在這個例子中,它是: MODPATH=m:\sysbits 在設(shè)置好了路徑之后,按 F5 重新裝入 minidump,MODPATH 的值將通過命令行參數(shù)傳遞給調(diào)試器;在 Visual Studio .NET 的后續(xù)版本中應(yīng)該會有更方便的方法設(shè)置這個參數(shù),或許可以作為一個選項(xiàng)出現(xiàn)在屬性對話框中。 盡管找到二進(jìn)制文件并不太可能改善調(diào)用棧窗口的情況,但是它卻能解決模塊窗口中的問題,如圖 3 所示: 它現(xiàn)在顯示的不再是“No matching binary found”,而是“Cannot find or open a required DBG file”(我怎么覺得這個地方的英文語法應(yīng)該用“nor”而不是“or”……呵呵,不管它了,反正微軟程序中無傷大雅的語法錯誤已經(jīng)不是第一次被發(fā)現(xiàn)了——譯者注)和“No symbols loaded”。前一條消息出現(xiàn)在那些使用 DBG 文件存儲調(diào)試信息的系統(tǒng) DLL 上,后一條消息則出現(xiàn)在使用 PDB 文件的 DLL 上。找到對應(yīng)的二進(jìn)制文件并不能使你看到調(diào)用棧;你還需要找到它們對應(yīng)的調(diào)試信息。 | 方法 A:坎坷之路 為了完整地分析一個 minidump,你需要找到所有的調(diào)試信息。但為了節(jié)省時間,你可以只找那些你需要的信息。本例中的調(diào)用棧列表包含了 User32.dll 和 Kernel32.dll,所以需要它們的調(diào)試信息。 對應(yīng)的調(diào)試信息 操作系統(tǒng)所需的文件 | Windows NT 4 | DBGs | | Windows 2000 | DBGs, PDBs | | Windows XP | PDBs | 一個找系統(tǒng)符號的好地方在?http://www.microsoft.com/ddk/debugging,你也可以在 Windows NT Server 和 Windows 2000 Server 操作系統(tǒng)的 Support CD 上找到系統(tǒng)符號。在本例中,它們被拷貝到了二進(jìn)制代碼所在的位置。實(shí)際情況中你可能會遇到非微軟發(fā)布的二進(jìn)制模塊,這時候你就需要它們的 PDB 文件了。同樣在本例中,Notepad 的 DBG 和 PDB 文件也被拷貝了出來,因?yàn)樗俏覀兪褂玫臉颖緫?yīng)用程序。 在單擊“調(diào)試”菜單上的“停止調(diào)試”命令后再按 F5 就會看到調(diào)用棧列表,如圖 4 所示。你也許發(fā)現(xiàn)了,由于添加了新的二進(jìn)制文件和調(diào)試信息,調(diào)用棧發(fā)生了變化。這就是我們要的結(jié)果;只有在具有調(diào)試信息的情況下才能準(zhǔn)確地回溯一個調(diào)用棧,提供的信息越詳細(xì),你得到的堆棧就越精確,通常能夠把那些原來沒有顯示出來的棧幀信息暴露出來。 在本例中并沒有崩潰。在實(shí)際情況中,這些信息應(yīng)該已經(jīng)能夠幫助你查找出大概 70% 的崩潰原因。另外,本例中的調(diào)用棧列表是使用微軟隨系統(tǒng)組件提供的、經(jīng)過刪減的符號文件所生成的,所以沒有行號信息。如果你使用自己生成的、完整的 PDB 文件,你可以看到一個更詳盡的調(diào)用棧。 圖 4:找到符號和二進(jìn)制文件后的調(diào)用棧窗口 | 符號服務(wù)器 如果你需要處理大量 minidumps,進(jìn)行大范圍調(diào)試,那么存儲和訪問所有的二進(jìn)制文件以及 PDB/DBG 文件將變得很困難。Windows NT 中包含了一種叫做符號服務(wù)器的技術(shù),起初只是用來存儲符號文件的,后來擴(kuò)展到也支持二進(jìn)制文件的查找。Windows NT 調(diào)試器是第一個支持它的工具,但實(shí)際上 Visual Studio .NET 也支持它,雖然沒有文檔提及(事實(shí)上,在 Visual Studio .NET 2003 的文檔中和 MSDN 的 Knowledge Base (KB) 中都有講到如何使用符號服務(wù)器,KB 中的 Q319037 和 Q311503 分別講述了如何在 Visual Studio .NET 2002 和 Visual Studio 6.0 中使用符號服務(wù)器,甚至還包括了一個詳細(xì)無比的、傻瓜式的教學(xué)視頻。在 MSDN 中搜索關(guān)鍵字“symsrv.dll”可以找到這部分內(nèi)容——譯者注)。關(guān)于符號服務(wù)器,可以參考?http://www.microsoft.com/ddk/debugging/symbols.asp。 | | 方法 B:康莊大道——使用符號服務(wù)器 首先,去?http://www.microsoft.com/ddk/debugging?下載調(diào)試工具。你需要安裝 Symsrv.dll 文件,你可以將它拷貝到 devenv.exe 所在的目錄下,或者放到你的 System32 目錄下,以便 Visual Studio .NET 可以訪問到它。在復(fù)制了 Symsrv.dll 文件之后,你就可以安全地卸載調(diào)試工具了。你還需要創(chuàng)建一個本地目錄,在本例中,創(chuàng)建了一個本地目錄 C:\localstore。 在工程屬性對話框中的“調(diào)試”屬性頁上,填寫“符號路徑”: SRV*c:/localstore*http://msdl.microsoft.com/download/symbols 這個字符串會告訴調(diào)試器使用符號服務(wù)器來獲取符號文件,并在本地創(chuàng)建一個符號服務(wù)器,用來存放符號文件?,F(xiàn)在,當(dāng)你在 minidump 工程中按下 F5 后,符號文件將從微軟的網(wǎng)站上拷貝到本地服務(wù)器。在第一次下載后,之后的加載速度就會快很多,因?yàn)榉栁募谋镜胤?wù)器中直接加載,不再需要通過 Web 下載了。 在調(diào)試微軟之外的程序時,你應(yīng)該將方法 A 和方法 B 結(jié)合起來。用方法 A 獲得系統(tǒng)組件的符號文件(反了吧?好像應(yīng)該用方法 B 吧……不過原文確實(shí)是“Use A to get the system components”——譯者注),然后附上你自己的符號文件路徑,用分號將它們隔開,例如: c:\drop\build\myapp;SRV*c:\localstore*http://msdl.microsoft.com/download/symbols 由于符號服務(wù)器是 Visual Studio .NET 中的一個沒有文檔說明的特性,所以沒有錯誤報告。如果表達(dá)式錯誤或者 Symsrv.dll 文件的位置不正確,符號文件就不能被加載,只能在模塊窗口中顯示“No symbols loaded”的錯誤信息。你也可以使用符號服務(wù)器存儲和下載二進(jìn)制文件,但是 MODPATH 表達(dá)式需要使用“symsrv*symsrv.dll*”而不是“SRV*”(MSDN 中對于“srv”的解釋是:“This is shorthand for symsrv*symsrv.dll.”——譯者注)。 注意:微軟的符號服務(wù)器不包含二進(jìn)制文件,但是你自己創(chuàng)建的符號服務(wù)器卻可以。 符號服務(wù)器不僅僅是用來調(diào)試 minidumps 的,它提供了一種“在線”調(diào)試的方法。在使用符號服務(wù)器之前,別忘了正確地配置“調(diào)試”屬性頁上的“符號路徑”選項(xiàng)。 | |