幾篇參考文章:
windbg
http://help.wugnet.com/vista/collecting-Crash-dump-vista-ftopict24054.html
http://www.eggheadcafe.com/conversation.aspx?messageid=31157261&threadid=31157181
http://www.codeproject.com/KB/debug/windbg_part1.aspx
http://www.codeproject.com/KB/debug/cdbntsd.aspx
http://guide.it168.com/files/22620/22620.html
sogou搜尋引擎也不錯的,能搜出好多baidu搜不出來的東西!
頂一下! 畢竟兩者的資料庫不一樣!
WinDbg入門教程
摘自紅色駭客聯盟(www.7747.net) 原文:http://www.7747.net/Article/200812/31157.html
介紹
在我的職業生涯中,我看到我們大多數都是使用Visual Studio來進行調試,而不是用其它許多免費的調試器。你可能有許多理由來使用這樣的調試器,比如,在你家裡的機器上沒裝開發環境,但是一個程式一次次的崩潰。其實根據堆棧的dump就可以判斷出IE的崩潰是否是由於一個第三方的外掛程式。
對於WinDbg,我目前為止還沒有發現很好的快速入門的教程。這篇文章結合執行個體討論了WinDbg的使用。我首先假設你熟悉調試的基本概念:stepping in, stepping out,斷點以及遠端偵錯的基本概念。
注意,這本來是座位一個入門的文檔,你可以閱讀並且開始使用WinDbg. 如果對於特定的命令有疑問,請查閱WinDbg的文檔。你可以在任何微軟提供的調試器中使用這篇文章中提到的命令,比如在VS的命令列視窗中。
這篇文章是基於WinDbg 6.3.
這僅僅是一系列關於調試技術的文章中的第一篇。在下一篇文章中,我會解釋如何針對調試器編寫擴充DLL.
調試器一覽
下面大概介紹了你可以從微軟網站上下載到的調試器:
· KD-核心調試器。你可以用它來調試藍屏一類的系統問題。如果是開發裝置驅動程式是少不了它的。
· CDB-命令列調試器。這是一個命令列程式
· NTSD-NT調試器。這是一個使用者模式調試器,可以用來調試使用者模式應用程式。它實際上是一個CDB的windows UI增強。
· WinDbg-用一個漂亮的UI封裝了KD和NTSD。WinDbg即可以調試核心模式,也可以調試使用者模式程式。
· VS, VS.net-使用同KD和NTSD相同的偵錯引擎,並且相比於同樣用於調試目的的WinDbg,提供了功能更豐富的介面。
調試器之間的比較
功能
KD
NTSD
WinDbg
Visual Studio .NET
核心模式調試
Y
N
Y
N
使用者模式調試
Y
Y
Y
非託管調試
Y
Y
Y
Y
託管調試
Y
Y
Y
遠端偵錯
Y
Y
Y
Y
附加到進程
Y
Y
Y
Y
從進程分離
Y
Y
Y
Y
SQL調試
N
N
N
Y
WinDbg
WinDbg實際上封裝了NTSD和KD並且提供了一個更好用的使用者介面。它也提供了命令列開關,比如最小化啟動(-m),附加到一PID指定的進程(-p)以及自動開啟崩潰檔案(-z)。它支援三種類型的命令。
· Regular commands(比如: k) 用來調試進程
· Dot commands(比如:.sympath)用來控制調試器
· Extension commands(比如: !handle)-這些命令屬於可以用來添加到WinDbg的自訂命令;它們用擴充DLL的輸出函數來實現。
PDB檔案
PDB檔案指的是連結器產生程式資料庫檔案(Program database files)。私人的PDB檔案包括私人以及公有符號,原始碼行號,類型,局部以及全域變數。公有的PDB檔案不包含類型,局部變數以及原始碼行號資訊。
調試情境
遠端偵錯
使用WinDbg進行遠端偵錯是很容易的,而且有很多種可行的方法。在下文中,’調試伺服器’指的是運行在你所要調試的遠程機器上的調試器。’調試用戶端’指的是控制當前會話的調試器。
· 使用調試器:你需要CDB, NTSD或者WinDbg已經安裝在遠程機器上。WinDbg用戶端可以串連到CDB, NTSD或者WinDbg中的任何一個作為伺服器,反之亦然。在用戶端和伺服器直接可以選擇TCP或者具名管道作為通訊協議。
o 在伺服器端的啟動過程:
§ WinDbg –server npipe:pipe=pipename(註:可以允許多個用戶端連或
§ 從WinDbg內部: .server npipe:pipe=pipename(注,串連單個用戶端)
你可以用多種協議開啟不同的服務會話。並且可用密碼來保護一個會話。
o 從用戶端串連:
§ WinDbg -remote npipe:server=Server, pipe=PipeName[,password=Password]
§ 從WinDbg內部: File->Connect to Remote Session: for connection string, enter npipe:server=Server, pipe=PipeName [,password=Password]
· 使用Remote.exe: Remote.exe使用具名管道作為通訊的方式。如果你使用的是一個命令列介面的程式,比如KD,CDB或者NTSD。你可以使用remote.exe來遠端偵錯。注意:使用@q(不是q)來退出用戶端,不用關掉服務端。
o 要啟動一個服務端:
§ Remote.exe /s “cdp –p <pid>” test1
o 從用戶端串連:
§ Remote.exe /c <machinename> test1
上面的test1是我們所選擇的具名管道的名字。
服務端會顯示那個用戶端從那個伺服器串連以及執行過的命令。你可以使用‘qq’命令來退出服務端;或者使用File->Exit來退出用戶端。另外,如果要進行遠端偵錯,你必須屬於遠程機器的”Debugger User”組並且伺服器必須允許遠端連線。
即時調試
在WinDbg的文檔的”Enabling Postmorten Debugging”部分對此有很詳細的討論。簡而言之,你可以把WinDbg設定成預設的即時調試器,命令就是:Windbg –I。這個命令實際上是把註冊表中 HKLM/Software/Microsoft/Windows NT/CurrentVersion/AeDebug的索引值設定成WinDbg。如果要把WinDbg設定成為預設的託管調試器,你需要顯示設定如下的註冊表索引值:
HKLM/Software/Microsoft/.NETFramework/DbgJITDebugLaunchSetting 設定成 2
HKLM/Software/Microsoft/.NETFramework/DbgManagedDebugger 設定成Windbg.(注意其中的啟動參數設定)
通過JIT的設定,當一個應用程式在不是調試的狀態下拋出了未處理的異常之時,WinDbg就會被啟動。
64位調試
所有這些調試器均支援在AMD64和IA64上的64位調試環境。
託管應用程式的調試
WinDbg 6.3以後的版本支援在Widbey(VS2005和.net 2.0的內部開發代號) .net CLR託管調試。在文檔中針對託管調試有很好的討論。需要注意的是,對於託管程式來說,沒有剛才所說的PDB(譯註:Managed 程式碼實際上也是有PDB的,但是這個PDB實際上記錄了C#代碼和IL代碼的對應關係以及相關的一些資訊)的概念,因為所有的程式都是編譯成為ILASM。調試器通過CLR來查詢所需的附加資訊。
有幾點需要注意:
你只能在托段函數的代碼被執行過至少一次之後才能設定斷點。只有這樣它才能被編譯成彙編代碼。記住以下的幾點:
關於函數的地址的複雜化以及對應的斷點設定:
o CLR有可能丟棄已經編譯好的代碼,所以函數的入口地址有可能改變。
o 同樣的代碼有可能被多次編譯,如果多個應用程式定義域沒有共用這段代碼的話。如果你設定了一個斷點,它就會被設定在當前線程(譯註:CLR的邏輯線程)所在的應用程式定義域內。
o 泛型的特殊執行個體可能導致同一個函數有不同的地址。.
資料存放區布局的複雜化以及對應的資料檢查:
CLR可能會在啟動並執行時候任意改變資料的儲存布局,所以一個結構體成員的位移量可能會被改變掉. (譯註:實際上是在一個類型被載入的時候決定的資料布局,之後是不會改變的。)
一個類型的資訊是在第一次使用的時候被載入,所以你可能不能夠查看一個資料成員如果它還沒有被使用過.
調試器命令的複雜化
o 當跟蹤Managed 程式碼的時候,你會需要穿越大段的CLR自己的代碼比如JIT編譯器的代碼,原因可能是你第一次進入一個函數,或者是你在託管和Unmanaged 程式碼之間進行切換。
調試Windows服務
使用WinDbg,你可以像調試其它應用程式那樣調試Windows服務程式。即可以通過附加進程的方法啟動Windows服務,也可以把WinDbg當作一個即時調試器,並且在代碼中調用DbgBreakPoint 或者 DebugBreak,或者在x86機器上加入一條int 3彙編指令。
調試異常
一個調試器會得到兩次的異常通知-第一次在應用程式有機會處理異常之前(‘first chance exception’);如果應用程式沒有處理這個異常,這時候調試器就會有機會來處理異常(‘second-chance exception’)。如果調試器沒有處理二次機會的異常,應用程式就會退出。
.lastevent或者,!analyze –v命令會給你顯示異常的記錄以及異常拋出所在函數的堆疊追蹤資訊。
你也可以使用 .exr, .cxr以及 .ecxr命令來顯示異常和上下文記錄。同時需要注意的是,你也可以改變first-chance的處理選項。對應的命令就是: sxe, sxd, sxn和sxi。
WinDbg的功能
調試器擴充DLL
所謂的擴充指的是一些DLL,你可以用在調試器內調用並且執行一些自訂的命令。這些DLL必須實現一些特定的函數,並且要滿足一些需求,這樣才能被認為是一個擴充DLL。在下一篇文章內,我們將會瞭解到怎樣寫出一個擴充DLL。所謂的bang(!)命令就是從你的擴充DLL內執行的命令。注意這些DLL是被載入到調試器的進程空間內。
記憶體轉儲檔案
你可以使用轉儲功能來取得一個進程的快照資訊。一個mini-dump通常比較小,除非你使用了全記憶體的minidump(.dump /mf)。通常能夠轉儲控制代碼資訊也是很有用的,命令是 .dump/mfh。一個小型傾印通常包含了所有的線程的堆棧以及一個已被載入的模組的列表。一個全轉儲包含了更多的資訊,比如進程的堆。
崩潰轉儲分析
如果你的windows系統當機,那麼它就會在一個檔案中轉儲實體記憶體中的資料,以及所有的進程資訊。可以通過Control Panel ->System->Advanced->’Startup and Recovery’來配置。你也可以首先把WinDbg配置成為一個即時調試器,然後就可以取得任意一個非正常終止的進程的轉儲(.dump)。注意,從轉儲檔案中分析出代碼中的bug往往是一個複雜費力的過程。
使用以下的步驟來分析一個轉儲檔案:
1) 在WinDbg內,通過 File->’Open Crash Dump’, 指向轉儲檔案。
2) WinDgb會給你顯示應用程式崩潰之時所執行的指令。
3) 正確設定你的符號檔案目錄和原始碼目錄。如果你不能夠匹配正確的符號檔案,想要弄清楚程式的邏輯是非常困難的。如果你能夠把符號檔案匹配到正確版本的原始碼,這是就應該很容易分析出Bug原因。注意,私人符號檔案含有行號資訊並且會盲目的顯示你原始碼中的對應行而不進行任何的檢查;如果你的源碼版本不對,那麼你就不能夠看到匹配彙編代碼的正確源碼。如果你僅僅有公有的符號檔案,你會看到最後一個被調用的函數(棧上的)。
注意調試驅動或者Managed 程式碼是與此有很大不同的。參考《The Windows 2000 Device Driver Book》來獲得調試裝置驅動的技術。
WinDbg的常用設定
符號檔案與檔案夾
如果想更有效調試,你需要符號檔案。符號檔案可以是老式的COFF格式或者就是PDB格式。PDB就是程式資料庫檔案並且包含了公有符號。這些調試器內,你可以使用一系列的地址來讓調試器尋找已經載入的二進位檔案的符號。
作業系統的符號檔案一般儲存在%SYSTEMDIR%Symbols目錄。驅動程式的符號檔案(.DBG或.PDB)一般儲存在和驅動檔案(.sys 檔案)相同的目錄下。私人符號檔案包含的資訊包括:函數,局部以及全域變數,以及用來把彙編代碼和原始碼關聯起來的行號資訊;對於客戶來說,符號檔案一半是公有的-這些檔案僅僅包括公有成員。
你可以通過File-Symbol File Path來設定符號檔案目錄,或者使用 .sympath命令。如果想要添加到網路上符號檔案的引用,添加以下的內容到你的 .sympath
SRV*downstream_store*http://msdl.microsoft.com/download/symbols
使用的命令就是:
.sympath+ SRV*c:/tmp*http://msdl.microsoft.com/download/symbols
C:/tmp就是download_store,所需要的符號檔案會被下載儲存至此。注意這個符號伺服器僅僅開放了公有的符號檔案。
當調試器把一個二進位檔案(DLL或exe)的時候,他會檢查比如檔案名稱,時間戳記以及校正值。如果你有符號資訊,你就可以在調用棧上看到函數名和他們的參數。如果二進位檔案和PDB檔案都來自於你自己的應用程式,你就可以看到比如私人函數,局部變數以及類型這類額外的資訊。
原始碼路徑
你可以通過File->Source File Path來設定源碼路徑,或者使用.srcpath命令。如果你設定了代碼的路徑,當你調試的時候,調試器會通過PDB檔案的行號資訊來顯示相匹配的原始碼。
斷點,跟蹤
· 通過bp命令或者工具列上的斷點圖片來設定軟斷點。
· 通過代碼比如DbgBreakPoint() 或者 KdBreakPoint()來設定硬斷點。
· 在擴充DLL中使用跟蹤函數DbgPrint, KdPrint, OutputDebugString 來把輸出顯示在WinDbg的輸出視窗中。
摘自紅色駭客聯盟(www.7747.net) 原文:http://www.7747.net/Article/200812/31157.html