Debugging Tools for Windows
|
如果可以分析源代碼而不是反匯編二進(jìn)制代碼,調(diào)試程序會更加容易一些。
當(dāng)源代碼是
C
、
C++
或匯編語言時,
WinDbg
、
CDB
和
KD
可以在調(diào)試中使用它們。
編譯的要求
要進(jìn)行源碼調(diào)試,必須讓編譯器或鏈接器在構(gòu)建二進(jìn)制文件時生成符號文件
(
.pdb
文件
)
。這些符號文件保存了二進(jìn)制指令和源碼行之間的對應(yīng)關(guān)系。
另外,調(diào)試器必須能夠訪問源碼文件,因?yàn)榉栁募胁⒉话瑢?shí)際的源代碼文本。
如果這些都滿足,編譯器和鏈接器還不能對代碼進(jìn)行優(yōu)化。如果代碼經(jīng)過優(yōu)化,在源碼調(diào)試時訪問局部變量會變得很困難,有時候幾乎是不可能的。如果使用
Build
實(shí)用程序作為編譯器和鏈接器,可以將
MSC_OPTIMIZATION
宏設(shè)置為
/Od /Oi
來避免優(yōu)化。
定位符號文件和源碼文件
在源碼模式下調(diào)試,調(diào)試器必須能夠找到源碼文件和符號文件。更多信息,查看
設(shè)置路徑和加載文件
。
開始源碼調(diào)試
只要調(diào)試器擁有當(dāng)前被調(diào)試線程的正確的符號和源碼文件,就可以顯示源碼信息。
如果使用調(diào)試器啟動一個新的用戶模式程序,在
Ntdll.dll
加載程序時初始斷點(diǎn)就會觸發(fā)。由于調(diào)試器不能訪問
Ntdll.dll
的源碼文件,所以這時不能訪問應(yīng)用程序的源碼信息。
要將程序計數(shù)器移動到程序的開始位置,可以在二進(jìn)制代碼入口點(diǎn)設(shè)置斷點(diǎn)。在
調(diào)試器命令窗口
輸入下面的命令。
bp?main
g
之后,程序會被加載起來并在進(jìn)入
main
函數(shù)時停止。
(
當(dāng)然,可以使用任何入口點(diǎn),而不僅僅是
main
。
)
如果程序拋出一個異常,它會中斷到調(diào)試器中。這時源碼信息是可用的。但是,如果通過
CTRL+C
、
CTRL+BREAK
或
Debug?|?Break
命令來中斷,調(diào)試器創(chuàng)建了一個新線程,所以不能看到源代碼。
當(dāng)?shù)竭_(dá)具有源碼文件的線程時,在調(diào)試器命令窗口中就可以執(zhí)行源碼調(diào)試命令了。如果使用
WinDbg
,
Source
窗口
會出現(xiàn)。如果已經(jīng)通過點(diǎn)擊
File
菜單的
Open Source File
打開了源碼窗口,
在
WinDbg GUI
中進(jìn)行源碼調(diào)試
如果使用
WinDbg
,當(dāng)程序計數(shù)器運(yùn)行到調(diào)試器擁有源碼信息的代碼時,一個源碼窗口會出現(xiàn)。
WinDbg
為用戶或它自己打開的每個源文件顯示一個源碼窗口。關(guān)于該窗口的文本屬性的更多信息,查看
Source
窗口
。
之后可以單步執(zhí)行程序、執(zhí)行到斷點(diǎn)或執(zhí)行到光標(biāo)。關(guān)于單步和跟蹤命令的更多信息,查看
控制目標(biāo)
。
源碼模式調(diào)試時,如果單步執(zhí)行程序,合適的源碼窗口會移動到前臺。因?yàn)閼?yīng)用程序執(zhí)行中也會調(diào)用到一些
Microsoft Windows
函數(shù),這時調(diào)試器可能會將
反匯編窗口
移 到前臺
(
因?yàn)檎{(diào)試器不能訪問這些函數(shù)的源碼
)
。當(dāng)程序計數(shù)器又返回到已知的源碼文件,相關(guān)的源碼窗口又會被激活??刂茟?yīng)用程序執(zhí)行時,
WinDbg
將源碼 窗口和匯編窗口中所在的位置用綠色高亮。設(shè)置了斷點(diǎn)的行為紅色
(
啟用的斷點(diǎn)
)
、黃色
(
禁用的斷點(diǎn)
)
或紫色
(
如果當(dāng)前程序計數(shù)器是斷點(diǎn)位置
)
。源代碼會根據(jù) 對語言的分析進(jìn)行著色。如果已經(jīng)選中了源碼窗口,則可以將鼠標(biāo)移動到符號上來查看它的值。關(guān)于這些特性的信息以及如何控制它們,查看
Source
窗口
。
在
WinDbg
中激活源碼調(diào)試,可以使用
L+t
命令、點(diǎn)擊
Debug
菜單的
Source Mode
或在工具欄點(diǎn)擊
Source mode on
按鈕
(
)
。
源碼模式激活時,狀態(tài)欄的
ASM
指示器會變?yōu)榛疑?
源碼模式下單步執(zhí)行某個函數(shù)時,可以查看或修改它的任何局部變量的值。更多信息,查看
讀寫內(nèi)存
。
調(diào)試器命令窗口中的源碼調(diào)試
如果使用
CDB
,則沒有單獨(dú)的源碼窗口。但是,在單步執(zhí)行源碼時還是可以查看運(yùn)行的情況。
使用
CDB
源碼調(diào)試之前,必須通過
.lines?(Toggle Source Line Support)
命令加載源碼行符號,或者使用
-lines
命令行選項
啟動調(diào)試器。
如果使用了
l
l+t
命令,則每次單步執(zhí)行一行源碼。使用
L-t
來一次執(zhí)行一條匯編指令。如果使用
WinDbg
,該命令和選中或清除
Debug
菜單上的
Source Mode
或使用工具欄菜單的效果一樣。
?
l+s
命令在提示符顯示當(dāng)前的代碼行和行號。如果只想顯示行號,使用
l+l
。
如果使用
l+o
和
l+s
,在單步執(zhí)行時只會顯示源碼行。程序計數(shù)器、匯編碼和寄存器信息都不會顯示。這種顯示類型使得可以快速通過源碼來單步調(diào)試而不會看到除了源碼之外的東西。
用
lsp?(Set Number of Source Lines)
命令來指定單步或者執(zhí)行程序時顯示的源碼行數(shù)。
下面的命令序列是一種單步執(zhí)行源碼文件的有效方式。
.lines????????
啟用源碼行信息
bp?main???????
設(shè)置初始斷點(diǎn)
l+t???????????
按源碼行進(jìn)行單步
l+s???????????
命令窗口中顯示源碼行
g?????????????
運(yùn)行程序,直到
"main"
函數(shù)
pr????????????
執(zhí)行一行源碼,并將寄存器切換為不顯示
p?????????????
執(zhí)行一行源碼
?
因?yàn)?
ENTER
會重復(fù)最后一條命令,所以現(xiàn)在可以通過
ENTER
鍵來單步調(diào)試程序了。每一步都會有源碼行、內(nèi)存偏移和匯編代碼顯示出來。
關(guān)于反匯編顯示的更多信息,查看
匯編模式調(diào)試
。
當(dāng)顯示匯編代碼時,在每行右邊末尾會顯示出任何訪問到的內(nèi)存位置。用
d* (Display Memory)
和
e* (Enter Values)
命令來查看或修改這些位置的值。
如果需要查看每條匯編代碼來確認(rèn)偏移或內(nèi)存信息,使用
l-t
來以匯編指令單步而不是用源碼。源碼行信息仍然可以顯示出來。每行源碼和一條或多條匯編指令對應(yīng)。
所有這些命令在
WinDbg
和
CDB
中都可用。可以使用這些命令來在
WinDbg
的
調(diào)試器命令窗口
查看源碼,而不是在源碼窗口中。
源碼行和偏移
使用表達(dá)式求值器來確定和指定源碼行關(guān)聯(lián)的偏移位置也可以進(jìn)行源碼調(diào)試。
下面的命令顯示一個內(nèi)存偏移。
??`
[[
module
!
]
filename
][
:
linenumber
]
`
?
如果省略
filename
,調(diào)試器會搜索和當(dāng)前程序計數(shù)器位置符合的代碼。
不管當(dāng)前使用的基數(shù)是什么,如果沒有添加
0x
前綴,調(diào)試器認(rèn)為
linenumber
是
10
進(jìn)制數(shù)。如果省略了
linenumber
,表達(dá)式的值為和源碼文件關(guān)聯(lián)的可執(zhí)行文件初始地址。
CDB
中只有在使用了
.lines
命令或
-lines
命令行選項來加載源碼行符號時才能識別該語法。
該技術(shù)非常有用,因?yàn)椴还墚?dāng)前的程序計數(shù)器指向什么地方都可以使用。例如,可以使用下面這樣的命令來預(yù)先設(shè)置斷點(diǎn)。
bp?`source.c:31`?
更多信息,查看
源碼行語法
和
使用斷點(diǎn)
。
源碼模式下的單步和跟蹤
以源碼模式調(diào)試時,單行代碼種可能有多個函數(shù)調(diào)用。不能使用
p
和
t
來分開這些調(diào)用。
例如,在下面的命令中,
t
命令會單步進(jìn)入
GetTickCount
和
printf
,而
p
命令會單步步過兩個調(diào)用。
printf(?"%x\n",?GetTickCount()?);
如果在跟蹤進(jìn)入其他調(diào)用時想步過某個調(diào)用,用
.step_filter
(Set Step Filter)
來指定步過哪些調(diào)用。
可以使用
_step_filter
來跳過框架函數(shù)
(
例如,對微軟基本類庫
(Microsoft Foundation Classes,MFC)
或活動模板庫
(ATL)
的調(diào)用
)
。
??2008?Microsoft Corporation
Send feedback on this topic
Debugging Tools for Windows
August 24, 2008
翻譯:NetRoc
Build machine: CAPEBUILD
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯(lián)系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長非常感激您!手機(jī)微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
