---------------------------------------------------
快速入門:
ps aux|grep programname '查看進程ID(pid)
gdb programname
attach pid
b a.cpp:120 '設定斷點
c '讓程式繼續運行
(gdb) shell '切換到shell介面
#exit '重新回到gdb模式
----------------------------------------------------
一、負載檔案
啟動GDB的方法有以下幾種:
1、>gdb [exe]
2、>gdb pid [pid]
GDB啟動時,可以加上一些GDB的啟動開關,詳細的開關可以用gdb -help查看。我在下面只例舉一些比較常用的參數:
-symbols
-s
從指定檔案中讀取符號表。
-se file
從指定檔案中讀取符號表資訊,並把他用在可執行檔中。
-core
-c
調試時core dump的core檔案。
-directory
-d
加入一個源檔案的搜尋路徑。預設搜尋路徑是環境變數中PATH所定義的路徑。
二、運行命令
當以gdb 方式啟動gdb後,gdb會在PATH路徑和目前的目錄中搜尋的源檔案。
在gdb中,運行程式使用r或是run命令。程式的運行,你有可能需要設定下面四方面的事。
1、程式運行參數。
set args 可指定運行時參數。(如:set args 10 20 30 40 50)
show args 命令可以查看設定好的運行參數。
2、運行環境。
path
可設定程式的運行路徑。
show paths 查看程式的運行路徑。
set environment varname [=value] 設定環境變數。如:set env USER=hchen
show environment [varname] 查看環境變數。
3、工作目錄。
cd
相當於shell的cd命令。
pwd 顯示當前的所在目錄。
4、程式的輸入輸出。
info terminal 顯示你程式用到的終端的模式。
使用重新導向控製程序輸出。如:run > outfile
tty命令可以指寫輸入輸出的終端裝置。如:tty /dev/ttyb
三、斷線(break / b)
我們用break命令來設定斷點。正面有幾點設定斷點的方法:
>break +offset / break -offset 在當前行號的前面或後面的offset行停住。offiset為自然數。
>break filename:linenum 在源檔案filename的linenum行處停住。
>break filename:function 在源檔案filename的function函數的入口處停住。
>break *address 在程式啟動並執行記憶體位址處停住。
>break break命令沒有參數時,表示在下一條指令處停住。
>break ... if 在條件成立時停住。比如在迴圈境體中,可以設定break if i=100,表示當i為100時停住程式。
查看斷點時,可使用info命令,如下所示:(註:n表示斷點號)
>info breakpoints [n]
>info break [n]
四、設定觀察點(WatchPoint)
觀察點一般來觀察某個運算式(變數也是一種運算式)的值是否有變化了,如果有變化,馬上停住程式。我們有下面的幾種方法來設定觀察點:
watch
為運算式(變數)expr設定一個觀察點。一量運算式值有變化時,馬上停住程式。
rwatch
當運算式(變數)expr被讀時,停住程式。
awatch
當運算式(變數)的值被讀或被寫時,停住程式。
info watchpoints
列出當前所設定了的所有觀察點。
五、設定捕捉點(CatchPoint)
你可設定捕捉點來補捉程式運行時的一些事件。如:載入共用庫(動態連結程式庫)或是C++的異常。設定捕捉點的格式為:
catch
當event發生時,停住程式。event可以是下面的內容:
1、throw 一個C++拋出的異常。(throw為關鍵字)
2、catch 一個C++捕捉到的異常。(catch為關鍵字)
3、exec 調用系統調用exec時。(exec為關鍵字,目前此功能只在HP-UX下有用)
4、fork 調用系統調用fork時。(fork為關鍵字,目前此功能只在HP-UX下有用)
5、vfork 調用系統調用vfork時。(vfork為關鍵字,目前此功能只在HP-UX下有用)
6、load 或 load 載入共用庫(動態連結程式庫)時。(load為關鍵字,目前此功能只在HP-UX下有用)
7、unload 或 unload 卸載共用庫(動態連結程式庫)時。(unload為關鍵字,目前此功能只在HP-UX下有用)
tcatch
只設定一次捕捉點,當程式停住以後,該點被自動刪除。
六、斷點條件(condit)
在設定斷點時,我們提到過可以設定一個條件,當條件成立時,程式自動pause。一般來說,為斷點設定一個條件,我們使用if關鍵詞,後面跟其斷點條件。 並且,條件設定好後,我們可以用condition命令來修改斷點的條件。(只有break和watch命令支援if,catch目前暫不支援if)
condition [brknum] [expr]
修改斷點號為bnum的停止條件為expression,或者清除斷點號為bnum的停止條件。
還有一個比較特殊的維護命令ignore,你可以指定程式運行時,忽略停止條件幾次。
ignore [brknum] [count]
表示忽略斷點號為bnum的停止條件count次。
GDB還提供的command命令來設定停止點的運行命令。利用它可以在斷點條件達到時批處理一些命令,這對基於GDB的自動化調試是一個強大的支援。
commands [bnum]
... command-list ...
end
例如:
break foo if x>0
commands
printf "x is %d ",x
continue
end
斷點設定在函數foo中,斷點條件是x>0,如果程式被斷住後,也就是,一旦x的值在foo函數中大於0,GDB會自動列印出x的值,並繼續運行程式。
七、單步調試
當程式被停住了,你可以用continue命令恢複程式的運行直到程式結束,或下一個斷點到來。也可以使用step或next命令單步跟蹤程式。
continue [ignore-count]
c [ignore-count]
fg [ignore-count]
恢複程式運行,直到程式結束,或是下一個斷點到來。ignore-count表示忽略其後的斷點次數。continue,c,fg三個命令都是一樣的意思。
step [count]
單步跟蹤,很像.net等工具中的step in。後面可以加count也可以不加,不加表示一條條地執行,加表示執行後面的count條指令,然後再停住。
next [count]
同樣單步跟蹤,如果有函數調用,他不會進入該函數。很像VC等工具中的step over。後面可以加count也可以不加,不加表示一條條地執行,加表示執行後面的count條指令,然後再停住。
set step-mode
set step-mode on
開啟step-mode模式,於是,在進行單步跟蹤時,程式不會因為沒有debug資訊而不停住。這個參數有很利於查看機器碼。
set step-mod off
關閉step-mode模式。
finish
運行程式,直到當前函數完成返回。並列印函數返回時的堆棧地址和傳回值及參數值等資訊。
until 或 u
當你厭倦了在一個迴圈體內單步跟蹤時,這個命令可以運行程式直到退出迴圈體。
stepi 或 si
nexti 或 ni
單步跟蹤一條機器指令。一條程式碼有可能由數條機器指令完成,stepi和nexti可以逐步執行機器指令。與之一樣有相同功能的命令是 “display/i $pc” ,當運行完這個命令後,單步跟蹤會在打出程式碼的同時打出機器指令(也就是彙編代碼)