GDB調試訊號、多線程、多進程

來源:互聯網
上載者:User

轉自:http://blog.csdn.net/yanook/article/details/6585648


GDB的功能很強大,本文主要介紹用GDB來調試訊號、多進程、多線程,具體如下:

(一)訊號

GDB有能力在你偵錯工具的時候處理任何一種訊號,你可以告訴GDB需要處理哪一種訊號。你可以要求GDB收到你所指定的訊號時,馬上停住正在啟動並執行程式,以供你進行調試。你可以用GDB的handle命令來完成這一功能。

    handle <signal> <keywords...>
        在GDB中定義一個訊號處理。訊號<signal>可以以SIG開頭或不以SIG開頭,可以用定義一個要處理訊號的範圍(如:SIGIO- SIGKILL,表示處理從SIGIO訊號到SIGKILL的訊號,其中包括SIGIO, SIGIOT,SIGKILL三個訊號),也可以使用關鍵字 all來標明要處理所有的訊號。一旦被調試的程式接收到訊號,運行程式馬上會被GDB停住,以供調試。其<keywords>可以是以下幾種關鍵字的一個或多個。

        nostop
            當被調試的程式收到訊號時,GDB不會停住程式的運行,但會打出訊息告訴你收到這種訊號。
        stop
            當被調試的程式收到訊號時,GDB會停住你的程式。
        print
            當被調試的程式收到訊號時,GDB會顯示出一條資訊。
        noprint
            當被調試的程式收到訊號時,GDB不會告訴你收到訊號的資訊。
        pass
        noignore
            當被調試的程式收到訊號時,GDB不處理訊號。這表示,GDB會把這個訊號交給被偵錯工具會處理。
        nopass
        ignore
            當被調試的程式收到訊號時,GDB不會讓被偵錯工具來處理這個訊號。

    info signals
    info handle
    查看有哪些訊號在被GDB檢測中。

(二)線程

如果你程式是多線程的話,你可以定義你的斷點是否在所有的線程上,或是在某個特定的線程。GDB很容易幫你完成這一工作。

    break <linespec> thread <threadno>
    break <linespec> thread <threadno> if ...
        linespec指定了斷點設定在的來源程式的行號。threadno指定了線程的ID,注意,這個ID是GDB分配的,你可以通過“info threads”命令來查看正在運行程式中的線程資訊。如果你不指定
thread <threadno>則表示你的斷點設在所有線程上面。你還可以為某線程指定斷點條件。如:

        (gdb) break frik.c:13 thread 28 if bartab > lim

    當你的程式被GDB停住時,所有的運行線程都會被停住。這方便你你查看運行程式的總體情況。而在你恢複程式運行時,所有的線程也會被恢複運行。那怕是主進程在被單步調試時。

線程有自己的寄存器,運行時堆棧或許還會有私人記憶體。   
gdb提供了以下供調試多線程的進程的功能:   
*   自動通告新線程。   
*   \ "thread   THREADNO\ ",一個用來線上程之間切換的命令。   
*   \ "info   threads\ ",一個用來查詢現存線程的命令。   
*   \ "thread   apply   [THREADNO]   [ALL]   ARGS\ ",一個用來向線程提供命令的命令。   
*   線程有關的斷點設定。   
注意:這些特性不是在所有gdb版本都能使用,歸根結底要看作業系統是否支援。   
如果你的gdb不支援這些命令,會顯示出錯資訊:   
(gdb)   info   threads   
(gdb)   thread   1   
Thread   ID   1   not   known.   Use   the   \ "info   threads\ "   command   to   
see   the   IDs   of   currently   known   threads.   
gdb的線程級調試功能允許你觀察你程式運行中所有的線程,但無論什麼時候   
gdb控制,總有一個“當前”線程。調試命令對“當前”進程起作用。   
一旦gdb發現了你程式中的一個新的線程,它會自動顯示有關此線程的系統信   
息。比如:   
[New   process   35   thread   27]   
不過格式和作業系統有關。   
為了調試的目的,gdb自己設定線程號。   
`info   threads\ "   
顯示進程中所有的線程的概要資訊。gdb按順序顯示:   
1.線程號(gdb設定)   
2.目標系統的線程標識。   
3.此線程的當前堆棧。   
一前面打\ "*\ "的線程表示是當前線程。   
例如:   
(gdb)   info   threads   
3   process   35   thread   27   0x34e5   in   sigpause   ()   
2   process   35   thread   23   0x34e5   in   sigpause   ()   
*   1   process   35   thread   13   main   (argc=1,   argv=0x7ffffff8)   
at   threadtest.c:68   
`thread   THREADNO\ "   
把線程號為THREADNO的線程設為當前線程。命令列參數THREADNO是gdb內定的   
線程號。你可以用\ "info   threads\ "命令來查看gdb內設定的線程號。gdb顯示該線程   
的系統定義的標識號和線程對應的堆棧。比如:   

(gdb)   thread   2   
[Switching   to   process   35   thread   23]   
0x34e5   in   sigpause   ()   
\ "Switching後的內容取決於你的作業系統對線程標識的定義。   

`thread   apply   [THREADNO]   [ALL]   ARGS\ "   
此命令讓你對一個以上的線程發出相同的命令\ "ARGS\ ",[THREADNO]的含義同上。   
如果你要向你進程中的所有的線程發出命令使用[ALL]選項。   
無論gdb何時中斷了你的程式(因為一個斷點或是一個訊號),它自動選擇訊號或   
斷點發生的線程為當前線程。gdb將用一個格式為\ "[Switching   to   SYSTAG]\ "的訊息   
來向你報告。   

 

(三)進程

1. 用的是attach子進程的方法
attach到正在啟動並執行進程的功能,即attach <pid>命令。因此我們可以利用該命令attach到子進程然後進行調試。

一般的步驟是  1.首先要在要調試的子進程初始代碼中,加入一段特殊代碼,使子進程睡眠等待,然後運行待調試的程式
2.用ps -ef |grep 查看產生的子進程pid
3. 然後gdb啟動,attach <pid>到進程後在該程式碼片段後設上斷點,就可以調試了

eg.

        pid = fork();
if (pid <0) {
printf("fork err\n");
exit(-1);
} else if (pid == 0) {
/* in child */
sleep(60); ------------------ (!)

int     value   = 10;

**********
} /**in parent****/

執行程式(比如說是 examp)
examp &   --- 讓examp後台運行吧。(不後台運行也可以);

尋找進程id:
ps -ef

運行gdb:
gdb
(gdb) attach xxxxx  --- xxxxx為利用ps命令獲得的子進程 id
(gdb) stop --- 這點很重要,你需要先暫停那個子進程,然後設定一些斷點和一些Watch
(gdb) break xx 
Breakpoint 1 at 0x10808: file eg1.c, line 37.
(gdb) c
Continuing.

2. 使用follow-fork-mode 的方法調試多進程
最好使用GDB 6.6或以上版本

使用follow-fork-mode 的方法調試多進程時的一般步驟是:
1.啟動gdb 
2設定set follow-fork-mode [child/parent] 想調試child就使用child參數,如調試parent則使用parent
3啟動程式檔案 file ./hello ----------當然路徑名自己要搞對哦
4.break num -----------如調試子進程則num是子進程代碼的行數,
還有個小技巧就是break fork也就是在fork函數處設定斷點,

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.