Windows調試工具入門-2<?xml:namespace prefix = w ns = "urn:schemas-microsoft-com:office:word" />
<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />
NetRoc
本篇介紹Windows調試工具的基本設置和基本操作方法。這裏我們會用一個測試程序一步一步說明如何使用WinDbg開始調試工作。首先用VC建立一個名爲TestDebug1的控制檯項目,並生成它。
一、符號、源碼和可執行映像路徑設置
使用WinDbg開始調試工作之前,最重要的就是配置好各種環境了。這使得調試器可以正確識別調試目標中的各種變量、函數等等,使得我們能夠進行符號化調試或者源碼調試,而不是只能在一堆彙編代碼中轉圈。
首先來看一下未設置環境之前的樣子。使用剛纔說的TestDebug1項目,爲了對比更清晰,用Release進行編譯,鏈接選項中選中生成map文件和調試信息,如下:
<?xml:namespace prefix = v ns = "urn:schemas-microsoft-com:vml" />
在C/C++選項卡中設置如下:
程序代碼如下:
#include "stdafx.h"
#include <stdio.h>
int main(int argc, char* argv[])
{
printf( "TestDebug1.cpp");
return 0;
}
編譯之後,將Release目錄下的TestDebug1.pdb剪切到其他目錄下(如果沒有這樣做,由於編譯出來的程序中包含了符號文件路徑,調試器可以直接使用exe中的信息找到pdb文件,而不需要設置路徑)。在map文件中可以看到像下面這樣的內容:
0001:00000000 _main 00401000 f TestDebug1.obj
說明main函數位於401000地址處。
通過WinDbg的File->Open Executeable菜單打開TestDebug1.exe,可以在調試器命令窗口中看到下面的內容:
可以看到,調試器自動中斷下來的位置並不是程序入口點,這是由WinDbg實現造成的,這裏先不管它。
調試器命令窗口中可以看到,我們還沒有設置符號路徑,所以WinDbg目前還找不到TestDebug1.exe的任何符號文件。如果想在main函數下斷,這時就不能使用符號,而只能直接使用main的地址。
使用命令bp 00401000在main函數設置斷點,然後F5執行就可以中斷到main的入口處了。斷點設置和基本操作我們將在後面介紹。可以在反彙編窗口中看到這樣的內容:
由於沒有加載任何符號,所以我們看到的都是一堆反彙編代碼和地址。在上一篇中已經介紹過,WinDbg不像OllyDbg這些調試器一樣擁有強大的反彙編分析能力,所以僅僅靠這些看起來一團亂麻的反彙編代碼,調試工作是很難開展下去的。
l 符號路徑的設置
要想在WinDbg中看到程序中的符號,必須通過命令或者WinDbg菜單設置符號路徑。如果還設置了Microsoft公共符號存儲的話,我們不但能夠看到自己程序中的符號,還能夠看到Windows平臺代碼中的符號,這對於調試會提供很好的幫助。
所謂符號路徑,就是包含了程序符號信息的符號文件所在的目錄路徑。通常我們接觸到的符號文件都是以pdb作爲後綴名的。TestDebug1.exe項目如果在項目設置的Link選項中選中了生成調試信息的話(如上圖中的Generate debug info),那麼可以在Debug或者Release目錄中找到它的符號文件TestDebug1.pdb。
我們通過WinDbg的File->Symbol File Path…菜單,或者命令.sympath設置符號路徑爲TestDebug1.pdb所在的目錄。例如剛纔我把生成的pdb文件移動到桌面上了,所以在我的機器上就設置爲:
完成之後在命令窗口輸入.reload命令,我們可以看到反彙編窗口的內容發生改變:
這裏就已經可以看到TestDebug1.exe中的函數、變量名這樣的符號了。而我們也可以通過bp main這樣的命令直接使用符號來操作調試器。
另外,在Local、Watch等窗口中也可以直接使用符號名查看到變量的值、在Call Stack窗口中可以看到函數名,等等。
l 源碼路徑的設置
通過上面的設置,我們可以對程序進行符號化調試。如果擁有程序的代碼,還可以通過設置源碼路徑來進行源碼級調試。
繼續上面的工作,我們通過WinDbg的File->Source File Path…菜單或者.srcpath命令設置源代碼保存的路徑,比如我的機器上是這樣:
確定之後,如果當前指令指針在源文件的代碼範圍內,就會自動跳出源文件窗口。如果沒有跳出,那麼可以通過File->Open Source File…菜單手動打開源文件。由於剛纔設置的斷點還沒有刪除,所以在源碼窗口也能口看到設斷的行被高亮了:
之後就基本上可以完全通過源碼窗口進行設置斷點、查看變量、跟蹤代碼等操作。比只有符號的時候方便了很多。
l 可執行映像路徑的設置
可執行映像路徑一般在調試dump文件時才用得上。需要將這個路徑設置成要調試的exe、dll、sys等可執行文件的路徑。可以通過File->Image File Path…菜單或者.exepath命令設置。
l 使用微軟公共符號存儲
除了使用自己程序的符號之外,調試時還可以使用微軟提供的Windows系統代碼的符號。這需要修改一下我們設置的符號路徑。最方便的辦法是使用.symfix命令。
現在我們來看一下kernel32.dll中的代碼,在反彙編窗口的Offset欄中填入kernel32!OpenProcess,在我的機器上代碼如下:
注意位於764e8ccf處的那個call,現在只能看到調用了kernel32某個偏移處的地址。
使用命令.symfix+ d:/Symbols命令,注意加號要緊靠前面的文本。d:/Symbols是用來保存下載的符號文件的目錄,可以修改成自己需要的路徑。再來打開符號路徑窗口,我們可以看到調試器自動添加了一些內容:
自己在源碼路徑中加入這些新的內容也可以實現相同的效果。詳細的原理請參考WinDbg幫助文檔關於符號服務器設置的部分內容。
接下來再次使用.reload命令重新加載符號,第一次使用到的符號文件會從網上自動下載下來,所以可能有時候會等待一會。完成之後,可以看到反彙編窗口中出現了新的符號內容:
764e8cd8處指令中可以看到這是調用了kernel32導入的函數NtOpenProcess。
微軟提供的Windows符號是我們研究Windows實現的必備利器。首先,符號化的名字有助於調試過程中的記憶和對各種信息的識別;其次,通過名字就常常可以猜測出來函數或變量的作用,很大的方便調試。在各種調試應用中,都強烈建議添加微軟公共符號的引用。
l 設置環境變量
上面介紹的各種路徑都可以通過環境變量來進行設置。將一些常用的路徑保存在環境變量中,就可以避免每次在新的工作空間中進行調試時都要重新設置的麻煩。另外,Visual Studio 2008也共享一些環境變量的設置,這樣在使用IDE調試的時候也能方便的查看到各種符號了。常用的有下面幾個:
環境變量 |
作用 |
_NT_SOURCE_PATH = Path |
指定包含調試目標的源代碼的路徑。Path可以包含後跟一個冒號(:)的驅動器符。用分號分隔多個目錄(;)。 |
_NT_SYMBOL_PATH = Path |
指定包含符號文件的目錄樹的根目錄。Path可以包含後跟一個冒號(:)的驅動器符。用分號分隔多個目錄(;)。 |
_NT_EXECUTABLE_IMAGE_PATH = Path |
指定包含二進制可執行文件的路徑。Path可以包含後跟一個冒號(:)的驅動器符。用分號分隔多個目錄(;)。 |
_NT_DEBUG_LOG_FILE_OPEN = Filename |
(僅CDB和KD) 指定調試器用來記錄輸出的日誌文件。 |
_NT_DEBUG_LOG_FILE_APPEND = Filename |
(僅CDB和KD) 指定調試器用來添加輸出的日誌文件。新的內容每次會添加到這個文件末尾,而不是覆蓋整個文件。 |
如果設置了符號路徑的環境變量的話,可能在初期使用VS 2008調試MFC這樣的有較多導入庫的程序時會下載很多符號文件,使得啓動調試的速度變慢。不過經過一段時間,大部分需要的符號都緩存到本地之後速度就會快起來。
二、配置日誌文件
進行調試時,有時候調試器命令窗口會變得很雜亂,所以常常想用.cls命令清空它。但是這樣會無法再看到之前調試過程中輸出的結果。另外,有時候想保存下整個調試過程的詳細記錄以備後面“回味”。這時,就需要用到日誌文件了。可以將調試器命令窗口中出現過的所有內容都自動記錄到日誌文件中。
創建日誌文件:
- (僅CDB 和KD) 啓動調試器之前,設置_NT_DEBUG_LOG_FILE_OPEN環境變量。
- 啓動調試器時,使用-logo 命令行選項。 如-logo d:/logs/mylogfile.txt
- 使用.logopen命令。如.logopen /t d:/logs/mylogfile.txt
- (僅WinDbg) 使用Edit->Open/Close Log File菜單命令。
將日誌添加到已有的文件末尾:
- (僅CDB 和KD) 啓動調試器之前,設置_NT_DEBUG_LOG_FILE_APPEND環境變量。
- 啓動調試器時,使用-loga命令行選項。如-loga d:/logs/mylogfile.txt
- 使用.logappend命令。 如. logappend/t d:/logs/mylogfile.txt
- (僅WinDbg) 使用Edit->Open/Close Log File菜單命令,然後選擇Append。
關閉日誌文件:
- 使用.logclose命令
- (僅WinDbg) 使用Edit->Open/Close Log File菜單命令,然後選擇Close Open Log File。
三、設置工作空間
工作空間(Workspace)是用來保存WinDbg中工作環境的工具。例如習慣的窗口布局方式、符號路徑、異常處理的設置等等,都可以通過工作空間保存下來,在下次調試的時候就不用再次設置了。
相關的設置都可以通過WinDbg菜單來完成,有下面幾個:
l Open Workspace:這裏只能打開自己通過SaveAs保存的工作空間。
l Save Workspace:按默認的方式保存當前的工作空間。下次再打開相同的調試目標時,就會自動打開這個Workspace。
l Save Workspace As:可以自己設置工作空間的名字,這樣就能通過Open Workspace來手動打開。
l Clear Workspace:可以選擇保存工作空間時要保存哪些設置。
l Delete Workspace:刪除當前保存的工作空間。這裏可以查看到所有默認保存和另存爲的工作空間,用來進行清理是很方便的。
l Save Worlspace in File和Open Workspace in File:將工作空間保存到文件或者從文件打開。可以把自己的工作空間保存下來,這樣通過U盤之類的就能在多臺機器之間方便的使用相同的設置了。
在沒有調試目標的時候調整WinDbg的窗口布局等等設置的話,會保存爲默認的工作空間。下一次打開新目標的時候,就會使用這個設置。通常我們可以設定一個默認的工作空間,然後爲各個單獨的任務保存另外的設置。