手把手教你玩GDB

第一部分牛刀小試:啓動GDB開始調試linux

1.       編譯帶調試信息的可執行程序:用gcc(g++)編譯的時候帶上-g選項便可c++

2.       啓動GDB開始調試正則表達式

1gdb program       ///最經常使用的用gdb啓動程序,開始調試的方式
2gdb program core   ///gdb查看core dump文件,跟蹤程序core的緣由
3gdb 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多線程

1End-of-File(Ctrl+d)app

2quit或者q編輯器

5.       GDB調試程序的時候執行shell命令:

1shellcommand args(也能夠先執行shell命令,GDB會退出到當前shell,執行完command後,而後在shell中執行exit命令,即可回到GDB

2makemake-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)

2helpclass-name:查看該類型的命令的詳細幫助說明

3help all:列出全部命令的詳細說明

4helpcommand:列出命令command的詳細說明

5aproposword:列出與word這個詞相關的命令的詳細說明

6completeargs:列出全部以args爲前輟的命令

7.       infoshow

1info:用來獲取和被調試的應用程序相關的信息

2show:用來獲取GDB自己設置相關的一些信息

第二部分 Breakpoint, WatchpointCatchpoint

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,但且僅但condtrue時,程序停下來

j. tbreakargs: 設置一個只中止一次的breakpoints,argsbreak命令的同樣。這樣的breakpoint當第一次停下來後,就會被本身刪除

k. rbreakregex: 在全部符合正則表達式regex的函數處設置breakpoint

2info breakpoints [n]:查看第nbreakpoints的相關信息,若是省略了n,則顯示全部breakpoints的相關信息

3pending 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)

4breakpoints的刪除:

a. clear:清除當前stack frame中下一條指令以後的全部breakpoints

b. clearfunction & clear filename:function: 清除函數function入口處的breakpoints

c. clearlinenum & clear filename:linenum: 清除第linenum行處的breakpoints

d. delete [breakpoints] [range…]:刪除由range指定的範圍內的breakpointsrange範圍是指breakpoint的序列號的範圍

5breakpoints的禁用、啓用:

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能夠經過breakif cond來設置,也能夠經過conditionbnum expression來設置,在這裏首先要經過(1)中介紹的命令設置好breakpoints,而後用condition命令來指定某breakpoint的條件,該breakpointbnum指定,條件由expression指定

b. conditionbnum: 取消第bnumbreakpoint的條件

c. ignorebnum count: bnumbreakpoint跳過count次後開始生效

7)指定程序在某個breakpoint處停下來後執行一串命令:

a. 格式:commands [bnum]

         … command-list …

         end

b. 用途:指定程序在第bnumbreakpoint處停下來後,執行由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時,程序都會中止運行

2info watchpoints:查看當前調試的程序中設置的watchpoints相關信息

3watchpointsbreakpoints很相像,都有enable/disabe/delete等操做,使用方法也與breakpoints的相似

3.       Catchpoints相關命令:(catchpoints的做用是讓程序在發生某種事件的時候中止運行,好比C++中發生異常事件,加載動態庫事件)

1)設置catchpoints:

a. catchevent: 當事件event發生的時候,程序中止運行,這裏event的取值有:

1throw: C++拋出異常

2catch: C++捕捉到異常

3exec: exec被調用

4fork: fork被調用

5vfork: vfork被調用

6load:加載動態庫

7loadlibname: 加載名爲libname的動態庫

8unload:卸載動態庫

9unloadlibname: 卸載名爲libname的動態庫

10syscall [args]:調用系統調用,args能夠指定系統調用號,或者系統名稱

b. tcatchevent: 設置只停一次的catchpoint,第一次生效後,該catchpoint被自動刪除

2catchpointsbreakpoints很相像,都有enable/disabe/delete等操做,使用方法也與breakpoints的相似

第三部分經常使用命令介紹

1.         attach process-id/detach

1attachprocess-id: GDB狀態下,開始調試一個正在運行的進程,其進程IDprocess-id

2detach:中止調試當前正在調試有進程,與attach配對試用

2.        kill

1)基本功能:殺掉當前GDB正在調試的應用程序所對應的子進程

2)若是想不退出GDB而對當前正在調試的應用程序從新編譯、連接,能夠在GDB中執行kill殺掉子進程,等編譯、連接完後,再從新執行runGDB即可加載新的可執行程序啓動調試

3.         多線程程序調試相關:

1threadthreadno:切換當前線程到由threadno指定的線程

2info threads:查看GDB當前調試的程序的各個線程的相關信息

3thread apply [threadno] [all]args:對指定(或全部)的線程執行由args指定的命令

4.         多進程程序調試相關(fork/vfork)

1)缺省方式:fork/vfork以後,GDB仍然調試父進程,與子進程不相關

2set follow-fork-modemode:設置GDB行爲,modeparent時,與缺省狀況同樣;modechild時,fork/vfork以後,GDB進入子進程調試,與父進程再也不相關

3show follow-fork-mode:查看當前GDB多進程跟蹤模式的設置

5.         step & stepi

1step [count]:若是沒有指定count, 則繼續執行程序,直到到達與當前源文件不一樣的源文件中時中止;若是指定了count,則重複行上面的過程count

2stepi [count]:若是沒有指定count, 繼續執行下一條機器指令,而後中止;若是指定了count,則重複上面的過程count

3step比較常見的應用場景:在函數func被調用的某行代碼處設置斷點,等程序在斷點處停下來後,能夠用step命令進入該函數的實現中,但前提是該函數編譯的時候把調試信息也編譯進去了,負責step會跳過該函數。

6.         next & nexti

1next [count]:若是沒有指定count, 單步執行下一行程序;若是指定了count,單步執行接下來的count行程序

2nexti [count]:若是沒有指定count, 單步執行下一條指令;若是指定了count,單步執行接下來的count條執行

3stepinexti的區別:nexti在執行某機器指令時,若是該指令是函數調用,那麼程序執行直到該函數調用結束時才中止。

7.         continue [ignore-count]: 喚醒程序,繼續運行,至到遇到下一個斷點,或者程序結束。若是指定ignore-count,那麼程序在接下來的運行中,忽略ignore-count次斷點。

8.         finish & return

1finish:繼續執行程序,直到當前被調用的函數結束,若是該函數有返回值,把返回值也打印到控制檯

2return [expression]:停止當前函數的調用,若是指定了expression,把expresson值當作當前函數的返回值;若是沒有,直接結束當前函數調用

9.         信號的處理

1info signals &info handle:打印全部的信號相關的信息,以及GDB缺省的處理方式

 

2handlesignal keywords: 設置GDB對具體某個信號的處理方式。signal能夠爲信號整數值,也能夠爲SIGSEGV這樣的符號。keywords的取值有:

a. stopnostop:nostop表示當GDB收到指定的信號,不會應用中止程序的執行,只會打印出一條收到信號的消息,所以,nostop也暗含了下面的print;stop則表示,當GDB收到指定的信號,中止應用程序的執行。

b. printnoprint:print表示若是收到指定的信號,打印出一條信息;noprintprint表示相反的意思

c. passnopasspass表示若是收到指定的信號,把該信號通知給應用程序;nopass表示與pass相反的意思

d. ignorenoignore:ignorenopass同義,同理,noignorepass同義

第四部分調用棧(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. backtraceframen或者frameaddr獲得的簡要信息內容:

1)楨序號(Frame number)

2)函數名

3Program counter(除非set print address off)(在程序當前執行到的那一楨,PC不會被顯示)

4)源代碼文件名和行號

5)函數的參數名和傳入的值

b. info frameinfo framen或者info frameaddr獲得的詳細的信息內容:

1)當前楨的地址

2)下一楨的地址

3)上一楨的地址

4)源代碼所用的程序的語言(c/c++)

5)當前楨的參數的地址

6)當前相中局部變量的地址

7PCprogram counter

8)當前楨中存儲的寄存器

4.       info args:查看當前楨中的參數

5.       info locals:查看當前楨中的局部變量

6.       info catch:查看當前楨中的異常處理器(exception handlers

第五部分數據和源代碼(Data and Source Code

1.       list命令(縮寫爲l:

1listlinenum: 打印當前文件中第linenum行周圍的源代碼

2listfunction: 打印function函數週圍的源代碼

3list:在上一次使用list命令的基礎上,再多打印一些源代碼

4list -:打印和上一次使用list命令同樣的源代碼

5set listsizecount: 設置list命令顯示源代碼的行數

6show 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的時候都去設置一下了)

2edit:編輯當前文件

3editnumber: 編輯當前文件的第number

4editfunction: 編輯當前文件的function函數

5editfilename: number: 編輯名爲filename的文件的第number

6editfilename: function: 編輯名爲filename的文件的function函數

3.       設置源代碼目錄

1directorydirname: 設置當前調試的程序的源代碼目錄爲dirname

2directory:將當前調試的程序的源代碼目錄清空

3show directories:打印當前調試的程序的源代碼目錄

4.       print命令打印數據:

1printexpr: 打印表達式expr的值

2print /f expr:f指定的格式打印表達式expr的值

3print:打印上一次打印的表達式的值

4print /f:f指定的形式打印上一次打印的表達式的值

print支持的格式有:x-16進制整數,d-10進制整數,u-10進制無符號整數,o-8進制整數,t-2進制整數,a-地址形式整數,c-字符常量整數,f-浮點數)

5.       GDB支持的表達式:

1Any 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

3file::variable:指定變量varialbe被定義的文件file

4function::varable:指定變量variable被定義的函數function

5{type}address: address指定的內存解釋爲type類型(相似於強制轉型,更增強)

6.       打印內存:x /nfu addr:

1n:重複次數,缺省是1

2f:打印格式,與print的相同的,還有s-C風格字符串,i-機器指令,缺省是x

3u:打印單位大小,b-byteh-halfwords2字節),w-words4字節),g-Giant words8字節)

7.       自動打印:

1display /f expr|addr:以f爲格式,打印expr或者addr

2undisplaydnumsdelete display dnums:刪除第dnumsdisplay

3disable displaydnums:禁用第dnumsdisplay

4enable displaydnums:啓用第dnumsdisplay

5info display:查看全部的display

8.       打印選項:

a. set printfield: 打開field選項

b. set printfield on: 打開field選項

c. set printfield off: 關閉field選項

d. show printfield: 查看field選項的打開、關閉狀況

1set print array:以一種比較好看的方式打印數組,缺省是關閉的

2set print elementsnum-of-elements:設置GDB打印數據時顯示元素的個數,缺省爲200,設爲0表示不限制(unlimited)

3set print null-stop:設置GDB打印字符數組的時候,遇到NULL時中止,缺省是關閉的

4set print pretty:設置GDB打印結構的時候,每行一個成員,而且有相應的縮進,缺省是關閉的

5set print object:設置GDB打印多態類型的時候,打印實際的類型,缺省爲關閉

6set print static-members:設置GDB打印結構的時候,是否打印static成員,缺省是打開的

7set print vtbl:以漂亮的方式打印C++的虛函數表,缺省是關閉的

9.       寄存器:

1info registers:查看當前楨中的各個寄存器的狀況

2info registersregname: 查看指定的寄存器

3)各個寄存器:

 

10.   內存copy:

1dump [format]memory filename start_addr end_addr

2append [binary]memory filename start_addr end_addr

3restorefilename [binary] bias start end

11.   GDB中定義宏:

1info macromacro:查看宏macro的定義

2macro definemacro replacement-list:(還沒實現)

3macro definemacro(arglist) replacement-list:(還沒實現)

4macro undefmacro:(還沒實現)

12.   修改程序的運行(Altering Execution)

1)修改變量值:

a. printv=value: 修改變量值的同時,把修改後的值顯示出來

b. set [var]v=value: 修改變量值,須要注意若是變量名與GDB中某個set命令中的關鍵字同樣的話,前面加上var關鍵字

c. whatisv: 查看變量類型

2signalsignal: 向程序發送信號signal,signal能夠是信號的符號或數字形式,若是signal=0,那麼程序將會繼續運行,程序不會收到任何信號。

3return [expression]:中斷函數執行,從當前位置直接返回。(注意:finish是把函數運行完,再返回,return是直接返回。)

4callexpr: GDB中調用應用程序中的函數

13.   用戶自定義命令:

1)定義一個命令

definecommandname

        

        end

2)條件語句:

if cond-expr

     …

     else

     …

     end

4)循環語句:

whilecond-expr

       …

       end

5)定義一個命令的文檔信息,在helpcommandname的時候能夠顯示:

documentcommandname

        …

        end

6$arg0…$arg9:表示命令行參數,最多10

7help user-defined:查看全部的用戶自定義命令

8show usercommandname:查看自定義命令commandname的定義

9helpcommandname:查看自定義命令commandname的幫助信息

10show max-user-call-depth:查看用戶自定義命令的最大遞歸調用深度

11set max-user-call-depth:設置用戶自定義命令的最大遞歸調用深度

 

轉載自:http://www.wuzesheng.com

相關文章
相關標籤/搜索