在來源模式中偵錯

如果您可以分析程式碼的來源,而不是反組譯的二進位檔,偵錯應用程式會比較容易。

如果來來源語言為 C、C++ 或元件,WinDbg、CDB 和 KD 可以在偵錯中使用原始程式碼。

編譯需求

若要使用來源偵錯,您必須在建置二進位檔時,讓編譯器或連結器建立符號檔 (.pdb 檔案) 。 這些符號檔會顯示偵錯工具二進位指令如何對應至來源行。

此外,偵錯工具必須能夠存取實際的原始程式檔,因為符號檔不包含實際的來源文字。

如果可能的話,編譯器和連結器不應該優化您的程式碼。 如果程式碼已優化,來源偵錯和區域變數的存取會比較困難,有時幾乎不可能。 如果您使用 Build 公用程式作為編譯器和連結器,請將MSC_OPTIMIZATION宏設定為 /Od /Oi 以避免優化。

尋找符號檔和原始程式檔

若要在來源模式中偵錯,偵錯工具必須能夠找到來源檔案和符號檔。 如需詳細資訊,請參閱 來源路徑

開始來源偵錯

每當偵錯工具有正在偵錯之執行緒的適當符號和來源檔案時,偵錯工具就可以顯示來源資訊。

如果您使用偵錯工具啟動新的使用者模式應用程式,則 Ntdll.dll 載入應用程式時,就會發生初始中斷。 因為偵錯工具無法存取 Ntdll.dll 來源檔案,所以您目前無法存取應用程式的來源資訊。

若要將程式計數器移至應用程式的開頭,請在進入點將中斷點新增至您的二進位檔。 在 [ 偵錯工具命令] 視窗中,輸入下列命令。

bp main
g

然後載入應用程式,並在輸入 main 函式時停止。 (當然,您可以使用任何進入點,而不只是 main.)

如果應用程式擲回例外狀況,它會中斷至偵錯工具。 此時會提供來源資訊。 不過,如果您使用 CTRL+CCTRL+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+ol+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` 

如需詳細資訊,請參閱 源行語法 和使用 中斷點

來源模式中的逐步執行和追蹤

當您在來源模式中偵錯時,單一來源行上可能會有多個函式呼叫。 您無法使用 pt 命令來分隔這些函式呼叫。

例如,在下列命令中, t 命令會逐步執行 GetTickCountprintf,而 p 命令會逐步執行這兩個函式呼叫。

printf( "%x\n", GetTickCount() );

如果您想要在追蹤到其他呼叫時逐步執行某些呼叫,請使用 .step_filter (設定步驟篩選) 來指出要逐步執行哪些呼叫。

例如,您可以使用 _step_filter 篩選出架構函式 (,例如 Microsoft Foundation Classes (MFC) 或 Active Template Library (ATL) 呼叫) 。