手把手教你玩GDB


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

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

2.       啟動GDB開始調試

1gdb program       ///最常用的用gdb啟動程序,開始調試的方式
2gdb program core   ///gdb查看core dump文件,跟蹤程序core的原因
3gdb program pid    ///gdb調試已經開始運行的程序,指定pid即可

3.       應用程序帶命令行參數的情況,可以通過下面三種方法啟動:

1)啟動GDB的時候,加上--args選項,然后把應用程序和其命令行參數帶在后面,具體格式為:gdb --args program args

2)先按1中講的方法啟動GDB,然后在執行run命令的時候,后面加上參數

3)先按1中講的方法啟動GDB,然后用set argsarglist設置命令行參數,接下來再執行run(r)命令運行程序

4.       退出GDB

1End-of-File(Ctrl+d)

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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM