第一步,編譯生成帶源代碼調(diào)試符號的可執(zhí)行文件:
gcc –o hello –g hello.c
其中-g的意思是生成帶源代碼調(diào)試符號的可執(zhí)行文件hello,不使用-g進(jìn)行編譯的可執(zhí)行文件也可以使用gdb調(diào)試,但是缺少部分調(diào)試信息(如行號、函數(shù)名等)。調(diào)試信息包括用戶程序里的每個(gè)變量的類型和在可執(zhí)行文件里的地址映射以及源代碼的行號。

第二,使用gdb hello進(jìn)入gdb,進(jìn)行調(diào)試階段。啟動(dòng)gdb有以下幾種方式:
gdb filename        //指定要調(diào)試的程序
gdb filename core    //指定要調(diào)試的程序及其coredump文件
gdb filename pid    //指定要調(diào)試的程序及對應(yīng)進(jìn)程id號
可以使用命令行參數(shù)更加詳細(xì)地控制gdb的行為:
-silent            //不顯示進(jìn)入gdb開頭的提示信息
-help(h)        //命令行輔助信息
-se file        //從file中讀取符號,并作為可執(zhí)行文件
-core(c) file        //指定core dump文件file
-c id            //連接到進(jìn)程號為id,與attach命令相似
-x file            //file中存放一系列的gdb命令,執(zhí)行file中的gdb命令
-symbols(s)        //從file中讀取符號,但不作為可執(zhí)行文件
-directory(d) path    //指定路徑path,將path加入到搜索源文件的路徑中
注意:gdb開始運(yùn)行時(shí),它把任何一個(gè)不帶選項(xiàng)前綴的參數(shù)都當(dāng)作一個(gè)可執(zhí)行文件或core文件或進(jìn)程號,具體為:把第一個(gè)前面沒有選項(xiàng)說明的參數(shù)看作加了-se選項(xiàng),而第二個(gè)看作是跟著-c選項(xiàng)后面。在gdb中可以把選項(xiàng)名掐頭去尾,只要保證gdb能唯一判斷是哪個(gè)選項(xiàng)就行。

第三,逐步調(diào)試,部分命令如下:
break(b) [file:] func / line / addr / +num / -num    //某函數(shù)、某行或者某內(nèi)存地址處設(shè)斷點(diǎn),可同時(shí)設(shè)置多個(gè)斷點(diǎn)
break args if COND                    //COND非零時(shí)在args處中斷
tbreak agrs                        //斷點(diǎn)只有效一次
clear 
[file:] func / line / addr / +num / -num        //清楚某種斷點(diǎn),可同時(shí)清除多個(gè)
delete(d) breaknum                    //使用斷點(diǎn)號來清除斷點(diǎn)或觀察點(diǎn),沒有參數(shù)則清除所有斷點(diǎn)
disable(dis) breaknum                    //禁止……
enable 
[once] breaknum                    //啟用或者僅啟用一次……
--------------------------------
watch expr            //expr值改變時(shí)停止程序,用于捕獲錯(cuò)誤很有效
run(r) arg            //從頭開始運(yùn)行程序,并以arg作為參數(shù)(可多個(gè))
continue(c)            //繼續(xù)被中斷的程序,不能用作程序的運(yùn)行啟動(dòng)
step(s)                //單步進(jìn)入,跟蹤到函數(shù)內(nèi)
next(n)                //單步,不進(jìn)入函數(shù)內(nèi)
list(l)                //顯示源代碼(正在執(zhí)行區(qū)域附件10行)
backtrace(bt) / where(w)    //顯示函數(shù)棧的內(nèi)容
print(p) expr            //查看變量或者表達(dá)式的值
display expr            //每次中斷時(shí),顯示expr的值
undisplay 
[expr]        //取消display,沒有參數(shù)的話則取消全部
whatis expr            //顯示expr的資料形態(tài),例如變量類型等
------------------------------
set width 
70            //設(shè)置屏幕列數(shù)
quit(q)                //終止退出
kill(k)                //終止正在調(diào)試的程序,但不退出調(diào)試,可重來
file                //裝入想要調(diào)試的可執(zhí)行文件
shell command            //在gdb中直接運(yùn)行shell命令且不需要退出gdb
help command            //command命令說明
complete arg            //列出所有arg開頭的命令
Esc + Shift + ?            //查看所有命令的列表
------------------------------
attach pidat pid        //接上一個(gè)執(zhí)行的進(jìn)程pid,這會(huì)使pid暫停,中斷任何sleep以及可中斷的系統(tǒng)調(diào)用
detach pid            //解除目前接上的進(jìn)程pid
jump address            //跳到指定的內(nèi)存位置,并開始執(zhí)行
make filename            //不退出gdb就能重新產(chǎn)生可執(zhí)行文件
注意:
(1)有的命令后面可以跟參數(shù),例如step接受一個(gè)參數(shù)表示單步執(zhí)行多少步;有的命令不接受任何參數(shù)。
(2)空行表示重復(fù)上一個(gè)命令;有的命令不可重復(fù),例如run;還有一些重復(fù)后會(huì)產(chǎn)生嚴(yán)重后果,建議不使用空行重復(fù)。
(3)可以使用gdb的info(i)和show命令來查詢程序狀態(tài),每個(gè)命令可以查詢一系列的狀態(tài),具體如下:
info:
info breakpoints           //查看斷點(diǎn)情況
info args                       //查看程序參數(shù)
info display                  //查看所有display
info stack                    //查看函數(shù)棧內(nèi)容,與backtrace相同
info watchpoints          //查看觀察點(diǎn)
show:
show version              //顯示gdb版本號
show copying             //顯示版權(quán)信息
set:
set命令用來為程序設(shè)置運(yùn)行環(huán)境,比如可以用set prompt $ 來把gdb提示符設(shè)置為$。使用set命令可以改變絕大多數(shù)show顯示的信息。

第四,調(diào)試完成后,可以使用strip命令刪除那些帶有-g選項(xiàng)的C編譯程序所生成的信息,釋放一些磁盤空間。
strip命令減少XCOFF對象文件的大小,strip命令從XCOFF對象文件中有選擇地除去行號信息、重定位信息、調(diào)試段、注釋段、文件頭以及所有或部分符號表。一旦使用該命令,則很難調(diào)試文件的符號,因此通常只在已經(jīng)調(diào)試和測試過的生成模塊上使用strip命令。
/usr/binstrip [選項(xiàng)] file 
strip的具體選項(xiàng)信息在這里不作總結(jié)。