1. 程式人生 > >gdb調試多進程多線程程序

gdb調試多進程多線程程序

mage 支持 nbsp rgs 提示 功能 網絡 網絡編程 指令

一、調試的指令

  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 在滿足條件的那一行停住

    關閉斷點:delete(d) breakpoint -id 

  4.單步命令:

    step count  一次性執行count步,有函數進入函數

    next count  一次性執行count步,不進入函數

    finish     運行函數,知道當前函數完成返回,並打印出函數返回時的堆棧地址、返回值和參數信息

    until     退出循環體

  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  當表達式被讀是,停住程序

    awctah  expr  當表達式的值被讀或者背寫時,停住程序

  8.exammine命令:

    查看內存地址的值。語法是:x/u addr

  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這些命令就只對當前線程起作用。

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模式,一般多線程調試就很有用的。

gdb調試多進程多線程程序