編譯時(shí)必須加上參數(shù)-g ,例:g++ -g temp.cpp -o temp.通過Gcc編譯生成可執(zhí)行文件才能用Gdb進(jìn)行調(diào)試。
進(jìn)入gdb界面:gdb temp. 提示符變成(gdb)
(1)查看文件
在Gdb中鍵入”l”(list)就可以查看所載入的文件
(2)設(shè)置斷點(diǎn)
只需在”b”后加入對(duì)應(yīng)的行號(hào)即可(這是最常用的方式,另外還有其他方式設(shè)置斷點(diǎn))。如下所示:
(gdb)b 6
代碼運(yùn)行到第五行之前暫停(并沒有運(yùn)行第五行)。
(3)查看斷點(diǎn)情況
(Gdb) info b
(4)運(yùn)行代碼
Gdb默認(rèn)從首行開始運(yùn)行代碼,可鍵入”r”(run)即可(若想從程序中指定行開始運(yùn)行,可在r后面加上行號(hào))。
(5)查看變量值
查看斷點(diǎn)處的相關(guān)變量值。在Gdb中只需鍵入”p”+變量值即可,如下所示:
(Gdb) p n
Gdb在顯示變量值時(shí)都會(huì)在對(duì)應(yīng)值之前加上”$N”標(biāo)記,它是當(dāng)前變量值的引用標(biāo)記,所以以后若想再次引用此變量就可以直接寫作”$N”,而無需寫冗長的變量名。
(6)單步運(yùn)行
使用命令”n”(next)或”s”(step),它們之間的區(qū)別在于:若有函數(shù)調(diào)用的時(shí)候,”s”會(huì)進(jìn)入該函數(shù)而”n”不會(huì)進(jìn)入該函數(shù)。因此,”s”就類似于VC等工具中的”step in”,”n”類似與VC等工具中的”step over”。
(7)恢復(fù)程序運(yùn)行
使用命令”c”(continue).
在Gdb中,程序的運(yùn)行狀態(tài)有“運(yùn)行”、“暫?!焙汀巴V埂比N,其中“暫?!睜顟B(tài)為程序遇到了斷點(diǎn)或觀察點(diǎn)之類的,程序暫時(shí)停止運(yùn)行,而此時(shí)函數(shù)的地址、函數(shù)參數(shù)、函數(shù)內(nèi)的局部變量都會(huì)被壓入“棧”(Stack)中。故在這種狀態(tài)下可以查看函數(shù)的變量值等各種屬性。但在函數(shù)處于“停止”狀態(tài)之后,“?!本蜁?huì)自動(dòng)撤銷,它也就無法查看各種信息了。
Gdb中的命令主要分為以下幾類:工作環(huán)境相關(guān)命令、設(shè)置斷點(diǎn)與恢復(fù)命令、源代碼查看命令、查看運(yùn)行數(shù)據(jù)相關(guān)命令及修改運(yùn)行參數(shù)命令。以下就分別對(duì)這幾類的命令進(jìn)行講解。
1.工作環(huán)境相關(guān)命令
set args運(yùn)行時(shí)的參數(shù) | 指定運(yùn)行時(shí)參數(shù),如:set args 2 |
show args | 查看設(shè)置好的運(yùn)行參數(shù) |
path dir | 設(shè)定程序的運(yùn)行路徑 |
show paths | 查看程序的運(yùn)行路徑 |
set enVironment var [=value] | 設(shè)置環(huán)境變量 |
show enVironment [var] | 查看環(huán)境變量 |
cd dir | 進(jìn)入到dir目錄,相當(dāng)于shell中的cd命令 |
pwd | 顯示當(dāng)前工作目錄 |
shell command | 運(yùn)行shell的command命令 |
2.設(shè)置斷點(diǎn)與恢復(fù)命令
info b | 查看所設(shè)斷點(diǎn) |
break 行號(hào)或函數(shù)名 <條件表達(dá)式> | 設(shè)置斷點(diǎn) |
tbreak 行號(hào)或函數(shù)名 <條件表達(dá)式> | 設(shè)置臨時(shí)斷點(diǎn),到達(dá)后被自動(dòng)刪除 |
delete [斷點(diǎn)號(hào)] | 刪除指定斷點(diǎn),其斷點(diǎn)號(hào)為”info b”中的第一欄。若缺省斷點(diǎn)號(hào)則刪除所有斷點(diǎn) |
disable [斷點(diǎn)號(hào)]] | 停止指定斷點(diǎn),使用”info b”仍能查看此斷點(diǎn)。同delete一樣,省斷點(diǎn)號(hào)則停止所有斷點(diǎn) |
enable [斷點(diǎn)號(hào)] | 激活指定斷點(diǎn),即激活被disable停止的斷點(diǎn) |
condition [斷點(diǎn)號(hào)] <條件表達(dá)式> | 修改對(duì)應(yīng)斷點(diǎn)的條件 |
ignore [斷點(diǎn)號(hào)]<num> | 在程序執(zhí)行中,忽略對(duì)應(yīng)斷點(diǎn)num次 |
step | 單步恢復(fù)程序運(yùn)行,且進(jìn)入函數(shù)調(diào)用 |
next | 單步恢復(fù)程序運(yùn)行,但不進(jìn)入函數(shù)調(diào)用 |
finish | 運(yùn)行程序,直到當(dāng)前函數(shù)完成返回 |
c | 繼續(xù)執(zhí)行函數(shù),直到函數(shù)結(jié)束或遇到新的斷點(diǎn) |
由于設(shè)置斷點(diǎn)在Gdb的調(diào)試中非常重要,所以在此再著重講解一下Gdb中設(shè)置斷點(diǎn)的方法。
Gdb中設(shè)置斷點(diǎn)有多種方式:其一是按行設(shè)置斷點(diǎn),設(shè)置方法在3.5.1節(jié)已經(jīng)指出,在此就不重復(fù)了。另外還可以設(shè)置函數(shù)斷點(diǎn)和條件斷點(diǎn),在此結(jié)合上一小節(jié)的代碼,具體介紹后兩種設(shè)置斷點(diǎn)的方法。
① 函數(shù)斷點(diǎn)
(gdb) b 函數(shù)名
② 條件斷點(diǎn)
格式為:b 行數(shù)或函數(shù)名 if 表達(dá)式
(gdb) b 8 if i==10
3.Gdb中源碼查看相關(guān)命令
list <行號(hào)>|<函數(shù)名> | 查看指定位置代碼 |
file [文件名] | 加載指定文件 |
forward-search 正則表達(dá)式 | 源代碼前向搜索 |
reverse-search 正則表達(dá)式 | 源代碼后向搜索 |
dir dir | 停止路徑名 |
show directories | 顯示定義了的源文件搜索路徑 |
info line | 顯示加載到Gdb內(nèi)存中的代碼 |
4.Gdb中查看運(yùn)行數(shù)據(jù)相關(guān)命令
指當(dāng)程序處于“運(yùn)行”或“暫?!睜顟B(tài)時(shí),可以查看的變量及表達(dá)式的信息
print 表達(dá)式|變量 | 查看程序運(yùn)行時(shí)對(duì)應(yīng)表達(dá)式和變量的值 |
x <n/f/u> | 查看內(nèi)存變量內(nèi)容。其中n為整數(shù)表示顯示內(nèi)存的長度,f表示顯示的格式,u表示從當(dāng)前地址往后請(qǐng)求顯示的字節(jié)數(shù) |
display 表達(dá)式 | 設(shè)定在單步運(yùn)行或其他情況中,自動(dòng)顯示的對(duì)應(yīng)表達(dá)式的內(nèi)容 |
5.Gdb中修改運(yùn)行參數(shù)相關(guān)命令
Gdb還可以修改運(yùn)行時(shí)的參數(shù),并使該變量按照用戶當(dāng)前輸入的值繼續(xù)運(yùn)行。它的設(shè)置方法為:在單步執(zhí)行的過程中,鍵入命令“set 變量=設(shè)定值”。這樣,在此之后,程序就會(huì)按照該設(shè)定的值運(yùn)行了。下面,筆者結(jié)合上一節(jié)的代碼將n的初始值設(shè)為4,其代碼如下所示:
(Gdb) b 7
Breakpoint 5 at 0x804847a: file test.c, line 7.
(Gdb) r
Starting program: /home/yul/test
The sum of 1-m is 1275
Breakpoint 5, main () at test.c:7
7 for(i=1; i<=50; i++)
(Gdb) set n=4
(Gdb) c
Continuing.
The sum of 1-50 is 1279
Program exited with code 031.
可以看到,最后的運(yùn)行結(jié)果確實(shí)比之前的值大了4。
Gdb的使用切記點(diǎn):
· 在Gcc編譯選項(xiàng)中一定要加入”-g”。
· 只有在代碼處于“運(yùn)行”或“暫停”狀態(tài)時(shí)才能查看變量值。
· 設(shè)置斷點(diǎn)后程序在指定行之前停止。