【文章內(nèi)容簡(jiǎn)介】
nd就行了。七、斷點(diǎn)菜單在C++中,可能會(huì)重復(fù)出現(xiàn)同一個(gè)名字的函數(shù)若干次(函數(shù)重載),在這種情況下,break 不能告訴GDB要停在哪個(gè)函數(shù)的入口。當(dāng)然,你可以使用break 也就是把函數(shù)的參數(shù)類型告訴GDB,以指定一個(gè)函數(shù)。否則的話,GDB會(huì)給你列出一個(gè)斷點(diǎn)菜單供你選擇你所需要的斷點(diǎn)。你只要輸入你菜單列表中的編號(hào)就可以了。如:(gdb) b String::after[0] cancel[1] all[2] file:。 line number:867[3] file:。 line number:860[4] file:。 line number:875[5] file:。 line number:853[6] file:。 line number:846[7] file:。 line number:735 2 4 6Breakpoint 1 at 0xb26c: file , line 867.Breakpoint 2 at 0xb344: file , line 875.Breakpoint 3 at 0xafcc: file , line 846.Multiple breakpoints were set.Use the delete mand to delete unwantedbreakpoints.(gdb)可見(jiàn),GDB列出了所有after的重載函數(shù),你可以選一下列表編號(hào)就行了。0表示放棄設(shè)置斷點(diǎn),1表示所有函數(shù)都設(shè)置斷點(diǎn)。八、恢復(fù)程序運(yùn)行和單步調(diào)試當(dāng)程序被停住了,你可以用continue命令恢復(fù)程序的運(yùn)行直到程序結(jié)束,或下一個(gè)斷點(diǎn)到來(lái)。也可以使用step或next命令單步跟蹤程序。continue [ignorecount]c [ignorecount]fg [ignorecount]恢復(fù)程序運(yùn)行,直到程序結(jié)束,或是下一個(gè)斷點(diǎn)到來(lái)。ignorecount表示忽略其后的斷點(diǎn)次數(shù)。continue,c,fg三個(gè)命令都是一樣的意思。step 單步跟蹤,如果有函數(shù)調(diào)用,他會(huì)進(jìn)入該函數(shù)。進(jìn)入函數(shù)的前提是,此函數(shù)被編譯有debug信息。很像VC等工具中的step in。后面可以加count也可以不加,不加表示一條條地執(zhí)行,加表示執(zhí)行后面的count條指令,然后再停住。next 同樣單步跟蹤,如果有函數(shù)調(diào)用,他不會(huì)進(jìn)入該函數(shù)。很像VC等工具中的step over。后面可以加count也可以不加,不加表示一條條地執(zhí)行,加表示執(zhí)行后面的count條指令,然后再停住。set stepmodeset stepmode on打開(kāi)stepmode模式,于是,在進(jìn)行單步跟蹤時(shí),程序不會(huì)因?yàn)闆](méi)有debug信息而不停住。這個(gè)參數(shù)有很利于查看機(jī)器碼。set stepmod off關(guān)閉stepmode模式。finish運(yùn)行程序,直到當(dāng)前函數(shù)完成返回。并打印函數(shù)返回時(shí)的堆棧地址和返回值及參數(shù)值等信息。until 或 u當(dāng)你厭倦了在一個(gè)循環(huán)體內(nèi)單步跟蹤時(shí),這個(gè)命令可以運(yùn)行程序直到退出循環(huán)體。stepi 或 sinexti 或 ni單步跟蹤一條機(jī)器指令!一條程序代碼有可能由數(shù)條機(jī)器指令完成,stepi和nexti可以單步執(zhí)行機(jī)器指令。與之一樣有相同功能的命令是 “display/i $pc” ,當(dāng)運(yùn)行完這個(gè)命令后,單步跟蹤會(huì)在打出程序代碼的同時(shí)打出機(jī)器指令(也就是匯編代碼)九、信號(hào)(Signals)信號(hào)是一種軟中斷,是一種處理異步事件的方法。一般來(lái)說(shuō),操作系統(tǒng)都支持許多信號(hào)。尤其是UNIX,比較重要應(yīng)用程序一般都會(huì)處理信號(hào)。UNIX定義了許多信號(hào),比如SIGINT表示中斷字符信號(hào),也就是Ctrl+C的信號(hào),SIGBUS表示硬件故障的信號(hào);SIGCHLD表示子進(jìn)程狀態(tài)改變信號(hào); SIGKILL表示終止程序運(yùn)行的信號(hào),等等。信號(hào)量編程是UNIX下非常重要的一種技術(shù)。GDB有能力在你調(diào)試程序的時(shí)候處理任何一種信號(hào),你可以告訴GDB需要處理哪一種信號(hào)。你可以要求GDB收到你所指定的信號(hào)時(shí),馬上停住正在運(yùn)行的程序,以供你進(jìn)行調(diào)試。你可以用GDB的handle命令來(lái)完成這一功能。handle 在GDB中定義一個(gè)信號(hào)處理。信號(hào)可以以SIG開(kāi)頭或不以SIG開(kāi)頭,可以用定義一個(gè)要處理信號(hào)的范圍(如:SIGIOSIGKILL,表示處理從SIGIO信號(hào)到SIGKILL的信號(hào),其中包括SIGIO,SIGIOT,SIGKILL三個(gè)信號(hào)),也可以使用關(guān)鍵字all來(lái)標(biāo)明要處理所有的信號(hào)。一旦被調(diào)試的程序接收到信號(hào),運(yùn)行程序馬上會(huì)被GDB停住,以供調(diào)試。其可以是以下幾種關(guān)鍵字的一個(gè)或多個(gè)。nostop當(dāng)被調(diào)試的程序收到信號(hào)時(shí),GDB不會(huì)停住程序的運(yùn)行,但會(huì)打出消息告訴你收到這種信號(hào)。stop當(dāng)被調(diào)試的程序收到信號(hào)時(shí),GDB會(huì)停住你的程序。print當(dāng)被調(diào)試的程序收到信號(hào)時(shí),GDB會(huì)顯示出一條信息。noprint當(dāng)被調(diào)試的程序收到信號(hào)時(shí),GDB不會(huì)告訴你收到信號(hào)的信息。passnoignore當(dāng)被調(diào)試的程序收到信號(hào)時(shí),GDB不處理信號(hào)。這表示,GDB會(huì)把這個(gè)信號(hào)交給被調(diào)試程序會(huì)處理。nopassignore當(dāng)被調(diào)試的程序收到信號(hào)時(shí),GDB不會(huì)讓被調(diào)試程序來(lái)處理這個(gè)信號(hào)。info signalsinfo handle查看有哪些信號(hào)在被GDB檢測(cè)中。十、線程(Thread Stops)如果你程序是多線程的話,你可以定義你的斷點(diǎn)是否在所有的線程上,或是在某個(gè)特定的線程。GDB很容易幫你完成這一工作。break thread break thread if ...linespec指定了斷點(diǎn)設(shè)置在的源程序的行號(hào)。threadno指定了線程的ID,注意,這個(gè)ID是GDB分配的,你可以通過(guò)“info threads”命令來(lái)查看正在運(yùn)行程序中的線程信息。如果你不指定thread 則表示你的斷點(diǎn)設(shè)在所有線程上面。你還可以為某線程指定斷點(diǎn)條件。如:(gdb) break :13 thread 28 if bartab lim當(dāng)你的程序被GDB停住時(shí),所有的運(yùn)行線程都會(huì)被停住。這方便你你查看運(yùn)行程序的總體情況。而在你恢復(fù)程序運(yùn)行時(shí),所有的線程也會(huì)被恢復(fù)運(yùn)行。那怕是主進(jìn)程在被單步調(diào)試時(shí)。查看棧信息—————當(dāng)程序被停住了,你需要做的第一件事就是查看程序是在哪里停住的。當(dāng)你的程序調(diào)用了一個(gè)函數(shù),函數(shù)的地址,函數(shù)參數(shù),函數(shù)內(nèi)的局部變量都會(huì)被壓入“棧”(Stack)中。你可以用GDB命令來(lái)查看當(dāng)前的棧中的信息。下面是一些查看函數(shù)調(diào)用棧信息的GDB命令:backtrace bt 打印當(dāng)前的函數(shù)調(diào)用棧的所有信息。如:(gdb) bt0 func (n=250) at :61 0x08048524 in main (argc=1, argv=0xbffff674) at :302 0x400409ed in __libc_start_main () from /lib/從上可以看出函數(shù)的調(diào)用棧信息:__libc_start_main main() func()backtrace bt n是一個(gè)正整數(shù),表示只打印棧頂上n層的棧信息。backtrace n bt n n表一個(gè)負(fù)整數(shù),表示只打印棧底下n層的棧信息。如果你要查看某一層的信息,你需要在切換當(dāng)前的棧,一般來(lái)說(shuō),程序停止時(shí),最頂層的棧就是當(dāng)前棧,如果你要查看棧下面層的詳細(xì)信息,首先要做的是切換當(dāng)前棧。frame f n是一個(gè)從0開(kāi)始的整數(shù),是棧中的層編號(hào)。比如:frame 0,表示棧頂,frame 1,表示棧的第二層。up 表示向棧的上面移動(dòng)n層,可以不打n,表示向上移動(dòng)一層。 down 表示向棧的下面移動(dòng)n層,可以不打n,表示向下移動(dòng)一層。 上面的命令,都會(huì)打印出移動(dòng)到的棧層的信息。如果你不想讓其打出信息。你可以使用這三個(gè)命令:selectframe 對(duì)應(yīng)于 frame 命令。upsilently 對(duì)應(yīng)于 up 命令。downsilently 對(duì)應(yīng)于 down 命令。查看當(dāng)前棧層的信息,你可以用以下GDB命令:frame 或 f 會(huì)打印出這些信息:棧的層編號(hào),當(dāng)前的函數(shù)名,函數(shù)參數(shù)值,函數(shù)所在文件及行號(hào),函數(shù)執(zhí)行到的語(yǔ)句。info frame info f 這個(gè)命令會(huì)打印出更為詳細(xì)的當(dāng)前棧層的信息,只不過(guò),大多數(shù)都是運(yùn)行時(shí)的內(nèi)內(nèi)地址。比如:函數(shù)地址,調(diào)用函數(shù)的地址,被調(diào)用函數(shù)的地址,目前的函數(shù)是由什么樣的程序語(yǔ)言寫成的、函數(shù)參數(shù)地址及值、局部變量的地址等等。如:(gdb) info fStack level 0, frame at 0xbffff5d4:eip = 0x804845d in func (:6)。 saved eip 0x8048524called by frame at 0xbffff60csource language c.Arglist at 0xbffff5d4, args: n=250Locals at 0xbffff5d4, Previous frame39。s sp is 0x0Saved registers:ebp at 0xbffff5d4, eip at 0xbffff5d8info args打印出當(dāng)前函數(shù)的參數(shù)名及其值。info locals打印出當(dāng)前函數(shù)中所有局部變量及其值。info catch打印出當(dāng)前的函數(shù)中的異常處理信息。查看源程序—————一、顯示源代碼GDB 可以打印出所調(diào)試程序的源代碼,當(dāng)然,在程序編譯時(shí)一定要加上g的參數(shù),把源程序信息編譯到執(zhí)行文件中。不然就看不到源程序了。當(dāng)程序停下來(lái)以后, GDB會(huì)報(bào)告程序停在了那個(gè)文件的第幾行上。你可以用list命令來(lái)打印程序的源代碼。還是來(lái)看一看查看源代碼的GDB命令吧。list 顯示程序第linenum行的周圍的源程序。list 顯示函數(shù)名為function的函數(shù)的源程序。list 顯示當(dāng)前行后面的源程序。list 顯示當(dāng)前行前面的源程序。一般是打印當(dāng)前行的上5行和下5行,如果顯示函數(shù)是是上2行下8行,默認(rèn)是10行,當(dāng)然,你也可以定制顯示的范圍,使用下面命令可以設(shè)置一次顯示源程序的行數(shù)。set listsize 設(shè)置一次顯示源代碼的行數(shù)。show listsize查看當(dāng)前l(fā)istsize的設(shè)置。list命令還有下面的用法:list , 顯示從first行到last行之間的源代碼。list , 顯示從當(dāng)前行到last行之間的源代碼。list +往后顯示源代碼。一般來(lái)說(shuō)在list后面可以跟以下這們的參數(shù):行號(hào)。+offset 當(dāng)前行號(hào)的正偏移量。offset 當(dāng)前行號(hào)的負(fù)偏移量。哪個(gè)文件的哪一行。函數(shù)名。哪個(gè)文件中的哪個(gè)函數(shù)。*address 程序運(yùn)行時(shí)的語(yǔ)句在內(nèi)存中的地址。二、搜索源代碼不僅如此,GDB還提供了源代碼搜索的命令:forwardsearch search 向前面搜索。reversesearch 全部搜索。其中,就是正則表達(dá)式,也主一個(gè)字符串的匹配模式,關(guān)于正則表達(dá)式,我就不在這里講了,還請(qǐng)各位查看相關(guān)資料。三、指定源文件的路徑某些時(shí)候,用g編譯過(guò)后的執(zhí)行程序中只是包括了源文件的名字,沒(méi)有路徑名。GDB提供了可以讓你指定源文件的路徑的命令,以便GDB進(jìn)行搜索。directory dir 加一個(gè)源文件路徑到當(dāng)前路徑的前面。如果你要指定多