【正文】
1: mov %edx,%eax 0x8048485 func+53: jmp 0x8048487 func+55 0x8048487 func+55: mov %ebp,%esp 0x8048489 func+57: pop %ebp 0x804848a func+58: ret End of assembler dump. 查看運(yùn)行時(shí)數(shù)據(jù)在你調(diào)試程序時(shí),當(dāng)程序被停住時(shí),你可以使用print命令(簡(jiǎn)寫(xiě)命令為p),或是同義命令inspect來(lái)查看當(dāng)前程序的運(yùn)行數(shù)據(jù)。 表達(dá)式print和許多GDB的命令一樣,可以接受一個(gè)表達(dá)式,GDB會(huì)根據(jù)當(dāng)前的程序運(yùn)行的數(shù)據(jù)來(lái)計(jì)算這個(gè)表達(dá)式,既然是表達(dá)式,那么就可以是當(dāng)前程序運(yùn)行中的const常量、變量、函數(shù)等內(nèi)容。 表達(dá)式的語(yǔ)法應(yīng)該是當(dāng)前所調(diào)試的語(yǔ)言的語(yǔ)法,由于C/C++是一種大眾型的語(yǔ)言,所以,本文中的例子都是關(guān)于C/C++的。 是一個(gè)和數(shù)組有關(guān)的操作符,在后面會(huì)有更詳細(xì)的說(shuō)明。 {type} addr 表示一個(gè)指向內(nèi)存地址addr的類(lèi)型為type的一個(gè)對(duì)象。如果此時(shí)你想查看全局變量的值時(shí),你可以使用“::”操作符: file::variable function::variable 可以通過(guò)這種形式指定你所想查看的變量,是哪個(gè)文件中的或是哪個(gè)函數(shù)中的。39。 另外,需要注意的是,如果你的程序編譯時(shí)開(kāi)啟了優(yōu)化選項(xiàng),那么在用GDB調(diào)試被優(yōu)化過(guò)的程序時(shí),可能會(huì)發(fā)生某些變量不能訪(fǎng)問(wèn),或是取值錯(cuò)誤碼的情況。對(duì)付這種情況時(shí),需要在編譯程序時(shí)關(guān)閉編譯優(yōu)化。關(guān)于編譯器的參數(shù),還請(qǐng)查看編譯器的使用說(shuō)明文檔。比如數(shù)組的一段,或是動(dòng)態(tài)分配的數(shù)據(jù)的大小。例如,你的程序中有這樣的語(yǔ)句: int *array = (int *) malloc (len * sizeof (int))。 輸出格式一般來(lái)說(shuō),GDB會(huì)根據(jù)變量的類(lèi)型輸出變量的值。例如,你想輸出一個(gè)整數(shù)的十六進(jìn)制,或是二進(jìn)制來(lái)查看這個(gè)整型變量的中的位的情況。 d 按十進(jìn)制格式顯示變量。 o 按八進(jìn)制格式顯示變量。 a 按十六進(jìn)制格式顯示變量。 f 按浮點(diǎn)數(shù)格式顯示變量。e39。x命令的語(yǔ)法如下所示: x/n/f/u addr n、f、u是可選的參數(shù)。 f 表示顯示的格式,參見(jiàn)上面。 u 表示從當(dāng)前地址往后請(qǐng)求的字節(jié)數(shù),如果不指定的話(huà),GDB默認(rèn)是4個(gè)bytes。當(dāng)我們指定了字節(jié)長(zhǎng)度后,GDB會(huì)從指內(nèi)存定的內(nèi)存地址開(kāi)始,讀寫(xiě)指定字節(jié),并把其當(dāng)作一個(gè)值取出來(lái)。 n/f/u三個(gè)參數(shù)可以一起使用。 自動(dòng)顯示你可以設(shè)置一些自動(dòng)顯示的變量,當(dāng)程序停住時(shí),或是在你單步跟蹤時(shí),這些變量會(huì)自動(dòng)顯示。 display expr display/fmt expr display/fmt addr expr是一個(gè)表達(dá)式,fmt表示顯示的格式,addr表示內(nèi)存地址,當(dāng)你用display設(shè)定好了一個(gè)或多個(gè)表達(dá)式后,只要你的程序被停下來(lái),GDB會(huì)自動(dòng)顯示你所設(shè)置的這些表達(dá)式的值。于是當(dāng)程序停下后,就會(huì)出現(xiàn)源代碼和機(jī)器指令碼相對(duì)應(yīng)的情形,這是一個(gè)很有意思的功能。如果要同時(shí)刪除幾個(gè),編號(hào)可以用空格分隔,如果要?jiǎng)h除一個(gè)范圍內(nèi)的編號(hào),可以用減號(hào)表示(如:25) disable display dnums... enable display dnums... disable和enalbe不刪除自動(dòng)顯示的設(shè)置,而只是讓其失效和恢復(fù)。GDB會(huì)打出一張表格,向你報(bào)告當(dāng)然調(diào)試中設(shè)置了多少個(gè)自動(dòng)顯示設(shè)置,其中包括,設(shè)置的編號(hào),表達(dá)式,是否enable。 set print address set print address on 打開(kāi)地址輸出,當(dāng)程序顯示函數(shù)信息時(shí),GDB會(huì)顯出函數(shù)的參數(shù)地址。 set print array set print array on 打開(kāi)數(shù)組顯示,打開(kāi)后當(dāng)數(shù)組顯示時(shí),每個(gè)元素占一行,如果不打開(kāi)的話(huà),每個(gè)元素則以逗號(hào)分隔。與之相關(guān)的兩個(gè)命令如下,我就不再多說(shuō)了。如果設(shè)置為0,則表示不限制。 set print nullstop on/off 如果打開(kāi)了這個(gè)選項(xiàng),那么當(dāng)顯示字符串時(shí),遇到結(jié)束符則停止顯示。 set print pretty on 如果打開(kāi)printf pretty這個(gè)選項(xiàng),那么當(dāng)GDB顯示結(jié)構(gòu)體時(shí)會(huì)比較漂亮。 set print sevenbitstrings on/off 設(shè)置字符顯示,是否按“\nnn”的格式顯示,如果打開(kāi),則字符串或字符數(shù)據(jù)按\nnn顯示,如“\065”。 set print union on/off 設(shè)置顯示結(jié)構(gòu)體時(shí),是否顯式其內(nèi)的聯(lián)合體數(shù)據(jù)。 typedef enum {Big_tree, Acorn, Seedling} Tree_forms。 struct thing { Species it。 Bug_forms bug。 }。 當(dāng)打開(kāi)這個(gè)開(kāi)關(guān)時(shí),執(zhí)行 p foo 命令后,會(huì)如下顯示: $1 = {it = Tree, form = {tree = Acorn, bug = Cocoon}} 當(dāng)關(guān)閉這個(gè)開(kāi)關(guān)時(shí),執(zhí)行 p foo 命令后,會(huì)如下顯示: $1 = {it = Tree, form = {...}} show print union 查看聯(lián)合體數(shù)據(jù)的顯示方式 set print object on/off 在C++中,如果一個(gè)對(duì)象指針指向其派生類(lèi),如果打開(kāi)這個(gè)選項(xiàng),GDB會(huì)自動(dòng)按照虛方法調(diào)用的規(guī)則顯示輸出,如果關(guān)閉這個(gè)選項(xiàng)的話(huà),GDB就不管虛函數(shù)表了。 show print object 查看對(duì)象選項(xiàng)的設(shè)置。默認(rèn)是on。 set print vtbl on/off 當(dāng)此選項(xiàng)打開(kāi)時(shí),GDB將用比較規(guī)整的格式來(lái)顯示虛函數(shù)表時(shí)。 show print vtbl 查看虛函數(shù)顯示格式的選項(xiàng)。GDB會(huì)以$1, $2, $3 .....這樣的方式為你每一個(gè)print命令編上號(hào)。這個(gè)功能所帶來(lái)的好處是,如果你先前輸入了一個(gè)比較長(zhǎng)的表達(dá)式,如果你還想查看這個(gè)表達(dá)式的值,你可以使用歷史記錄來(lái)訪(fǎng)問(wèn),省去了重復(fù)輸入。要定義一個(gè)GDB的變量很簡(jiǎn)單只需。GDB的環(huán)境變量和UNIX一樣,也是以$起頭。環(huán)境變量沒(méi)有類(lèi)型,你可以給環(huán)境變量定義任一的類(lèi)型。 show convenience 該命令查看當(dāng)前所設(shè)置的所有的環(huán)境變量。例如: set $i = 0 print bar[$i++]contents 于是,當(dāng)你就不必,print bar[0]contents, print bar[1]contents地輸入命令了。 查看寄存器要查看寄存器的值,很簡(jiǎn)單,可以使用如下命令: info registers 查看寄存器的情況。(包括浮點(diǎn)寄存器) info registers regname ... 查看所指定的寄存器的情況。你同樣可以使用print命令來(lái)訪(fǎng)問(wèn)寄存器的情況,只需要在寄存器名字前加一個(gè)$符號(hào)就可以了。 改變程序的執(zhí)行一旦使用GDB掛上被調(diào)試程序,當(dāng)程序運(yùn)行起來(lái)后,你可以根據(jù)自己的調(diào)試思路來(lái)動(dòng)態(tài)地在GDB中更改當(dāng)前被調(diào)試程序的運(yùn)行線(xiàn)路或是其變量的值,這個(gè)強(qiáng)大的功能能夠讓你更好的調(diào)試你的程序,比如,你可以在程序的一次運(yùn)行中走遍程序的所有分支。如: (gdb) print x=4 x=4這個(gè)表達(dá)式是C/C++的語(yǔ)法,意為把變量x的值修改為4,如果你當(dāng)前調(diào)試的語(yǔ)言是Pascal,那么你可以使用Pascal的語(yǔ)法:x:=4。 跳轉(zhuǎn)執(zhí)行一般來(lái)說(shuō),被調(diào)試程序會(huì)按照程序代碼的運(yùn)行順序依次執(zhí)行。這個(gè)功能可以由GDB的jump命令來(lái)完: jump linespec 指定下一條語(yǔ)句的運(yùn)行點(diǎn)。表式著下一條運(yùn)行語(yǔ)句從哪里開(kāi)始。 注意,jump命令不會(huì)改變當(dāng)前的程序棧中的內(nèi)容,所以,當(dāng)你從一個(gè)函數(shù)跳到另一個(gè)函數(shù)時(shí),當(dāng)函數(shù)運(yùn)行完返回時(shí)進(jìn)行彈棧操作時(shí)必然會(huì)發(fā)生錯(cuò)誤,可能結(jié)果還是非常奇怪的,甚至于產(chǎn)生程序Core Dump。 熟悉匯編的人都知道,程序運(yùn)行時(shí),有一個(gè)寄存器用于保存當(dāng)前代碼所在的內(nèi)存地址。于是,你可以使用“set $pc”來(lái)更改跳轉(zhuǎn)執(zhí)行的地址。如:中斷信號(hào)Ctrl+C。 語(yǔ)法是:signal singal,UNIX的系統(tǒng)信號(hào)量通常從1到15。 single命令和shell的kill命令不同,系統(tǒng)的kill命令發(fā)信號(hào)給被調(diào)試程序時(shí),是由GDB截獲的,而single命令所發(fā)出一信號(hào)則是直接發(fā)給被調(diào)試程序的。你可以使用return命令強(qiáng)制函數(shù)忽略還沒(méi)有執(zhí)行的語(yǔ)句并返回。 強(qiáng)制調(diào)用函數(shù)call expr 表達(dá)式中可以一是函數(shù),以此達(dá)到強(qiáng)制調(diào)用函數(shù)的目的。 另一個(gè)相似的命令也可以完成這一功能——print,print后面可以跟表達(dá)式,所以也可以用他來(lái)調(diào)用函數(shù),print和call的不同是,如果函數(shù)返回void,call則不顯示,print則顯示函數(shù)返回值,并把該值存入歷史數(shù)據(jù)中。一般說(shuō)來(lái),GDB會(huì)根據(jù)你所調(diào)試的程序來(lái)確定當(dāng)然的調(diào)試語(yǔ)言,比如:發(fā)現(xiàn)文件名后綴為“.c”的,GDB會(huì)認(rèn)為是C程序。而后綴是“.f, .F”的,GDB會(huì)認(rèn)為是Fortran程序,還有,后綴為如果是“.s, .S”的會(huì)認(rèn)為是匯編語(yǔ)言。比如一些GDB命令需要用到表達(dá)式或變量時(shí),這些表達(dá)式或變量的語(yǔ)法,完全是根據(jù)當(dāng)前的語(yǔ)言環(huán)境而改變的。并且,如果你當(dāng)前的程序是由幾種不同語(yǔ)言一同編譯成的,那到在調(diào)試過(guò)程中,GDB也能根據(jù)不同的語(yǔ)言自動(dòng)地切換語(yǔ)言環(huán)境。下面是幾個(gè)相關(guān)于GDB語(yǔ)言環(huán)境的命令: show language 查看當(dāng)前的語(yǔ)言環(huán)境。 info frame 查看當(dāng)前函數(shù)的程序語(yǔ)言。 如果GDB沒(méi)有檢測(cè)出當(dāng)前的程序語(yǔ)言,那么你也可以手動(dòng)設(shè)置當(dāng)前的程序語(yǔ)言。 當(dāng)set language命令后什么也不跟的話(huà),你可以查看GDB所支持的語(yǔ)言種類(lèi): (gdb) set language The currently understood settings are: local or auto Automatic setting based on source file c Use the C language c++ Use the C++ language asm Use the Asm language chill Use the Chill language fortran Use the Fortran language java Use the Java language modula2 Use the Modula2 language pascal Use the Pascal language scheme Use the Scheme language 于是你可以在set language后跟上被列出來(lái)的程序語(yǔ)言名,來(lái)設(shè)置當(dāng)前的語(yǔ)言環(huán)境。 6 for(i=0。 i++) 7 { 8 sum+=i。 11 } 12 13 14 int main(void) 15 { 16 int i。 18 for(i=1。 i++) 19 { 20 result += i。 24 printf(result[1250] = %d \n, func(250)