C編譯: 使用gdb調試


作者:Vamei 出處:http://www.cnblogs.com/vamei 歡迎轉載,也請保留這段聲明。謝謝! 

 

gdb是the GNU Debugger的簡稱。它是一款UNIX平台的調試器(debugger),可用於為C, C++, Objective-C, Java, Fortran等程序debug。

在gdb中,你可以通過設置斷點(break point)來控制程序運行的進度,並查看斷點時的變量和函數調用狀況,從而發現可能的問題。在許多IDE中,gdb擁有圖形化界面。

這里主要介紹gdb的命令行使用,並以C程序為例。測試使用的計算機是Mac OS系統。

 

啟動gdb

下面的有兩個C文件。(並沒有bug。我們使用gdb來查看程序運行的細節)

程序的一個為test.c,其中有主程序main()mean.c程序中定義了mean()函數,並在main()中調用。

test.c

#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; } 

 

mean.c

float mean(float a, float b) { return (a + b)/2.0; }

 

使用gcc同時編譯上面兩個程序。為了使用gdb對進行調試,必須使用-g選項(在編譯時生成debugging信息):

$gcc -g -o test test.c mean.c

生成main可執行文件。

(如有必要,使用:

$chmod +x test

來增加用戶的執行權限。)

 

進入gdb,准備調試程序:

$gdb test

進入gdb的互動命令行。

 

顯示程序

我們可以直接顯示某一行的程序,比如查看第9行程序:

(gdb) list 9

將顯示以第9行為中心,總共10行的程序。我們實際上編譯了兩個文件,在沒有說明的情況下,默認為主程序文件test.c:

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};

 

如果要查看mean.c中的內容,需要說明文件名:

(gdb) list mean.c:1

 

可以具體說明所要列出的程序行的范圍:

(gdb) list 5, 15

即顯示5-15行的程序。

 

顯示某個函數,比如:

(gdb) list mean

 

設置斷點

我們可以運行程序:

(gdb) run

程序正常結束。

 

運行程序並沒有什么有趣的地方。gdb的主要功能在於能讓程序在中途暫停。

斷點(break point)是程序執行中的一個位置。在gdb中,當程序運行到該位置時,程序會暫停,我們可以查看此時的程序狀況,比如變量的值。

 

我們可以在程序的某一行設置斷點,比如:

(gdb) break 16

將在test.c的第16行設置斷點。

 

你可以查看自己設置的斷點:

(gdb) info break

每個斷點有一個識別序號。我們可以根據序號刪除某個斷點:

(gdb) delete 1

也可以刪除所有斷點:

(gdb) delete breakpoints

 

查看斷點

設置斷點,並使用run運行程序,程序將運行到16行時暫停。gdb顯示:

Breakpoint 1, main () at test.c:16
16        for(i = 0; i < ARRAYSIZE - 1; i++) {

 

查看斷點所在行:

(gdb) list

 

查看斷點處的某個變量值:

(gdb) print a

(gdb) print array_a

 

查看所有的局部變量:

(gdb) info local

 

查看此時的棧狀態 (反映了函數調用,見Linux從程序到進程):

(gdb) info stack

 

可以更改變量的值。

(gdb) set var a=0.0

(gdb) set var array_a={0.0, 0.0, 1.0, 1.0}

當程序繼續運行時,將使用更改后的值。

 

如果我們將斷點設置在:

(gdb) break mean.c:2

此時棧中有兩個a,一個屬於main(),一個屬於mean()。我們可以用function::variable的方式區分:

(gdb) print mean::a

 

運行控制

讓程序從斷點開始,再多運行一行:

(gdb) step

也可以使用下面命令,從斷點恢復運行,直到下一個斷點:

(gdb) continue

使用run重新開始運行。

 

幫助

你可以通過gdb的幫助學到更多:

(gdb) help

或者更具體的命令:

(gdb) help info

 

退出

使用下面命令退出gdb:

(gdb) quit

 

debug

下面是一個有bug的C程序,demo.c

#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); }

程序可以成功編譯,但運行將返回:

Segmentation fault

可以使用gdb來查找問題。

 

Updata:

水土精靈提醒: gdb命令可以只輸入首字母的縮寫,比如c代表continue,b代表break,q代表quit。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM