GDB調試器使用總結

GDB調試器使用總結

概述: GDB是linux下調試程序的神器,做爲linux程序員,如果不能熟練的使用GDB進行程序調試,那將是很失敗的事情。強大的功能使GDB的使用也變得比較複雜,如果是初學者肯定會比繁雜的命令嚇到。下面是整理的一些我認爲會比較有幫助的部分。下文中以">"開頭的命令是linux的shell命令,以"(GDB)"開頭的則是GDB內部命令。

0.轉儲功能(core dump):

(1).開啓轉儲功能:首先用 >ulimit -c 查看是否開啓轉儲功能,如果命令返回不是0則已經開啓,否則就是未開啓。>ulimit -c unlimited 命令可以開啓轉儲功能。也可以用 >ulimit -c 1024來設定轉儲文件的大小。

(2).設定轉儲文件生成地址:編輯/etc/sysctl.conf文件,在文件最後加入下列兩行:

kernel.core_pattern = /var/core/%t-%e-%p.core

kernel.core_uses_pid = 0

然後將文件保存起來,保存完成之後執行:>sysctl -p命令(注意:執行這個命令需要root權限。)。此時執行一個會當機的程序,會在/var/core/文件夾下面生成轉儲文件(例如:1432378356-a.out-4821.core)。上面設定的文件名是有固定格式的,core_pattern中設定的就是文件保存目錄和文件的名字格式。其中%t是轉儲時的unix時間戳,%e是當前執行的文件名,%p是crash進程的PID。格式符說明如下:

格式符號
說明
%%
%字符本身
%p

被轉儲進程的進程ID(PID)

%u

被轉儲進程的真是用戶ID(UID)

%g

被轉儲進程的真是組(GID)

%s

引發轉儲的信號編號

%t

轉儲時間,unix時間戳(從1970年1月1日0時開始的秒數)

%h
主機名
%e

可執行文件的名稱

%c

轉儲文件的大小上限(內核版本2.6.24以後可使用)

(3).轉儲文件的壓縮:通過在/etc/sysctl.conf文件的core_pattern中加入壓縮腳本以及管道命令,可以對生成的轉儲文件進行壓縮。首先在/etc/sysctl.conf文件中加入下列兩行(如果已經存在則修改成下面的形式):

kernel.core_pattern = |/usr/localsbin/zipsh %t %e %p

kernel.core_uses_pid = 0

保存文件,然後執行:>sysctl -p命令。

/usr/local/sbin/zipsh文件的內容如下:

#!/bin/sh

exec gzip - > /var/core/$1-$2-$3.core.gz

這樣的話,以後都會在/var/core下生成壓縮的轉儲文件。

1.基本信息查看:

(1).棧信息:不管是操作轉儲文件還是用GDB設置斷點進行調試,都可以輸入(GDB)bt打印棧內容進行查看。一般的當機BUG,看下當機的位置,然後看下源代碼基本就可以解決了。但是很多情況下簡單的(GDB)bt還查不到問題,這時候就要涉及到比較複雜的操作。下面羅列了一些對棧的操作:

(GDB) bt:顯示所有棧幀。

(GDB) bt 10:顯示前面10個棧幀。

(GDB) bt -10:顯示後面10個棧幀。

(GDB) bt full:顯示棧幀以及局部變量。

(GDB) bt full 10:顯示前面10個棧幀以及局部變量。

(GDB) bt full -10:顯示後面10個棧幀以及局部變量。

(GDB) frame <棧幀編號>:進入指定的棧幀中,然後可以查看當前棧幀中的局部變量,以及棧幀內容等信息。

(GDB) info frame <棧幀編號>:可以查看指定棧幀的詳細信息。

(GDB) up:進入上層棧幀。

(GDB) down:進入下層棧幀。

 (2).變量:調試BUG過程中查看變量信息是很有幫助的操作,查看方式如下:

(GDB) p <變量名>

 (3).寄存器:對於調試來說寄存器中的值也很重要,可以查看到當前正在執行的指令的地址等。具體操作羅列如下:   

(GDB) info reg:顯示所有寄存器。可以簡寫爲:i r。如果要查看具體的寄存器可以這樣:i $ebx

(GDB) p $eax:顯示eax寄存器內容。

(GDB) p/c $eax:用字符顯示eax寄存器內容,反斜槓後面的是顯示格式,可使用的格式見下表:該表在顯示內存內容的x命令中也是通用的。

格式
說明
x

顯示爲十六進制數

d
顯示爲十進制數
u

顯示爲無符號十進制數

o
顯示爲八進制數
t
顯示爲二進制數
a
顯示爲地址
c

顯示爲字符(ASCII)

f
顯示爲浮點小數
s
顯示爲字符串
i

顯示爲機器語言(僅在顯示內存的x命令中可用)

(4).內存:可以查看具體內存地址中的內容,比如:目前執行的彙編指令,以及棧中內容等。

(GDB) x $pc:顯示程序指針指向位置的內容。

(GDB) x/i $pc:顯示程序當前位置的彙編指令。

(GDB) x/10i $pc:顯示程序當前位置開始往後的10條彙編指令。

(GDB) disassem $pc:反彙編當前函數。簡寫爲:disas $pc。

2.調試:

 (1).斷點:調試程序中,設置斷點進行調試是最方便有效的手段,因此學會如果靈活設置斷點是調試的基本功。:

 A.設置斷點:

(GDB) break <函數名>:對當前正在執行的文件中的指定函數設置斷點。可簡寫爲:(GDB) b <函數名>

(GDB) break <行號>:對當前正在執行的文件中的特定行設置斷點。可簡寫爲:(GDB) b <行號>

(GDB) break <文件名:行號>:對指定文件的指定行設置斷點。最常用的設置斷點方式。可簡寫爲:(GDB) b <文件名:行號>

(GDB) break <文件名:函數名>:對指定文件的指定函數設置斷點。C++類中的方法似乎不好使。可簡寫爲:(GDB) b <文件名:函數名>

(GDB) break <+/-偏移量>:當前指令行+/-偏移量出設置斷點。可簡寫爲:b <+/-偏移量>

(GDB) break <*地址>:指定地址處設置斷點。可簡寫爲:b <*地址>

B.查看、刪除斷點:

(GDB) info break :顯示所有斷點以及監視點。可簡寫爲:(GDB) i b

(GDB) delete <編號>:刪除編號指向的斷點或者監視點。可簡寫爲:(GDB) d <編號>

(GDB) clear <行號>:刪除改行的斷點。

(GDB) clear <文件名:行號>:刪除改行的斷點。

 C.設置無效、有效斷點:

(GDB) disable <斷點編號> : 當前斷點設置爲無效。

(GDB) enable <斷點編號>:當前斷點設置爲有效。

 (2).監視點:可以監視某個變量,在變量被訪問或者被修改時程序會在當前點進入斷點。刪除,查看監視點的方式與斷點相同。設置監視點方式如下:            

(GDB) watch <表達式>:表達式發生變化時暫停。

(GDB) awatch <表達式>:表達式訪問或者改變時暫停。

(GDB) rwatch <表達式>:表達式被訪問時暫停。

 (3).條件斷點:在調試程序過程中,有時候我們只想在某個條件下停止程序,然後進行單步調試,而條件斷點就是爲此而設計。下面是條件斷點的操作方式:    

(GDB) b <斷點> if <條件表達式> : 例如:b main.cpp:8 if x=10 && y=10

(GDB) condition <斷點編號>:刪除該斷點的條件。

(GDB) condition <斷點編號> <條件表達式>:修改斷點條件。例如:condition 1 x=10 && y=10

(4).斷點命令:每次斷點發生時候,想要查看的變量很多時,如果每個變量都手動print則需要浪費很多時間。斷點命令可以在斷點發生時批量執行GDB命令。下面是斷點命令的設置方式:

(GDB) commands <斷點編號>

(GDB) >print x

(GDB) >print y

(GDB) >end

首先輸入GDB命令commands <斷點編號>然後回車,這時候會出現>提示符。出現>提示符後可以輸入斷點發生時需要執行的GDB命令,每行一條,全部輸入完成後輸入end結束斷點命令。

 (5).反覆執行:單步執行時如果進入了你不關心的函數,你想立即跳出函數;或者進入了大循環中,你想立即循環。下面的命令可以幫到你:    

(GDB) ignore <斷點編號> <次數>:忽略N次斷點。

(GDB) c N: 執行N次指令,會忽略斷點。

(GDB) s/stepi/n/nexti N:往後執行N行,不會忽略斷點。

(GDB) finish:執行完當前函數後停止,不會忽略斷點。

(GDB) until:執行完當前循環後停止,不會忽略斷點。

(GDB) until <地址>:執行到指定地址停止。

(6).設置變量值:對變量的值進行控制,可以更快的調試自己的程序。下面就是設置變量值的方法:

(GDB) set variable <變量> = <表達式>:將變量的值設定爲指定表達式的值。例如 set variable x=10

 (7).手動生成轉儲文件:

(GDB) generate-core-file 簡寫爲:(GDB) gcore

3.調試在線進程:

(1).啓動GDB時鏈接目標進程:在啓動GDB的時候,通過參數-p指定目標進程,就可以進入調試狀態。剛鏈接成功後,程序是暫停運行狀態,你可以進行設置斷點等操作,然後輸入(GDB) c 命令繼續運行。命令如下:

>gdb -p <PID>:PID是進程ID,可以通過>ps aux | grep <程序名> 獲得。或者直接 >gdb -p  `pidof <程序名>`也可以。>pidof <程序名>是通過名字獲取進程ID的命令。

(2).GDB中鏈接目標進程:

(GDB) attach <PID>

 (3).斷開鏈接:

(GDB) detach

4.調試多線程程序:

 (1).查看線程:

(GDB) info thread:查看所有線程信息,可簡寫爲:i thr

 (2).切換到指定線程:

(GDB) thread <線程編號>:選中出現問題的線程,可簡寫爲:thr <線程編號>

(3).調試守護者進程:守護者進程在啓動好子進程後,會自動關閉主進程,如果沒有設定監控模式的話,GDB會提示斷開與進程的鏈接。所以必須設定監控對象,設置方式如下:

(GDB) set follow-fork-mode child/parent

原文:http://www.cnblogs.com/kiven-code/p/4528576.html?utm_source=tuicool
發佈了13 篇原創文章 · 獲贊 58 · 訪問量 28萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章