天天看點

如何利用 WinDbg 進行雙機調試

系統在崩潰時可能不能生成記憶體轉儲檔案,這樣的原因有一些。當然,系統挂起而不崩潰的情況也是有的。在這樣各種得不到轉儲檔案的情形下,如何才能才能診斷和調試系統錯誤呢?這就要用到雙機調試啦。(對于挂起的系統,還有另外的辦法可以采用,我将在日後的文章中進行讨論)

其實并不是隻有在生成不了轉儲檔案的情形下才能使用雙機調試,在任何情況下都是可以使用的,尤其是調試核心問題時,雙機調試不必限于轉儲檔案類型,均可獲得一切可以獲得的資訊,相當于完全記憶體轉儲了。而且,雙機調試可以調試到系統啟動階段和之後任意時刻的問題,這是記憶體轉儲做不到的。是以隻要滿足連接配接條件,将兩台機器相連,我們就可以進行雙機調試了。下面我們通過表格比較一下可用的三種連接配接方式:

連接配接類型 說明
COM 使用零數據機(Null-Modem)線纜,也就是兩個頭都是母孔的RS232線,通過COM端口連接配接
1394 利用IEEE 1394線纜連接配接,要求調試機和被調機運作相同版本的至少為Windows XP的系統
USB 2.0 使用一種内置硬體晶片來支援調試的特制 USB 線纜連接配接,要求被調機運作的系統至少為Windows Vista

在雙機調試中,我們一般選擇對硬體和軟體複雜度要求最低的 COM 對接方式進行連接配接。當然,目前很多的筆記型電腦并沒有再保留 COM 端口,那就要采取别的方式進行雙機調試了。這樣,筆記本使用者進行雙機調試就顯得複雜了許多,是以在能生成記憶體轉儲檔案的情況下還是盡量分析記憶體轉儲比較好。另外,在雙機調試之前,除了連接配接好線纜,我們還必須在被調機上做一些設定才能讓我們進行調試。下面我們一起看看需要做哪些設定。

其實要做的設定也不難,就是開啟系統的調試功能。鑒于現在 Windows XP Service Pack 3 的支援周期還沒有結束,我将講解 XP 和 Windows 7 兩個系統下的典型配置方式。(在這裡,我們統一設定連接配接口為 COM1 口,波特率為115200)

對于 Windows XP,由于啟動使用的是 boot.ini 資料,是以我們可以手動修改 C:\boot.ini 檔案(假設您的系統裝在 C 盤),在像 multi(0)disk(0)rdisk(0)partition(1)\WINDOWS="Microsoft Windows XP Professional" /fastdetect 這樣的啟動項目後增加參數 /debug /debugport=com1 /baudrate=115200。當然,編輯 boot.ini 之前,您需要顯示所有隐藏檔案并且取消隐藏受保護的系統檔案,而且還需清除該檔案的隻讀屬性。配置好的結果如下圖所示(該記事本啟用了自動換行,藍色高亮部分其實在同一行):

如何利用 WinDbg 進行雙機調試

除了直接編輯 boot.ini,還可以使用 msconfig 實用程式。啟動 msconfig,切換到 BOOT.INI 頁籤,點選 進階 按鈕,在彈出的對話框中進行如下配置後兩次單擊 确定 來退出 msconfig 即可:

如何利用 WinDbg 進行雙機調試

或者,還有一種推薦的指令行方式來設定:

在 cmd 下鍵入并執行指令:bootcfg /debug ON /port COM1 /baud 115200 /ID 1

成功後會有如下提示:

如何利用 WinDbg 進行雙機調試

這裡的 /ID 開關用于決定對 boot.ini 中的哪一條啟動項進行設定。可用的啟動項可通過執行不帶參數的 bootcfg 指令檢視。更多自定義調試參數的方式請執行 bootcfg /debug /? 查詢。

說到自定義調試參數,那我也得說說預設的調試參數:(預設調試參數即借助 /debug ON 參數單純啟用調試而沒有配置調試口、波特率時的系統預設調試參數)

系統版本 預設調試參數

Windows Vista 之前的 Windows 系統

如 Windows XP

調試口 COM1,波特率 19200 bps。
Windows Vista 及 Windows 7

調試口 COM1,波特率 115200 bps。

[全局預設設定]

說完了 Windows XP 的配置,我們再來說說現行主流系統 Windows 7 的調試配置:

Windows Vista 和 Windows 7 下,就沒有那麼多的方法了。如果采用 Windows 自帶的工具,就隻能使用 bcdedit 指令了。Vista 之後,啟動摒棄了 boot.ini 的方式,而是讀取啟動配置資料庫。為了簡化操作,我們可以使用預設調試配置,是以我們隻需開啟調試即可:

如何利用 WinDbg 進行雙機調試

以管理者身份運作的 cmd 下鍵入并執行指令:(每行一條指令)

bcdedit /bootdebug ON

bcdedit /debug ON

執行後得到的正确結果如下圖所示:

如何利用 WinDbg 進行雙機調試

您還可以通過執行 bcdedit /dbgsettings 指令來檢視目前的調試參數設定。如果您要自定義調試參數,請執行指令 bcdedit /dbgsettings /? 擷取幫助。

好了,做好了被調機的設定,我們還需做調試機的設定,這樣才能進行調試。

由于條件所限,我隻能使用我的筆記型電腦作為調試機,将安裝在本機上的 Windows 7 家庭普通版虛拟機作為被調機,使用 NirSoft 的 StartBlueScreen 程式造成系統崩潰。

接着上面的步驟,此時我們剛剛配置完被調機 Windows 7 家庭普通版,并且尚未重新開機。我們接着應該運作調試機上面安裝的 WinDbg,為了稍後能正确解析堆棧中的函數,我們首先應該點選 File – Symbol File Path…,填入 SRV*DownstreamStore*http://msdl.microsoft.com/download/symbols 後單擊 OK(如果是平時調試您自己的程式,或者存有本地 Symbol,這裡也可填寫本地符号檔案路徑),然後選擇 File – Kernel Debug…,在彈出的 Kernel Debugging 配置對話框中,我們選擇 COM 頁籤,在 Baud Rate 裡面填寫 115200(與被調機調試參數比對),然後單擊 确定 即可。本來接下來就是連接配接零數據機線纜,随後重新開機被調機即可連上進行調試了,可是我們這裡是虛拟示範,沒有真實的零數據機線纜,我們再重新開機被調機之前、在确定 Kernel Debugging 配置對話框之前,我們還得做一些設定:(在此列舉出來是為了友善有興趣做一下本實驗的人們 J)

勾選 Pipe 使用命名管道連接配接

勾選 Reconnect 確定在讀/寫錯誤發生時,WinDbg 自動斷開并重連管道

在 Port 字段填入命名管道名稱(本例中筆者使用 \\.\pipe\eric,具體用法在本文最後解釋)

激活被調機虛拟機視窗(以 Windows Virtual PC 為例),點選 工具 – 設定…, 在左欄選擇 COM1(與被調機系統中設定的調試口一緻),在右欄選擇 命名管道 并在該字段填入與 WinDbg 裡面一緻的管道名稱(本例是 \\.\pipe\eric),然後 确定。

如何利用 WinDbg 進行雙機調試
如何利用 WinDbg 進行雙機調試

設定好了命名管道之後,我們在 WinDbg 的 Kernel Debugging 配置對話框中單擊 确定。在詢問是否 Save WorkSpace 的對話框中,我們選擇 Yes。然後,WinDbg 就等待連接配接命名管道了。好了,後面的步驟就跟使用零數據機線纜連接配接的真實案例一樣了。

接下來重新開機被調機。等待被調機重新開機并進入系統引導階段後,WinDbg 會連上被調機并在 Waiting to reconnect… 狀态下出現新的顯示:

如何利用 WinDbg 進行雙機調試

連上後,我們可以在任意階段,于 WinDbg 内使用 Ctrl+Break 快捷鍵來中斷被調機系統的運作,并配合相應指令進行即時分析。例如,就在這個啟動階段,我們使用 Ctrl+Break 快捷鍵來中斷啟動過程,我們可以看見啟動過程的 UI 動畫也随即停止:

如何利用 WinDbg 進行雙機調試

如果要被調機繼續運作,鍵入 g 并運作或者按下 F5 鍵即可。下面,我們就等待登入系統。登入系統後,我們使用提升權限的 cmd 運作 NirSoft 的系統崩潰軟體來模拟一個平時我們見過的 0xc5 藍屏,指令是 StartBlueScreen 0xc5 0 0 0 0。被調機藍屏後,我們其實看不見以往的藍屏,但是可以在 WinDbg 中立即看見捕獲的資訊,就跟分析記憶體轉儲檔案一樣,我們可以開始以往的分析工作了:

如何利用 WinDbg 進行雙機調試

使用 !anaylze -v 指令,我們就可以定位出,造成藍屏的驅動是 NirSoftBlueScreenDriver.sys。這個分析比較簡單。但是值得注意的是,這個 bugcheck (即 0x000000C5)并不是系統像往常一樣根據錯誤類型自動給出的,而是驅動 NirSoftBlueScreenDriver.sys 直接向 KeBugCheckEx 函數傳遞的參數,這個參數是筆者在利用 StartBlueScreen 程式時傳遞給程式的自定義參數,是以借助 StartBlueScreen 我們可以自定義藍屏的五個參數。

Demo 做到這裡就結束了。在本文的末尾,我給出上文中出現的一些概念的解釋和一些過程的原理剖析及說明:

關于調試所使用的波特率(Baud Rate):可以使用的調試波特率有9600、 19200、38400、57600 和 115200,機關是 比特/秒,WinDbg 預設的設定是 19200 bps,系統的預設設定在上文中已經通過表格給出。從通信的角度解釋,波特率是信源每秒鐘發出的二進制符号的個數,是以我們在雙機調試時,選用越高的波特率就意味着 WinDbg 中越快的解析速度,但選用的波特率在被調機和調試機間應該比對。而且,就算選用最高的 115200 bps,也沒有直接調試本地記憶體轉儲檔案快,不過可以接近。

關于命名管道:命名管道是一個有名字的、實作單向或雙向通信的通信管道,可以是程序間的通信,也可以是跨越網絡的不同主機間不同程序間的通信。管道的名稱由兩部分組成——計算機名和管道名。标準格式為 \\[host_name]\pipe\[pipe_name](方括号内為參數)。對于同一主機,允許有多個同一命名管道的執行個體并且可以由不同的程序打開,但是不同的管道都有屬于自己的管道緩沖區和自己的通訊環境而互不影響,并且命名管道可以支援多個用戶端連接配接一個伺服器端。對于用戶端來說,命名管道可以是 \\[host_name]\pipe\[pipe_name] 形式,也可以是 \\.\pipe\[pipe_name] 形式,其中的"."表示本機。而伺服器端由于隻能指定本機作為主機名,故隻能使用 \\.\pipe\[pipe_name] 的形式。上文例子中的 eric 即為一個 [pipe_name]。另外,在同一主機上,管道名稱是唯一的。一個命名管道一旦被建立就不允許相同名稱的管道再被建立。

關于命名管道的連接配接與通信方式(WinDbg 的 Reconnect 設定涉及到):在伺服器端第一次建立命名管道後等待連接配接,當用戶端連接配接成功後伺服器端的命名管道就用作通訊用途。如果需要再次等待連接配接,伺服器端就需要再次打開命名管道(建立一個命名管道的執行個體)并等待連接配接。對于用戶端,每次打開命名管道後建立與伺服器的連接配接,然後就可以利用命名管道進行通信,如果需要建立第二個連接配接則需要再次打開管道和再次建立連接配接。

在 Windows Vista 及其後的 Windows 系統中,由于不再包含 Dr. Watson,故使用者模式調試器 NTSD 已不複存在。然而,在 Debugging Tools for Windows 中,包含了 NTSD 這一工具。如果您仍想通過 NTSD 來生成完整的使用者模式轉儲(full user-mode dump file),請通路: http://support.microsoft.com/kb/951018/en-us

調試的方法多種多樣,調試器也是多種多樣,本文僅為大家提供一種可行的解決辦法,而不一定是最優的解決辦法。例如,普通的最終使用者遇到的藍屏問題中,在能生成轉儲檔案的情況下,雙機調試就略顯複雜和多餘了。

上文給出了虛機的試驗方法,大家可以動手做做實驗加深對其中過程和原理的了解。