第一部分牛刀小試:啓動GDB開始調試linux
1. 編譯帶調試信息的可執行程序:用gcc(g++)編譯的時候帶上-g選項便可c++
2. 啓動GDB開始調試正則表達式
(1)gdb program ///最經常使用的用gdb啓動程序,開始調試的方式
(2)gdb program core ///用gdb查看core dump文件,跟蹤程序core的緣由
(3)gdb program pid ///用gdb調試已經開始運行的程序,指定pid便可
3. 應用程序帶命令行參數的狀況,能夠經過下面三種方法啓動:shell
(1)啓動GDB的時候,加上--args選項,而後把應用程序和其命令行參數帶在後面,具體格式爲:gdb --args program argsexpress
(2)先按1中講的方法啓動GDB,而後在執行run命令的時候,後面加上參數vim
(3)先按1中講的方法啓動GDB,而後用set argsarglist設置命令行參數,接下來再執行run(r)命令運行程序數組
4. 退出GDB:多線程
(1)End-of-File(Ctrl+d)app
(2)quit或者q編輯器
5. 在GDB調試程序的時候執行shell命令:
(1)shellcommand args(也能夠先執行shell命令,GDB會退出到當前shell,執行完command後,而後在shell中執行exit命令,即可回到GDB)
(2)makemake-args(等同於shell makemake-args)
6. 在GDB中獲取幫助:
(1)在GDB中執行help命令,能夠獲得如圖1所示的幫助信息:
圖1 GDB幫助菜單
由圖1能夠看出,GDB中的命令能夠分爲八類:別名(aliases)、斷點(breakpoints)、數據(data)、文件(files)、內部(internals)、隱含(obscure)、運行(running)、棧(stack)、狀態(status)、支持(support)、跟蹤點(tracepoints)和用戶自定義(user-defined)。
(2)helpclass-name:查看該類型的命令的詳細幫助說明
(3)help all:列出全部命令的詳細說明
(4)helpcommand:列出命令command的詳細說明
(5)aproposword:列出與word這個詞相關的命令的詳細說明
(6)completeargs:列出全部以args爲前輟的命令
7. info和show:
(1)info:用來獲取和被調試的應用程序相關的信息
(2)show:用來獲取GDB自己設置相關的一些信息
第二部分 Breakpoint, Watchpoint和Catchpoint
1. Breakpoints相關命令:(Breakpoint的做用是讓程序執行到某個特定的地方中止運行)
(1)設置breakpoint:
a. breakfunction: 在函數funtion入口處設置breakpoint
b. break +offset:在程序當前中止的行向前offset行處設置breakpoint
c. break –offset:在程序當前中止的行向衙offset行處設置breakpoint
d. breaklinenum: 在當前源文件的第linenum行處設置breakpoint
e. breakfilename:linenum: 在名爲filename的源文件的第linenum行處設置breakpoint
f. breakfilename:function: 在名爲filename的源文件中的function函數入口處設置breakpoint
g. break *address:在程序的地址address處設置breakpoint
h. break:
i. break … ifcond: …表明上面講到的任意一個可能的參數,在某處設置一個breakpoint,但且僅但cond爲true時,程序停下來
j. tbreakargs: 設置一個只中止一次的breakpoints,args與break命令的同樣。這樣的breakpoint當第一次停下來後,就會被本身刪除
k. rbreakregex: 在全部符合正則表達式regex的函數處設置breakpoint
(2)info breakpoints [n]:查看第n個breakpoints的相關信息,若是省略了n,則顯示全部breakpoints的相關信息
(3)pending breakpoints:是指設置在程序開始調試後加載的動態庫中的位置處的breakpoints
a. set breakpoint pending auto: GDB缺省設置,詢問用戶是否要設置pending breakpoint
b. set breakpoint pending on: GDB當前不能識別的breakpoint自動成爲pending breakpoint
c. set breakpoint pending off: GDB當前不能識別某個breakpoint時,直接報錯
d. show breakpoint pending:查看GDB關於pending breakpoint的設置的行爲(auto, on, off)
(4)breakpoints的刪除:
a. clear:清除當前stack frame中下一條指令以後的全部breakpoints
b. clearfunction & clear filename:function: 清除函數function入口處的breakpoints
c. clearlinenum & clear filename:linenum: 清除第linenum行處的breakpoints
d. delete [breakpoints] [range…]:刪除由range指定的範圍內的breakpoints,range範圍是指breakpoint的序列號的範圍
(5)breakpoints的禁用、啓用:
a. disable [breakpoints] [range…]:禁用由range指定的範圍內的breakpoints
b. enable [breakpoints] [range…]:啓用由range指定的範圍內的breakpoints
c. enable [breakpoints]once [range…]: 只啓用一次由range指定的範圍內的breakpoints,等程序停下來後,自動設爲禁用
d. enable [breakpoints]delete [range…]: 啓用range指定的範圍內的breakpoints,等程序停下來後,這些breakpoints自動被刪除
(6)條件breakpoints相關命令:
a. 設置條件breakpoints能夠經過break …if cond來設置,也能夠經過conditionbnum expression來設置,在這裏首先要經過(1)中介紹的命令設置好breakpoints,而後用condition命令來指定某breakpoint的條件,該breakpoint由bnum指定,條件由expression指定
b. conditionbnum: 取消第bnum個breakpoint的條件
c. ignorebnum count: 第bnum個breakpoint跳過count次後開始生效
(7)指定程序在某個breakpoint處停下來後執行一串命令:
a. 格式:commands [bnum]
… command-list …
end
b. 用途:指定程序在第bnum個breakpoint處停下來後,執行由command-list指定的命令串,若是沒有指定bnum,則對最後一個breakpoint生效
c. 取消命令列表:commands [bnum]
end
d. 例子:
break foo if x>0
commands
silent
printf "x is %d\n",x
continue
end
上面的例子含義:當x>0時,在foo函數處停下來,而後打印出x的值,而後繼續運行程序
2. Watchpoints相關命令:(Watchpoint的做用是讓程序在某個表達式的值發生變化的時候中止運行,達到‘監視’該表達式的目的)
(1)設置watchpoints:
a. watchexpr: 設置寫watchpoint,當應用程序寫expr,修改其值時,程序中止運行
b. rwatchexpr: 設置讀watchpoint,當應用程序讀表達式expr時,程序中止運行
c. awatchexpr: 設置讀寫watchpoint, 當應用程序讀或者寫表達式expr時,程序都會中止運行
(2)info watchpoints:查看當前調試的程序中設置的watchpoints相關信息
(3)watchpoints和breakpoints很相像,都有enable/disabe/delete等操做,使用方法也與breakpoints的相似
3. Catchpoints相關命令:(catchpoints的做用是讓程序在發生某種事件的時候中止運行,好比C++中發生異常事件,加載動態庫事件)
(1)設置catchpoints:
a. catchevent: 當事件event發生的時候,程序中止運行,這裏event的取值有:
1)throw: C++拋出異常
2)catch: C++捕捉到異常
3)exec: exec被調用
4)fork: fork被調用
5)vfork: vfork被調用
6)load:加載動態庫
7)loadlibname: 加載名爲libname的動態庫
8)unload:卸載動態庫
9)unloadlibname: 卸載名爲libname的動態庫
10)syscall [args]:調用系統調用,args能夠指定系統調用號,或者系統名稱
b. tcatchevent: 設置只停一次的catchpoint,第一次生效後,該catchpoint被自動刪除
(2)catchpoints和breakpoints很相像,都有enable/disabe/delete等操做,使用方法也與breakpoints的相似
第三部分經常使用命令介紹
1. attach process-id/detach
(1)attachprocess-id: 在GDB狀態下,開始調試一個正在運行的進程,其進程ID爲process-id
(2)detach:中止調試當前正在調試有進程,與attach配對試用
2. kill
(1)基本功能:殺掉當前GDB正在調試的應用程序所對應的子進程
(2)若是想不退出GDB而對當前正在調試的應用程序從新編譯、連接,能夠在GDB中執行kill殺掉子進程,等編譯、連接完後,再從新執行run,GDB即可加載新的可執行程序啓動調試
3. 多線程程序調試相關:
(1)threadthreadno:切換當前線程到由threadno指定的線程
(2)info threads:查看GDB當前調試的程序的各個線程的相關信息
(3)thread apply [threadno] [all]args:對指定(或全部)的線程執行由args指定的命令
4. 多進程程序調試相關(fork/vfork):
(1)缺省方式:fork/vfork以後,GDB仍然調試父進程,與子進程不相關
(2)set follow-fork-modemode:設置GDB行爲,mode爲parent時,與缺省狀況同樣;mode爲child時,fork/vfork以後,GDB進入子進程調試,與父進程再也不相關
(3)show follow-fork-mode:查看當前GDB多進程跟蹤模式的設置
5. step & stepi
(1)step [count]:若是沒有指定count, 則繼續執行程序,直到到達與當前源文件不一樣的源文件中時中止;若是指定了count,則重複行上面的過程count次
(2)stepi [count]:若是沒有指定count, 繼續執行下一條機器指令,而後中止;若是指定了count,則重複上面的過程count次
(3)step比較常見的應用場景:在函數func被調用的某行代碼處設置斷點,等程序在斷點處停下來後,能夠用step命令進入該函數的實現中,但前提是該函數編譯的時候把調試信息也編譯進去了,負責step會跳過該函數。
6. next & nexti
(1)next [count]:若是沒有指定count, 單步執行下一行程序;若是指定了count,單步執行接下來的count行程序
(2)nexti [count]:若是沒有指定count, 單步執行下一條指令;若是指定了count,單步執行接下來的count條執行
(3)stepi和nexti的區別:nexti在執行某機器指令時,若是該指令是函數調用,那麼程序執行直到該函數調用結束時才中止。
7. continue [ignore-count]: 喚醒程序,繼續運行,至到遇到下一個斷點,或者程序結束。若是指定ignore-count,那麼程序在接下來的運行中,忽略ignore-count次斷點。
8. finish & return
(1)finish:繼續執行程序,直到當前被調用的函數結束,若是該函數有返回值,把返回值也打印到控制檯
(2)return [expression]:停止當前函數的調用,若是指定了expression,把expresson值當作當前函數的返回值;若是沒有,直接結束當前函數調用
9. 信號的處理
(1)info signals &info handle:打印全部的信號相關的信息,以及GDB缺省的處理方式
(2)handlesignal keywords: 設置GDB對具體某個信號的處理方式。signal能夠爲信號整數值,也能夠爲SIGSEGV這樣的符號。keywords的取值有:
a. stop和nostop:nostop表示當GDB收到指定的信號,不會應用中止程序的執行,只會打印出一條收到信號的消息,所以,nostop也暗含了下面的print;而stop則表示,當GDB收到指定的信號,中止應用程序的執行。
b. print和noprint:print表示若是收到指定的信號,打印出一條信息;noprint與print表示相反的意思
c. pass和nopass:pass表示若是收到指定的信號,把該信號通知給應用程序;nopass表示與pass相反的意思
d. ignore和noignore:ignore與nopass同義,同理,noignore與pass同義
第四部分調用棧(Call Stack)
1. 查看調用棧信息:
a. backtrace:顯示程序的調用棧信息,能夠用bt縮寫
b. backtracen: 顯示程序的調用棧信息,只顯示棧頂n楨(frame)
c. backtrace -n:顯示程序的調用棧信息,只顯示棧底部n楨(frame)
d. set backtrace limitn: 設置bt顯示的最大楨層數
e. where,info stack:都是bt的別名,功能同樣
2. 選擇某一楨進行查看:
a. framen: 查看第n楨的信息
b. frameaddr: 查看pc地址爲addr的楨的相關信息
c. upn: 查看當前楨上面第n楨的信息
d. downn: 查看當前楨下面第n楨的信息
3. frame信息內容:
a. 用backtrace、framen或者frameaddr獲得的簡要信息內容:
(1)楨序號(Frame number)
(2)函數名
(3)Program counter(除非set print address off)(在程序當前執行到的那一楨,PC不會被顯示)
(4)源代碼文件名和行號
(5)函數的參數名和傳入的值
b. 用info frame、info framen或者info frameaddr獲得的詳細的信息內容:
(1)當前楨的地址
(2)下一楨的地址
(3)上一楨的地址
(4)源代碼所用的程序的語言(c/c++)
(5)當前楨的參數的地址
(6)當前相中局部變量的地址
(7)PC(program counter)
(8)當前楨中存儲的寄存器
4. info args:查看當前楨中的參數
5. info locals:查看當前楨中的局部變量
6. info catch:查看當前楨中的異常處理器(exception handlers)
第五部分數據和源代碼(Data and Source Code)
1. list命令(縮寫爲l):
(1)listlinenum: 打印當前文件中第linenum行周圍的源代碼
(2)listfunction: 打印function函數週圍的源代碼
(3)list:在上一次使用list命令的基礎上,再多打印一些源代碼
(4)list -:打印和上一次使用list命令同樣的源代碼
(5)set listsizecount: 設置list命令顯示源代碼的行數
(6)show listsize:查看list命令顯示
2. 用edit命令在GDB模式下編輯源代碼:
(1)選擇合適的編輯器,gdb會選擇/bin/ex作爲源代碼編輯器,有些linux發行版上可能會沒有安裝/bin/ex,能夠把編輯器修改成比較常見的vim,具體作法爲:有啓動gdb以前,在命令行執行export EDITOR=/usr/bin/vim(或者能夠在.profile中設置EDITOR這個變量的值爲/usr/bin/vim,這樣就不用每次啓動gdb的時候都去設置一下了)
(2)edit:編輯當前文件
(3)editnumber: 編輯當前文件的第number行
(4)editfunction: 編輯當前文件的function函數
(5)editfilename: number: 編輯名爲filename的文件的第number行
(6)editfilename: function: 編輯名爲filename的文件的function函數
3. 設置源代碼目錄
(1)directorydirname: 設置當前調試的程序的源代碼目錄爲dirname
(2)directory:將當前調試的程序的源代碼目錄清空
(3)show directories:打印當前調試的程序的源代碼目錄
4. print命令打印數據:
(1)printexpr: 打印表達式expr的值
(2)print /f expr:以f指定的格式打印表達式expr的值
(3)print:打印上一次打印的表達式的值
(4)print /f:以f指定的形式打印上一次打印的表達式的值
(print支持的格式有:x-16進制整數,d-10進制整數,u-10進制無符號整數,o-8進制整數,t-2進制整數,a-地址形式整數,c-字符常量整數,f-浮點數)
5. GDB支持的表達式:
(1)Any kind of constant, variable or operator defined by the programming language you are using is valid in an expression inGDB.
(2)@address:把address指定的內存看成數組,語法爲p *array@len
(3)file::variable:指定變量varialbe被定義的文件file
(4)function::varable:指定變量variable被定義的函數function
(5){type}address: 把address指定的內存解釋爲type類型(相似於強制轉型,更增強)
6. 打印內存:x /nfu addr:
(1)n:重複次數,缺省是1
(2)f:打印格式,與print的相同的,還有s-C風格字符串,i-機器指令,缺省是x
(3)u:打印單位大小,b-byte,h-halfwords(2字節),w-words(4字節),g-Giant words(8字節)
7. 自動打印:
(1)display /f expr|addr:以f爲格式,打印expr或者addr
(2)undisplaydnums,delete display dnums:刪除第dnums個display點
(3)disable displaydnums:禁用第dnums個display點
(4)enable displaydnums:啓用第dnums個display點
(5)info display:查看全部的display點
8. 打印選項:
a. set printfield: 打開field選項
b. set printfield on: 打開field選項
c. set printfield off: 關閉field選項
d. show printfield: 查看field選項的打開、關閉狀況
(1)set print array:以一種比較好看的方式打印數組,缺省是關閉的
(2)set print elementsnum-of-elements:設置GDB打印數據時顯示元素的個數,缺省爲200,設爲0表示不限制(unlimited)
(3)set print null-stop:設置GDB打印字符數組的時候,遇到NULL時中止,缺省是關閉的
(4)set print pretty:設置GDB打印結構的時候,每行一個成員,而且有相應的縮進,缺省是關閉的
(5)set print object:設置GDB打印多態類型的時候,打印實際的類型,缺省爲關閉
(6)set print static-members:設置GDB打印結構的時候,是否打印static成員,缺省是打開的
(7)set print vtbl:以漂亮的方式打印C++的虛函數表,缺省是關閉的
9. 寄存器:
(1)info registers:查看當前楨中的各個寄存器的狀況
(2)info registersregname: 查看指定的寄存器
(3)各個寄存器:
10. 內存copy:
(1)dump [format]memory filename start_addr end_addr
(2)append [binary]memory filename start_addr end_addr
(3)restorefilename [binary] bias start end
11. 在GDB中定義宏:
(1)info macromacro:查看宏macro的定義
(2)macro definemacro replacement-list:(還沒實現)
(3)macro definemacro(arglist) replacement-list:(還沒實現)
(4)macro undefmacro:(還沒實現)
12. 修改程序的運行(Altering Execution)
(1)修改變量值:
a. printv=value: 修改變量值的同時,把修改後的值顯示出來
b. set [var]v=value: 修改變量值,須要注意若是變量名與GDB中某個set命令中的關鍵字同樣的話,前面加上var關鍵字
c. whatisv: 查看變量類型
(2)signalsignal: 向程序發送信號signal,signal能夠是信號的符號或數字形式,若是signal=0,那麼程序將會繼續運行,程序不會收到任何信號。
(3)return [expression]:中斷函數執行,從當前位置直接返回。(注意:finish是把函數運行完,再返回,return是直接返回。)
(4)callexpr: 在GDB中調用應用程序中的函數
13. 用戶自定義命令:
(1)定義一個命令
definecommandname
…
end
(2)條件語句:
if cond-expr
…
else
…
end
(4)循環語句:
whilecond-expr
…
end
(5)定義一個命令的文檔信息,在helpcommandname的時候能夠顯示:
documentcommandname
…
end
(6)$arg0…$arg9:表示命令行參數,最多10個
(7)help user-defined:查看全部的用戶自定義命令
(8)show usercommandname:查看自定義命令commandname的定義
(9)helpcommandname:查看自定義命令commandname的幫助信息
(10)show max-user-call-depth:查看用戶自定義命令的最大遞歸調用深度
(11)set max-user-call-depth:設置用戶自定義命令的最大遞歸調用深度
轉載自:http://www.wuzesheng.com