使用gdb調試多進程多線程程序

一、gdb基礎知識

1、gdb是Linux環境下的一種調試工具,使用時在源程序生成是加上-g選項。

2、開始使用:gdb binFile;退出使用:ctrl+d或quit。

3、調試過程中常用的命令有:

(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 cindition          在某個條件滿足時,在某行停止

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

(4)單步命令

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

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

         finish                                   運行程序,直到當前函數完成返回,並打印函數返回時的堆棧地址和返回值以及參數信息

         until                                      退出循環體

(5)continue命令

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

(6)print(p)命令

           這個命令比較常用,用來查看我們想看的內容。比如有關數組可以看全部,也可以從左到右某一部分:

   print命令針對變量查看的輸出格式有:

            x                                         按十六進制格式顯示變量

           d                                          按十進制格式顯示變量

           u                                          按十六進制格式顯示無符號整型

           o                                          按八進制格式顯示變量

            t                                          按二進制格式顯示變量

           a                                          按字符格式顯示變量

            ......

(7)watch命令

            watch expr                          爲表達式expr設置一個觀察點,一旦表達式值有變化,馬上停住程序

           rwatch expr                          當表達式expr被讀時。停住程序

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

           info watchpoints                 列出所有觀察點(info指令通常可以去套)

(8)examine命令

            x/u addr                              查看內存中的值,“x/”後的n、f、u都是可選項

(9)jump命令 

       jump命令不會改變程序棧的內容,一般只在同一函數內跳轉

            jump linespec                  指定下一跳語句的運行點,linespec可以是linenum,filename+linenum,+offset這幾種形式

            jump address                   跳到代碼行的地址

(10)ignal命令

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

(11)set命令

             set args                               設置命令行參數

             set env environmentVarname=value設置環境變量。

(12)call命令

              call function                         強調調用某函數

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

(13)disassemble命令

          反彙編命令,查看執行時源代碼的機器碼

二、使用gdb調試多進程

1、代碼調試:


2、gdb可以同時調試多個程序。

     只需設置follow-fork-mode(默認值:parent)和detach-on-fork(默認值:on)即可。

parent on                        只調試主進程(gdb默認)

child on                          只調試子進程

parent off                        同時調試兩個進程,gdb和主程序,子進程block在fork位置

child off                          同時調試兩個進程,gdb和子進程,主進程block在fork位置

3、進入gdb調試模式


4、查看系統默認的follow-fork-mode和detach-on-fork


5、設置follow-fork-mode和detach-on-fork


6、用list命令查看源代碼(按enter翻頁),分別在子進程和父進程相應位置下斷點


7、打斷點


8、查看正在調試的進程:

        顯示gdb調試的所有inferior,gdb會爲它們分配id。其中帶有*得進程是正在調試的inferior。(gdb將每一個被調試程序的執行記錄在一個名爲inferior的結構中。一般情況下一個inferior對應一個進程,每個不同inferior有不同的地址空間。inferior有時候會在進程沒有啓動的時候就存在。)


9、切換調試的進程:inferior<infer number>


10、其他

(1)remove-inferior infno

刪除一個infno號的inferior。如果inferior正在運行則不能刪除,所以刪除前需要先kill或者detach這個inferior。

(2)clone-inferior[-copies n] [infno]

複製n個編號是infno號的inferior。如果指不定n的話,就只複製一個inferior。如果不指定infno,則就複製正在調試的inferior。

(3)detach inferior

detach掉編號是infno的inferior。注意這個inferior還存在,可以再次用run命令執行它。

(4)kill inferior infno:

kill掉infno號inferior。注意這個inferior任然存在,可以再次用run等命令執行它。

(5)set schedule-multiple on|off

設爲off:只有當前inferior會執行。

設爲on:全部是執行狀態inferior都會執行。

這個選項類似於多線程裏的set。

(6)main info program-space

顯示當前gdb一共管理多少地址空間

(7)set print inferior-events on|off

打開和關閉inferior狀態的提示信息

         show print inferior-events

查看print inferior-events設置的狀態

(8)set follow-exec-mode new|same

設置same:當發生exec的時候,在執行exec的inferior上控制子進程。

設置爲new:新建一個inferior給執行的子進程。而父進程的inferior任然保留,當前保留的inferior的程序狀態是沒有執行。

三、gdb調試多線程

1、調試代碼



上面代碼中主進程創建了3個子進程,他們是thread1,thread2和thread3,所以也就有3的線程。

2、使用gdb對多線程進行調試

            gdb調試多線程的的常用命令:

(1)info threads 顯示可以調試的所有線程

            gdb會爲每個線程分配一個id(和tid不同),編號一般從1開始。後面的id是指它的id。

(2)thread id 切換當前調試的線程·爲指定id的線程

(3)break FileName.cpp:LineNum thread all:

                所有線程都在文件FineName.cpp的第Linenum行有斷點

(4)step:在step(單步)調試時,只有被調試的線程運行

(5)set non-stop on/off

                當調試一個線程時,其它線程是否運行。

           set pagination on/off

                 在使用backtrack時,在分頁時是否停止

           set target-async on/off:

                  同步和異步。同步,gdb在輸出提示符之前等待程序報告一些線程已經終止的信息。而異步的則直接返回

            show scheduler-locking

              查看當前鎖定線程的模式

發佈了53 篇原創文章 · 獲贊 3 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章