1. 程式人生 > >GDB常用調試命令以及多進程多線程調試

GDB常用調試命令以及多進程多線程調試

star 調用 次循環 rgs 靈活 機器碼 cor trac 讓我

轉載自:http://blog.csdn.net/freeelinux/article/details/53700266

一:普通命令

1.list命令

  • list linenum 顯示程序第linenum行周圍的程序
  • list function 顯示函數名為function的函數的源程序
  • list 顯示當前行後面的源程序
  • list - 顯示當前行前面的源程序

2.run(r)

運行命令。
  • run args run命令可以直接接命令行參數值,也可以在執行run之前通過 set args + 參數值實現。

3.break(b)

打斷點,使用方法:
  • b linenum 在某行打斷點
  • b +offset/-offset 在當前行號的前面或後面offset停住
  • b filename:linenum 在某文件的某行打斷點
  • b filename:function 在某文件某個函數入口停住
  • b *address 在程序的運行地址處停住
  • b 沒有參數在下一句停住
  • b where if condition 當某個條件滿足時,在某一行停住(這個很有用,比如b 10 if ret == 5)
對於break命令,我們要靈活使用。例如打多個斷點。多線程程序中我們可以主函數中線程創建後立即打斷點,執行線程函數入口打斷點等。 關閉斷點:delete(d) breakpoint-id

4.單步命令

普通用法就不說了。
  • step count 一次性執行count步,如果有函數會進入函數
  • next count 一次執行count,不進入函數
  • finish 運行程序,直到當前函數完成返回,並打印函數返回時的堆棧地址和返回值以及參數信息
  • until 退出循環體(尤其是針對for循環這種,很煩的)

5.continue命令

當程序被停住之後,可以使用continue(c)命令,恢復程序的運行直到程序結束,或到達下一個斷點。這裏要註意如果沒有斷點程序是會直接結束的。

6.print(p)命令

這個命令比較常用,用來查看我們想看的內容。比如有關數組可以看全部,也可以看從左到右某一部分: 技術分享 print命令針對變量查看的輸出格式有:
  • x 按十六進制格式顯示變量
  • d 按十進制格式顯示變量
  • u 按十六進制格式顯示無符號整型
  • o 按八進制格式顯示變量
  • t 按二進制格式顯示變量t 按二進制格式顯示變量
  • a 按十六進制格式顯示變量
  • c 按字符格式顯示變量
  • f 按浮點數格式顯示變量

7.watch命令

這個命令比較有用。watch一般用來觀察某個表達式(變量也是一種表達式)的值是否有變化,如果有變化,馬上停住程序。我們有一下幾種方法設置觀察點:
  • watch expr 為表達式expr設置一個觀察點,一旦表達式值有變化,馬上停住程序
  • rwatch expr 當表達式expr被讀時,停住程序
  • awatch expr 當表達式的值被讀或被寫時,停住程序。
  • info watchpoints 列出所有觀察點(info指令通常可以去套)
舉例如下,演示觀測*i的值,一旦變化停下來: 技術分享 在循環中我們也可以使用watch,配合ignore,它是除了until命令之外又一個可以讓我們跳出循環的方法,不過watch+ignore更強大,可以任意跳轉到第i次循環。它們的意思就是觀察一個變量,可以理解為斷點,ignore這個斷點多少次,然後用continue就可以直接跳過了。 技術分享

8.examine命令

使用該命令來查看內存地址中的值。語法是:x/u addr addr表示一個內存地址。“x/”後的n、f、u都是可選的參數,n 是一個正整數,表示顯示內存的長度,也就是說從當前地址向後顯示幾個地址的內容;f 表示顯示的格式,如果地址所指的是字符串,那麽格式可以是s,如果地址是指令地址,那麽格式可以是i;u 表示從當前地址往後請求的字節數,如果不指定的話,GDB默認是4字節。u參數可以被一些字符代替:b表示單字節,h表示雙字節,w表示四字節,g表示八字節。當我們指定了字節長度後,GDB會從指定的內存地址開始,讀寫指定字節,並把其當作一個值取出來。n、f、u這3個參數可以一起使用,例如命令“x/3uh 0x54320”表示從內存地址0x54320開始以雙字節為1個單位(h)、16進制方式(u)顯示3個單位(3)的內存。 技術分享

9.jump命令

jump命令不會改變程序棧的內容,一般只在同一函數內跳轉。
  • jump linespec 指定下一條語句的運行點,linespec可以是linenum,filename+linenum,+offset這幾種形式
  • jump address 跳到代碼行的地址

10.signal命令

使用signal 信號名(如SIGINT)這種方式把信號發送給程序,如果程序註冊了signal_handler函數,還可以進行相應的處理,幫助調試程序。

11.set命令

  • set args 設置命令行參數
  • set env environmentVarname=value 設置環境變量。如:set env USER=benben

12.call命令

  • call function 強制調用某函數
強制調用某函數,它會顯示函數返回值(如果函數返回值不是void)。print命令也可以完成該功能。

13.disassemble命令

反匯編命令,查看執行時源代碼的機器碼。 技術分享

二:多進程調試

1.單獨調試子進程

我們可以先運行程序,然後再另一終端使用ps -ef | grep "main"(main此處是可執行文件名)搜索到子進程pid,然後啟動gdb,在將其附加(attach)到gdb調試器上。
  • attach child-pid 使用該命令後,直接run即可,和調試普通程序就沒區別了
  • dettach 脫離進程

2.使用調試器選項follow-fork-mode

我們知道如果不設置任何選項,gdb默認調試父進程。調試器選項用法如下:
  • set follow-fork-mode mode 其中mode的可選值是parent和child,分別表示調試父進程和子進程。
  • info inferiors 查詢正在調試的進程
  • inferior processnum 切換進程
默認設置下,在調試多進程程序時GDB只會調試主進程。但是GDB(>V7.0)支持多進程的分別以及同時調試,換句話說,GDB可以同時調試多個程序。只需要設置follow-fork-mode(默認值:parent)和detach-on-fork(默認值:on)即可。我們還可以使用catch fork指令,如果fork異常,會停止程序。
follow-fork-mode detach-on-fork 說明
parent on 只調試主進程(GDB默認)
child on 只調試子進程
parent off 同時調試兩個進程,gdb跟主進程,子進程block在fork位置
child off 同時調試兩個進程,gdb跟子進程,主進程block在fork位置
設置方法:set follow-fork-mode [parent|child] set detach-on-fork [on|off] 技術分享

三:多線程調試

gdb調試一般有兩種模式:all-stop模式和no-stop模式(gdb7.0之前不支持no-stop模式)。 1.all-stop模式 在這種模式下,當你的程序在gdb由於任何原因而停止,所有的線程都會停止,而不僅僅是當前的線程。一般來說,gdb不能單步所有的線程。因為線程調度是gdb無法控制的。無論什麽時候當gdb停止你的程序,它都會自動切換到觸發斷點的那個線程。 2.no-stop模式(網絡編程常用) 顧名思義,啟動不關模式。當程序在gdb中停止,只有當前的線程會被停止,而其他線程將會繼續運行。這時候step,next這些命令就只對當前線程起作用。 如果需要打開no-stop模式,可以向~/.gdbinit添加配置文件: [python] view plain copy
  1. #Enable the async interface
  2. set target-async 1
  3. #If using the CLI, pagination breaks non-stop
  4. set pagination off
  5. #Finall, turn it on
  6. set non-stop on
gdb支持的命裏有兩種類型:前臺的(同步的)和後臺(異步 )的。區別很簡單,同步的在輸出提示符之前會等待程序report一些線程已經終止的信息,異步則是直接返回。所以我們需要set target-async 1。set pagination off不要出現 Type <return> to continue 的提示信息 。最後一步是打開。 下面是常用命令:
  • info threads 顯示所有線程
  • thread id 切換到指定線程
  • break filename:linenum thread all 在所有線程相應行設置斷點,註意如果主線程不會執行到該行,並且啟動all-stop模式,主線程執行n或s會切換過去
  • set scheduler-locking off|on\step 默認off,執行s或c其它線程也同步執行。on,只有當前相稱執行。step,只有當前線程執行
  • show scheduler-locking 顯示當前模式
  • thread apply all command 每個線程執行同意命令,如bt。或者thread apply 1 3 bt,即線程1,3執行bt。
主要是我們要用能用的上的,比如no-stop模式,一般多線程調試就很有用的。

四:core文件

  • ulimit -c unlimited 生成core文件,也可以是指定大小,然後使用gdb ./main core啟動,bt查看調用棧即可。
參考:https://segmentfault.com/a/1190000003733061 http://www.cnblogs.com/frankbadpot/archive/2010/06/23/1762916.html

GDB常用調試命令以及多進程多線程調試