GDB的命令很多,本文不會全部介紹,僅會介紹一些最常用的。在介紹之前,先介紹GDB中的一個非常有用的功能:補齊功能。它就如同Linux下SHELL中的命令補齊一樣。當你輸入一個命令的前幾個字符,然後輸入TAB鍵,如果沒有其它命令的前幾個字符與此相同,SHELL將補齊此命令。如果有其它命令的前幾個字符與此相同,你會聽到一聲警告聲,再輸入TAB鍵,SHELL將所有前幾個字符與此相同的命令全部列出。而GDB中的補齊功能不僅能補齊GDB命令,而且能補齊參數。
本文將先介紹常用的命令,然後結合一個具體的例子來演示如何實際使用這些命令。下面的所有命令除了第一條啟動GDB命令是在SHELL下輸入的,其余都是GDB內的命令。大部分GDB內的命令都可以僅輸入前幾個字符,只要不與其它指令沖突。如quit可以簡寫為q,因為以q打頭的命令只有quit。List可以簡寫為l,等等。
1.啟動GDB
你可以輸入GDB來啟動GDB程序。GDB程序有許多參數,在此沒有必要詳細介紹,但一個最為常用的還是要介紹的:如果你已經編譯好一個程序,我們假設文件名為hello,你想用GDB調試它,可以輸入gdb hello來啟動GDB並載入你的程序。如果你僅僅啟動了GDB,你必須在啟動後,在GDB中再載入你的程序。
2.載入程序 === file
在GDB內,載入程序很簡單,使用file命令。如file hello。當然,程序的路徑名要正確。
退出GDB === quit
在GDB的命令方式下,輸入quit,你就可以退出GDB。你也可以輸入'C-d'來退出GDB。
3.運行程序 === run
當你在GDB中已將要調試的程序載入後,你可以用run命令來執行。如果你的程序需要參數,你可以在run指令後接著輸入參數,就象你在SHELL下執行一個需要參數的命令一樣。
4.查看程序信息 === info
info指令用來查看程序的信息,當你用help info查看幫助的話,info指令的參數足足占了兩個屏幕,它的參數非常多,但大部分不常用。我用info指令最多的是用它來查看斷點信息。
4.1 查看斷點信息
info br
br是斷點break的縮寫,記得GDB的補齊功能吧。用這條指令,你可以得到你所設置的所有斷點的詳細信息。包括斷點號,類型,狀態,內存地址,斷點在源程序中的位置等。
4.2 查看當前源程序
info source
4.3 查看堆棧信息
info stack
用這條指令你可以看清楚程序的調用層次關系。
4.4 查看當前的參數
info args
5.列出源一段源程序 === list
5.1 列出某個函數
list FUNCTION
5.2 以當前源文件的某行為中間顯示一段源程序
list LINENUM
5.3 接著前一次繼續顯示
list
5.4 顯示前一次之前的源程序
list -
5.5 顯示另一個文件的一段程序
list FILENAME:FUNCTION 或 list FILENAME:LINENUM
6.設置斷點 === break
現在我們將要介紹的也許是最常用和最重要的命令:設置斷點。無論何時,只要你的程序已被載入,並且當前沒有正在運行,你就能設置,修改,刪除斷點。設置斷點的命令是break。有許多種設置斷點的方法。如下:
6.1 在函數入口設置斷點
break FUNCTION
6.2 在當前源文件的某一行上設置斷點
break LINENUM
6.3 在另一個源文件的某一行上設置斷點
break FILENAME:LINENUM
6.4 在某個地址上設置斷點,當你調試的程序沒有源程序是,這很有用
break *ADDRESS
除此之外,設置一個斷點,讓它只有在某些特定的條件成立時程序才會停下,我們可以稱其為條件斷點。這個功能很有用,尤其是當你要在一個程序會很多次執行到的地方設置斷點時。如果沒有這個功能,你必須有極大的耐心,加上大量的時間,一次一次讓程序斷下,檢查一些值,接著再讓程序繼續執行。事實上,大部分的斷下並不是我們所希望的,我們只希望在某些條件下讓程序斷下。這時,條件斷點就可以大大提高你的效率,節省你的時間。條件斷點的命令如下,在後面的例子中會有示例。
6.5 條件斷點
break ...if COND
COND是一個布爾條件表達式,語法與C語言中的一樣。條件斷點與一般的斷點不同之處是每當程序執行到斷點處,都要計算條件表達式,如果為真,程序才會斷下,否則程序會一直執行下去。
7.其它斷點操作
GDB給每個斷點賦上一個整數數字,這個數字在操作斷點時起到重要作用,它實際上就代表相應的斷點。GDB中的斷點有四種狀態:
有效(Enabled)
禁止(Disabled)
一次有效(Enabled once)
有效後刪除(Enabled for deletion)
在上面的四個狀態有效和禁止都很好理解,禁止就是讓斷點暫時失效。一次有效就是當程序在此斷點斷下後,斷點狀態自動變為禁止狀態。有效後刪除就是當程序在此斷點斷下後,斷點被刪除。實際上,後兩種狀態一般不會碰到。
當你設置一個斷點後,它的確省狀態是有效。你可以用enable和disable指令來設置斷點的狀態為有效或禁止。例如,如果你想禁止2號斷點,可以用下面的指令:
disable 2
相應的,如果想刪除2號斷點,可以有下面的指令:
delete 2
8.設置監視點 === watch
當你調試一個很大的程序,並且在跟蹤一個關鍵的變量時,發現這個變量不知在哪兒被改動過,如何才能找到改動它的地方。這時你可以使用watch命令。簡單地說,監視點可以讓你監視某個表達式或變量,當它被讀或被寫時讓程序斷下。watch命令的用法如下:
watch EXPRESSION
watch指令是監視被寫的,當你想監視某個表達式或變量被讀的話,需要使用rwatch指令,具體用法是一樣的。要注意的是,監視點有硬件和軟件兩種方式,如果可能Linux盡可能用硬件方式,因為硬件方式在速度上要大大快於軟件方式。軟件方式由於要在每次執行一條指令後都要檢查所要監視的值是否被改變,因此它的執行速度會大大降低。同時它也無法設置成被讀時讓程序斷下,因為讀操作不會改變值,所以GDB無法檢測到讀操作。幸運的是,目前的PC機基本都支持硬件方式。如果你想確認一下你的機器是否支持硬件,你可以在調試程序時用watch設置一個監視點,如果GDB向你顯示:
Hardware watchpoint NUM: EXPR
那麼你可以放心了,你的機器支持硬件方式。
9.檢查數據
最常用的檢查數據的方法是使用print命令。
print exp
print指令打印exp表達式的值。卻省情況下,表達式的值的打印格式依賴於它的數據類型。但你可以用一個參數/F來選擇輸出的打印格式。F是一個代表某種格式的字母,詳細可參考輸出格式一節。表達式可以是常量,變量,函數調用,條件表達式等。但不能打印宏定義的值。表達式exp中的變量必須是全局變量或當前堆棧區可見的變量。否則GDB會顯示象下面的一條信息:
No symbol "varible" in current context
10.修改變量值
在調試程序時,你可能想改變一個變量的值,看看在這種情況下會發生什麼。用set指令可以修改變量的值:
set varible=value
例如你想將一個變量tmp的值賦為10,
set tmp=10
11.檢查內存值
檢查內存值的指令是x,x是examine的意思。用法如下:
x /NFU ADDR
其中N代表重復數,F代表輸出格式(見2.13),U代表每個數據單位的大小。U可以去如下值:
b :字節(byte)
h :雙字節數值
w :四字節數值
g :八字節數值
因此,上面的指令可以這樣解釋:從ADDR地址開始,以F格式顯示N個U數值。例如:
x/4ub 0x4000
會以無符號十進制整數格式(u)顯示四個字節(b),0x4000,0x4001,0x4002,0x4003。
12.輸出格式
缺省情況下,輸出格式依賴於它的數據類型。但你可以改變輸出格式。當你使用print命令時,可以用一個參數/F來選擇輸出的打印格式。F可以是以下的一些值:
'x' 16進制整數格式
'd' 有符號十進制整數格式
'u' 無符號十進制整數格式
'f' 浮點數格式
13.單步執行指令
單步執行指令有兩個step和next。Step可以讓你跟蹤進入一個函數,而next指令則不會進入函數。
14.繼續執行指令
當程序被斷下後,你查看了所需的信息後,你會希望程序執行下去,輸入 continue, 程序會繼續執行下去。
15.幫助指令help
在GDB中,如果想知道一條指令的用法,最方便的方法是使用help。使用方法很簡單,在help後跟上指令名。例如,想知道list指令用法,輸入
help list