GDB是GNU開(kāi)源組織發(fā)布的一個(gè)強大的UNIX下的程序調試工具?;蛟S,各位比較喜歡那種圖形界面方式的,像VC、BCB等IDE的調試,但如果你是在 UNIX平臺下做軟件,你會(huì )發(fā)現GDB這個(gè)調試工具有比VC、BCB的圖形化調試器更強大的功能。所謂“寸有所長(cháng),尺有所短”就是這個(gè)道理。一般來(lái)說(shuō),GDB主要幫忙你完成下面四個(gè)方面的功能:
1、啟動(dòng)你的程序,可以按照你的自定義的要求隨心所欲的運行程序。
2、可讓被調試的程序在你所指定的調置的斷點(diǎn)處停住。(斷點(diǎn)可以是條件表達式)
3、當程序被停住時(shí),可以檢查此時(shí)你的程序中所發(fā)生的事。
4、動(dòng)態(tài)的改變你程序的執行環(huán)境。
《GDB使用手冊》
一 列文件清單
List
(gdb) list line1,line2
二:執行程序
要想運行準備調試的程序,可使用run命令,在它后面可以跟隨發(fā)給該程序的任何參數,包括標準輸入和標準輸出說(shuō)明符(<和> )和shell通配符(*、?、[、])在內。如果你使用不帶參數的run命令,gdb就再次使用你給予前一條run命令的參數,這是很有用的。利用 set args 命令就可以修改發(fā)送給程序的參數,而使用show args 命令就可以查看其缺省參數的列表。
(gdb)set args –b –x
(gdb) show args
backtrace命令為堆棧提供向后跟蹤功能。
Backtrace 命令產(chǎn)生一張列表,包含著(zhù)從最近的過(guò)程開(kāi)始的所有有效過(guò)程和調用這些過(guò)程的參數。
三:顯示數據
利用print 命令可以檢查各個(gè)變量的值。
(gdb) print p (p為變量名)
print 是gdb的一個(gè)功能很強的命令,利用它可以顯示被調試的語(yǔ)言中任何有效的表達式。表達式除了包含你程序中的變量外,還可以包含以下內容:
對程序中函數的調用
(gdb) print find_entry(1,0)
數據結構和其他復雜對象
(gdb) print *table_start
={e=reference=’\000’,location=0x0,next=0x0}
值的歷史成分
(gdb)print (為歷史記錄變量,在以后可以直接引用的值)
人為數組
人為數組提供了一種去顯示存儲器塊(數組節或動(dòng)態(tài)分配的存儲區)內容的方法。早期的調試程序沒(méi)有很好的方法將任意的指針換成一個(gè)數組。就像對待參數一樣,讓我們查看內存中在變量h后面的10個(gè)整數,一個(gè)動(dòng)態(tài)數組的語(yǔ)法如下所示:
base@length
因此,要想顯示在h后面的10個(gè)元素,可以使用h@10:
(gdb)print h@10
=(-1,345,23,-234,0,0,0,98,345,10)
whatis 命令可以顯示某個(gè)變量的類(lèi)型
(gdb) whatis p
type = int *
四:斷點(diǎn)(breakpoint)
break命令(可以簡(jiǎn)寫(xiě)為b)可以用來(lái)在調試的程序中設置斷點(diǎn),該命令有如下四種形式:
break line-number 使程序恰好在執行給定行之前停止。
break function-name 使程序恰好在進(jìn)入指定的函數之前停止。
break line-or-function if condition 如果condition(條件)是真,程序到達指定行或函數時(shí)停止。
break routine-name 在指定例程的入口處設置斷點(diǎn)
如果該程序是由很多原文件構成的,你可以在各個(gè)原文件中設置斷點(diǎn),而不是在當前的原文件中設置斷點(diǎn),其方法如下:
(gdb) break filename:line-number
(gdb) break filename:function-name
要想設置一個(gè)條件斷點(diǎn),可以利用break if命令,如下所示:
(gdb) break line-or-function if expr
例:
(gdb) break 46 if testsize==100
從斷點(diǎn)繼續運行:countinue 命令
五.斷點(diǎn)的管理
1.顯示當前gdb的斷點(diǎn)信息:
(gdb) info break
他會(huì )以如下的形式顯示所有的斷點(diǎn)信息:
Num Type Disp Enb Address What
1 breakpoint keep y 0x000028bc in init_random at qsort2.c:155
2 breakpoint keep y 0x0000291c in init_organ at qsort2.c:168
刪除指定的某個(gè)斷點(diǎn):
(gdb) delete breakpoint 1
該命令將會(huì )刪除編號為1的斷點(diǎn),如果不帶編號參數,將刪除所有的斷點(diǎn)
(gdb) delete breakpoint
禁止使用某個(gè)斷點(diǎn)
(gdb) disable breakpoint 1
該命令將禁止斷點(diǎn) 1,同時(shí)斷點(diǎn)信息的 (Enb)域將變?yōu)?n
允許使用某個(gè)斷點(diǎn)
(gdb) enable breakpoint 1
該命令將允許斷點(diǎn) 1,同時(shí)斷點(diǎn)信息的 (Enb)域將變?yōu)?y
清除原文件中某一代碼行上的所有斷點(diǎn)
(gdb)clean number
注:number 為原文件的某個(gè)代碼行的行號
六.變量的檢查和賦值
whatis:識別數組或變量的類(lèi)型
ptype:比whatis的功能更強,他可以提供一個(gè)結構的定義
set variable:將值賦予變量
print 除了顯示一個(gè)變量的值外,還可以用來(lái)賦值
七. 單步執行
next 不進(jìn)入的單步執行
step 進(jìn)入的單步執行如果已經(jīng)進(jìn)入了某函數,而想退出該函數返回到它的調用函數中,可使用命令finish
八.函數的調用
call name 調用和執行一個(gè)函數
(gdb) call gen_and_sork( 1234,1,0 )
(gdb) call printf(“abcd”)
=4
finish 結束執行當前函數,顯示其返回值(如果有的話(huà))
九.機器語(yǔ)言工具
有一組專(zhuān)用的gdb變量可以用來(lái)檢查和修改計算機的通用寄存器,gdb提供了目前每一臺計算機中實(shí)際使用的4個(gè)寄存器的標準名字:
$pc : 程序計數器
$fp : 幀指針(當前堆棧幀)
$sp : 棧指針
$ps : 處理器狀態(tài)
十.信號
gdb通??梢圆蹲降桨l(fā)送給它的大多數信號,通過(guò)捕捉信號,它就可決定對于正在運行的進(jìn)程要做些什么工作。例如,按CTRL-C將中斷信號發(fā)送給 gdb,通常就會(huì )終止gdb。但是你或許不想中斷gdb,真正的目的是要中斷gdb正在運行的程序,因此,gdb要抓住該信號并停止它正在運行的程序,這樣就可以執行某些調試操作。
Handle命令可控制信號的處理,他有兩個(gè)參數,一個(gè)是信號名,另一個(gè)是接受到信號時(shí)該作什么。幾種可能的參數是:
nostop 接收到信號時(shí),不要將它發(fā)送給程序,也不要停止程序。
stop 接受到信號時(shí)停止程序的執行,從而允許程序調試;顯示一條表示已接受到信號的消息(禁止使用消息除外)
print 接受到信號時(shí)顯示一條消息
noprint 接受到信號時(shí)不要顯示消息(而且隱含著(zhù)不停止程序運行)
pass 將信號發(fā)送給程序,從而允許你的程序去處理它、停止運行或采取別的動(dòng)作。
nopass 停止程序運行,但不要將信號發(fā)送給程序。
例如,假定你截獲SIGPIPE信號,以防止正在調試的程序接受到該信號,而且只要該信號一到達,就要求該程序停止,并通知你。要完成這一任務(wù),可利用如下命令:
(gdb) handle SIGPIPE stop print
請注意,UNIX的信號名總是采用大寫(xiě)字母!你可以用信號編號替代信號名如果你的程序要執行任何信號處理操作,就需要能夠測試其信號處理程序,為此,就需要一種能將信號發(fā)送給程序的簡(jiǎn)便方法,這就是signal命令的任務(wù)。該命令的參數是一個(gè)數字或者一個(gè)名字,如SIGINT。假定你的程序已將一個(gè)專(zhuān)用的SIGINT(鍵盤(pán)輸入,或CTRL-C;信號2)信號處理程序設置成采取某個(gè)清理動(dòng)作,要想測試該信號處理程序,你可以設置一個(gè)斷點(diǎn)并使用如下命令:
?。╣db) signal 2
continuing with signal SIGINT(2)
該程序繼續執行,但是立即傳輸該信號,而且處理程序開(kāi)始運行。
GDB的使用方法
GDB是一個(gè)強大的命令行調試工具。大家知道命令行的強大就是在于,其可以形成
執行序列,形成腳本。UNIX下的軟件全是命令行的,這給程序開(kāi)發(fā)提代供了極大的
便利,命令行軟件的優(yōu)勢在于,它們可以非常容易的集成在一起,使用幾個(gè)簡(jiǎn)單的已
有工具的命令,就可以做出一個(gè)非常強大的功能。
于是UNIX下的軟件比Windows下的軟件更能有機地結合,各自發(fā)揮各自的長(cháng)處,組合
成更為強勁的功能。而Windows下的圖形軟件基本上是各自為營(yíng),互相不能調用,很
不利于各種軟件的相互集成。在這里并不是要和Windows做個(gè)什么比較,所謂“寸有
所長(cháng),尺有所短”,圖形化工具還是有不如命令行的地方。
用GDB調試程序
GDB概述
————
GDB是GNU開(kāi)源組織發(fā)布的一個(gè)強大的UNIX下的程序調試工具?;蛟S,各位比較喜歡
那種圖形界面方式的,像VC、BCB等IDE的調試,但如果你是在UNIX平臺下做軟件,你
會(huì )發(fā)現GDB這個(gè)調試工具有比VC、BCB的圖形化調試器更強大的功能。所謂“寸有所
長(cháng),尺有所短”就是這個(gè)道理。
一般來(lái)說(shuō),GDB主要幫忙你完成下面四個(gè)方面的功能:
1、啟動(dòng)你的程序,可以按照你的自定義的要求隨心所欲的運行程序。
2、可讓被調試的程序在你所指定的調置的斷點(diǎn)處停住。(斷點(diǎn)可以是條件表達式)
3、當程序被停住時(shí),可以檢查此時(shí)你的程序中所發(fā)生的事。
4、動(dòng)態(tài)的改變你程序的執行環(huán)境。
從上面看來(lái),GDB和一般的調試工具沒(méi)有什么兩樣,基本上也是完成這些功能,不過(guò)
在細節上,你會(huì )發(fā)現GDB這個(gè)調試工具的強大,大家可能比較習慣了圖形化的調試工
具,但有時(shí)候,命令行的調試工具卻有著(zhù)圖形化工具所不能完成的功能。讓我們一
一看來(lái)。
一個(gè)調試示例
——————
源程序:tst.c
1 #include
2
3 int func(int n)
4 {
5 int sum=0,i;
6 for(i=0; i
7 {
8 sum+=i;
9 }
10 return sum;
11 }
12
13
14 main()
15 {
16 int i;
17 long result = 0;
18 for(i=1; i<=100; i++)
19 {
20 result += i;
21 }
22
23 printf("result[1-100] = %d \n", result );
24 printf("result[1-250] = %d \n", func(250) );
25 }
編譯生成執行文件:(Linux下)
hchen/test> cc -g tst.c -o tst
使用GDB調試:
hchen/test> gdb tst <---------- 啟動(dòng)GDB
GNU gdb 5.1.1
Copyright 2002 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "i386-suse-linux"...
(gdb) l <-------------------- l命令相當于list,從第一行開(kāi)始例出原碼。
1 #include
2
3 int func(int n)
4 {
5 int sum=0,i;
6 for(i=0; i
7 {
8 sum+=i;
9 }
10 return sum;
(gdb) <-------------------- 直接回車(chē)表示,重復上一次命令
11 }
12
13
14 main()
15 {
16 int i;
17 long result = 0;
18 for(i=1; i<=100; i++)
19 {
20 result += i;
(gdb) break 16 <-------------------- 設置斷點(diǎn),在源程序第16行處。
Breakpoint 1 at 0x8048496: file tst.c, line 16.
(gdb) break func <-------------------- 設置斷點(diǎn),在函數func()入口處。
Breakpoint 2 at 0x8048456: file tst.c, line 5.
(gdb) info break <-------------------- 查看斷點(diǎn)信息。
Num Type Disp Enb Address What
1 breakpoint keep y 0x08048496 in main at tst.c:16
2 breakpoint keep y 0x08048456 in func at tst.c:5
(gdb) r <--------------------- 運行程序,run命令簡(jiǎn)寫(xiě)
Starting program: /home/hchen/test/tst
Breakpoint 1, main () at tst.c:17 <---------- 在斷點(diǎn)處停住。
17 long result = 0;
(gdb) n <--------------------- 單條語(yǔ)句執行,next命令簡(jiǎn)寫(xiě)。
18 for(i=1; i<=100; i++)
(gdb) n
20 result += i;
(gdb) n
18 for(i=1; i<=100; i++)
(gdb) n
20 result += i;
(gdb) c <--------------------- 繼續運行程序,continue命令簡(jiǎn)寫(xiě)。
Continuing.
result[1-100] = 5050 <----------程序輸出。
Breakpoint 2, func (n=250) at tst.c:5
5 int sum=0,i;
(gdb) n
6 for(i=1; i<=n; i++)
(gdb) p i <--------------------- 打印變量i的值,print命令簡(jiǎn)寫(xiě)。
= 134513808
(gdb) n
8 sum+=i;
(gdb) n
6 for(i=1; i<=n; i++)
(gdb) p sum
= 1
(gdb) n
8 sum+=i;
(gdb) p i
= 2
(gdb) n
6 for(i=1; i<=n; i++)
(gdb) p sum
= 3
(gdb) bt <--------------------- 查看函數堆棧。
#0 func (n=250) at tst.c:5
#1 0x080484e4 in main () at tst.c:24
#2 0x400409ed in __libc_start_main () from /lib/libc.so.6
(gdb) finish <--------------------- 退出函數。
Run till exit from #0 func (n=250) at tst.c:5
0x080484e4 in main () at tst.c:24
24 printf("result[1-250] = %d \n", func(250) );
Value returned is = 31375
(gdb) c <--------------------- 繼續運行。
Continuing.
result[1-250] = 31375 <----------程序輸出。
Program exited with code 027. <--------程序退出,調試結束。
(gdb) q <--------------------- 退出gdb。
hchen/test>
…………(限于篇幅,未全文轉載,各位讀者可去http://unix-cd.com/unixcd12/article_7137.html查看全文)
本站僅提供存儲服務(wù),所有內容均由用戶(hù)發(fā)布,如發(fā)現有害或侵權內容,請
點(diǎn)擊舉報。