在來源模式中偵錯
如果您可以分析程式碼的來源,而不是反組譯的二進位檔,偵錯應用程式會比較容易。
如果來來源語言為 C、C++ 或元件,WinDbg、CDB 和 KD 可以在偵錯中使用原始程式碼。
編譯需求
若要使用來源偵錯,您必須在建置二進位檔時,讓編譯器或連結器建立符號檔 (.pdb 檔案) 。 這些符號檔會顯示偵錯工具二進位指令如何對應至來源行。
此外,偵錯工具必須能夠存取實際的原始程式檔,因為符號檔不包含實際的來源文字。
如果可能的話,編譯器和連結器不應該優化您的程式碼。 如果程式碼已優化,來源偵錯和區域變數的存取會比較困難,有時幾乎不可能。 如果您使用 Build 公用程式作為編譯器和連結器,請將MSC_OPTIMIZATION宏設定為 /Od /Oi 以避免優化。
尋找符號檔和原始程式檔
若要在來源模式中偵錯,偵錯工具必須能夠找到來源檔案和符號檔。 如需詳細資訊,請參閱 來源路徑。
開始來源偵錯
每當偵錯工具有正在偵錯之執行緒的適當符號和來源檔案時,偵錯工具就可以顯示來源資訊。
如果您使用偵錯工具啟動新的使用者模式應用程式,則 Ntdll.dll 載入應用程式時,就會發生初始中斷。 因為偵錯工具無法存取 Ntdll.dll 來源檔案,所以您目前無法存取應用程式的來源資訊。
若要將程式計數器移至應用程式的開頭,請在進入點將中斷點新增至您的二進位檔。 在 [ 偵錯工具命令] 視窗中,輸入下列命令。
bp main
g
然後載入應用程式,並在輸入 main 函式時停止。 (當然,您可以使用任何進入點,而不只是 main.)
如果應用程式擲回例外狀況,它會中斷至偵錯工具。 此時會提供來源資訊。 不過,如果您使用 CTRL+C、 CTRL+BREAK或偵錯發出中斷 |中斷命令,偵錯工具會建立新的執行緒,因此您無法看到原始程式碼。
到達來源檔案的執行緒之後,您可以使用 [偵錯工具命令] 視窗來執行來源偵錯命令。 如果您使用 WinDbg, [來源] 視窗 隨即出現。 如果您已按一下 [檔案] 功能表上的 [開放原始碼檔案] 來開啟 [來源] 視窗,WinDbg 通常會為來源建立新的視窗。 您可以關閉上一個視窗,而不會影響偵錯程式。
WinDbg GUI 中的來源偵錯
如果您使用 WinDbg,只要程式計數器位於偵錯工具具有來源資訊的程式碼中,就會立即顯示 [來源] 視窗。
WinDbg 會針對您或 WinDbg 開啟的每個來源檔案顯示一個 [來源] 視窗。 如需此視窗之文字屬性的詳細資訊,請參閱 來源 Windows。
然後,您可以逐步執行應用程式,或執行至中斷點或游標。 如需逐步執行和追蹤命令的詳細資訊,請參閱 控制目標。
如果您是在來源模式中,適當的 [來源] 視窗會在您逐步執行應用程式時移至前景。 由於在應用程式執行期間也會呼叫 Microsoft Windows 常式,因此偵錯工具可能會在發生這種呼叫時,將反 組解碼視窗 移至前景 (,因為偵錯工具無法存取這些函式的來源) 。 當程式計數器返回已知的原始程式檔時,適當的 [來源] 視窗會變成作用中。
當您流覽應用程式時,WinDbg 會在 [來源] 視窗和 [反組解碼] 視窗中醒目提示您的位置。 設定中斷點的行也會反白顯示。 原始程式碼會根據語言的剖析來著色。 如果已選取 [來源] 視窗,您可以將滑鼠停留在符號上,以評估它。 如需這些功能及其控制方式的詳細資訊,請參閱 來源 Windows。
若要在 WinDbg 中啟用來源模式,請使用l+t命令,按一下偵錯功能表上的來源模式,或按一下按鈕上的來源模式。 當來源模式處於作用中狀態時, ASM 指標會出現在狀態列上無法使用。
當您在來源模式中逐步執行函式時,可以檢視或改變任何區域變數的值。 如需詳細資訊,請參閱 讀取和寫入記憶體。
偵錯工具命令視窗中的來源偵錯
如果您使用 CDB,則沒有個別的 [來源] 視窗。 不過,當您逐步執行來源時,您仍然可以檢視進度。
在 CDB 中執行來源偵錯之前,您必須發出 .lines (切換原始程式列支援) 命令,或使用 -lines 命令列選項啟動偵錯工具,來載入源行符號。
如果您執行 l+t 命令,所有程式逐步執行都會一次執行一個原始程式列。 使用 l-t 一次逐步執行一個元件指令。 如果您使用 WinDbg,此命令的效果與選取或清除 [偵錯] 功能表上的 [來源模式] 相同,或使用工具列按鈕。
l+s命令會在提示字元中顯示目前的源行和行號。 如果您只想看到行號,請改用 l+l 。
如果您使用 l+o 和 l+s,則當您逐步執行程式時,只會顯示來源行。 程式計數器、反組解碼和暫存器資訊會隱藏。 這種顯示可讓您快速逐步執行程式碼,並檢視來源。
您可以使用 lsp (設定來源行數) 命令,指定當您逐步執行或執行應用程式時,確切顯示多少個來源行。
下列命令序列是逐步執行原始程式檔的有效方式。
.lines enable source line information
bp main set initial breakpoint
l+t stepping will be done by source line
l+s source lines will be displayed at prompt
g run program until "main" is entered
pr execute one source line, and toggle register display off
p execute one source line
因為 ENTER 會重複最後一個命令,所以您現在可以使用 ENTER 鍵逐步執行應用程式。 每個步驟都會顯示來源行、記憶體位移和元件程式碼。
如需如何解譯反組解碼顯示的詳細資訊,請參閱 在元件模式中偵錯。
顯示元件程式碼時,正在存取的任何記憶體位置都會顯示在行右端。 您可以使用 d* (顯示記憶體) 和 e* (Enter Values) 命令來檢視或變更這些位置中的值。
如果您必須檢視每個元件指令來判斷位移或記憶體資訊,請使用 l-t 逐步執行元件指令,而不是來源行。 源行資訊仍可顯示。 每個來源行都會對應至一或多個元件指令。
所有這些命令都可在 WinDbg 和 CDB 中使用。 您可以使用 命令,從 WinDbg 的 [偵錯工具命令] 視窗 檢視源行資訊,而不是從 [來源] 視窗檢視。
來源行和位移
您也可以使用運算式評估工具來判斷對應至特定來源行的位移,以執行來源偵錯。
下列命令會顯示記憶體位移。
? `[[module!]filename][:linenumber]`
如果您省略 檔案名,偵錯工具會搜尋對應至目前程式計數器的來源檔案。
除非在偵錯工具之前新增0x,否則偵錯工具會以十進位數的形式讀取它,而不論目前的預設基數為何。 如果您省略 此運算式,運算式會評估為對應至原始程式檔之可執行檔的初始位址。
只有在 .lines 命令或 -lines 命令列選項已載入源行符號時,才能在 CDB 中瞭解此語法。
這項技術非常多用途,因為不論程式計數器指向的位置為何,您都可以使用它。 例如,這項技術可讓您使用下列命令預先設定中斷點。
bp `source.c:31`
來源模式中的逐步執行和追蹤
當您在來源模式中偵錯時,單一來源行上可能會有多個函式呼叫。 您無法使用 p 和 t 命令來分隔這些函式呼叫。
例如,在下列命令中, t 命令會逐步執行 GetTickCount 和 printf,而 p 命令會逐步執行這兩個函式呼叫。
printf( "%x\n", GetTickCount() );
如果您想要在追蹤到其他呼叫時逐步執行某些呼叫,請使用 .step_filter (設定步驟篩選) 來指出要逐步執行哪些呼叫。
例如,您可以使用 _step_filter 篩選出架構函式 (,例如 Microsoft Foundation Classes (MFC) 或 Active Template Library (ATL) 呼叫) 。