您好,登錄后才能下訂單哦!
介紹
gdb調(diào)試命令行使用
gdb是the GNU Debugger的簡(jiǎn)稱。它是一款UNIX平臺(tái)的調(diào)試器(debugger),可用于為C, C++, Objective-C, Java, Fortran等程序debug。
在gdb中,你可以通過(guò)設(shè)置斷點(diǎn)(break point)來(lái)控制程序運(yùn)行的進(jìn)度,并查看斷點(diǎn)時(shí)的變量和函數(shù)調(diào)用狀況,從而發(fā)現(xiàn)可能的問(wèn)題。在許多IDE中,gdb擁有圖形化界面。
這里主要介紹gdb的命令行使用,并以C程序?yàn)槔y(cè)試使用的計(jì)算機(jī)是Mac OS系統(tǒng)。
啟動(dòng)gdb
下面的有兩個(gè)C文件。(并沒(méi)有bug。我們使用gdb來(lái)查看程序運(yùn)行的細(xì)節(jié))
程序的一個(gè)為test.c,其中有主程序main()。mean.c程序中定義了mean()函數(shù),并在main()中調(diào)用。
test.c
復(fù)制代碼
#define ARRAYSIZE 4
float mean(float, float);
int main()
{
int i;
float a=4.5;
float b=5.5;
float rlt=0.0;
float array_a[ARRAYSIZE]={1.0, 2.0, 3.0, 4.0};
float array_b[ARRAYSIZE]={4.0, 3.0, 2.0, 1.0};
float array_rlt[ARRAYSIZE];
for(i = 0; i < ARRAYSIZE - 1; i++) {
array_rlt[i] = mean(array_a[i], array_b[i]);
}
rlt = mean(a, b);
return 0;
}
復(fù)制代碼
mean.c
float mean(float a, float b)
{
return (a + b)/2.0;
}
使用gcc同時(shí)編譯上面兩個(gè)程序。為了使用gdb對(duì)進(jìn)行調(diào)試,必須使用-g選項(xiàng)(在編譯時(shí)生成debugging信息):
$gcc -g -o test test.c mean.c
生成main可執(zhí)行文件。
(如有必要,使用:
$chmod +x test
來(lái)增加用戶的執(zhí)行權(quán)限。)
進(jìn)入gdb,準(zhǔn)備調(diào)試程序:
$gdb test
進(jìn)入gdb的互動(dòng)命令行。
顯示程序
我們可以直接顯示某一行的程序,比如查看第9行程序:
(gdb) list 9
將顯示以第9行為中心,總共10行的程序。我們實(shí)際上編譯了兩個(gè)文件,在沒(méi)有說(shuō)明的情況下,默認(rèn)為主程序文件test.c:
復(fù)制代碼
4
5 int main()
6 {
7 int i;
8 float a=4.5;
9 float b=5.5;
10 float rlt=0.0;
11
12 float array_a[ARRAYSIZE]={1.0, 2.0, 3.0, 4.0};
13 float array_b[ARRAYSIZE]={4.0, 3.0, 2.0, 1.0};
復(fù)制代碼
如果要查看mean.c中的內(nèi)容,需要說(shuō)明文件名:
(gdb) list mean.c:1
可以具體說(shuō)明所要列出的程序行的范圍:
(gdb) list 5, 15
即顯示5-15行的程序。
顯示某個(gè)函數(shù),比如:
(gdb) list mean
設(shè)置斷點(diǎn)
我們可以運(yùn)行程序:
(gdb) run
程序正常結(jié)束。
運(yùn)行程序并沒(méi)有什么有趣的地方。gdb的主要功能在于能讓程序在中途暫停。
斷點(diǎn)(break point)是程序執(zhí)行中的一個(gè)位置。在gdb中,當(dāng)程序運(yùn)行到該位置時(shí),程序會(huì)暫停,我們可以查看此時(shí)的程序狀況,比如變量的值。
我們可以在程序的某一行設(shè)置斷點(diǎn),比如:
(gdb) break 16
將在test.c的第16行設(shè)置斷點(diǎn)。
你可以查看自己設(shè)置的斷點(diǎn):
(gdb) info break
每個(gè)斷點(diǎn)有一個(gè)識(shí)別序號(hào)。我們可以根據(jù)序號(hào)刪除某個(gè)斷點(diǎn):
(gdb) delete 1
也可以刪除所有斷點(diǎn):
(gdb) delete breakpoints
查看斷點(diǎn)
設(shè)置斷點(diǎn),并使用run運(yùn)行程序,程序?qū)⑦\(yùn)行到16行時(shí)暫停。gdb顯示:
Breakpoint 1, main () at test.c:16
16 for(i = 0; i < ARRAYSIZE - 1; i++) {
查看斷點(diǎn)所在行:
(gdb) list
查看斷點(diǎn)處的某個(gè)變量值:
(gdb) print a
(gdb) print array_a
查看所有的局部變量:
(gdb) info local
查看此時(shí)的棧狀態(tài) (反映了函數(shù)調(diào)用,見(jiàn)Linux從程序到進(jìn)程):
(gdb) info stack
可以更改變量的值。
(gdb) set var a=0.0
(gdb) set var array_a={0.0, 0.0, 1.0, 1.0}
當(dāng)程序繼續(xù)運(yùn)行時(shí),將使用更改后的值。
如果我們將斷點(diǎn)設(shè)置在:
(gdb) break mean.c:2
此時(shí)棧中有兩個(gè)a,一個(gè)屬于main(),一個(gè)屬于mean()。我們可以用function::variable的方式區(qū)分:
(gdb) print mean::a
運(yùn)行控制
讓程序從斷點(diǎn)開(kāi)始,再多運(yùn)行一行:
(gdb) step
也可以使用下面命令,從斷點(diǎn)恢復(fù)運(yùn)行,直到下一個(gè)斷點(diǎn):
(gdb) continue
使用run重新開(kāi)始運(yùn)行。
幫助
你可以通過(guò)gdb的幫助學(xué)到更多:
(gdb) help
或者更具體的命令:
(gdb) help info
退出
使用下面命令退出gdb:
(gdb) quit
debug
下面是一個(gè)有bug的C程序,demo.c
復(fù)制代碼
#include <stdio.h>
struct node {
int element;
};
typedef struct node *PNode;
int main()
{
int i;
PNode np=NULL;
for (i=0; i<10; i++) {
printf("Hello World!");
}
printf("%d \n", np->element);
}
復(fù)制代碼
程序可以成功編譯,但運(yùn)行將返回:
Segmentation fault
可以使用gdb來(lái)查找問(wèn)題。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。