本文中,我們討論如何在6個簡單步驟下使用gdb調試器調試C程序。
為了調試目的編寫一個帶有錯誤的C程序示例。
為了學習C編程調試,讓我們創建下面C程序,它計算並且打印一個數的階乘。然而該C程序包括一些錯誤,它是為了我們調試目的而為。
$ vim factorial.c
# include <stdio.h>
int main()
{
inti, num, j;
printf("Enter the number: ");
scanf("%d", &num );
for(i=1; i<num; i++)
j=j*i;
printf("Thefactorial of %d is %d\n",num,j);
}
$ cc factorial.c
$ ./a.out
Enter the number: 3
The factorial of 3 is 12548672
讓我們開始調試它,學習gdb中許多最有用的命令。
步驟1:使用編譯選項-g編譯C程序
使用-g選項編譯你的C程序,這允許編譯器收集調試信息。
$ cc -g factorial.c
注意:上面的命令創建一個a.out文件,它用於下面顯示的調試。
步驟2:運行gdb
運行C調試器(gdb),如下所示:
$ gdb a.out
步驟3:在C程序中設置斷點
語法:break line_number
其它的格式:
break [file_name]:line_number
break [file_name]:func_name
在C程序中你假設錯誤的地方放置斷點。當執行程序時,調試器將在斷點處停止,並且給你調試的提示。
因此在開始運行程序之前,讓我們在程序中來設置下面的斷點。
(gdb) break 10
Breakpoint 1 at 0x40050b: file factorial.c,line 10.
步驟4:在gdb調試器中執行C程序
run [args]
你也可以在dbg調試器中使用run命令啟動程序。你也可以使用run args把命令行參數給程序。我們這裡使用的例子程序不需要任何的命令行參數,讓我們輸入run讓程序執行。
(gdb) run
Starting program: /root/valgrind/a.out
當你執行C程序,它會執行到第一個斷點,並且給你調試的提示。
Breakpoint 1, main () at factorial.c:10
10 j=j*i;
你也可以使用下面章節說明的各種gdb命令來調試C程序。
步驟5:打印gdb調試器中的變量值
語法: print {variable}
Examples:
print i
print j
print num
(gdb) p i
$1 = 1
(gdb) p j
$2 = 3042592
(gdb) p num
$3 = 3
(gdb)
正如上面所示,在factorial.c中,我們沒有初始化變量j,因此它給一個垃圾值作為階乘的值。
通過初始化化j為1來修復這個問題,編譯C程序並且再次執行它。
甚至在修復之後,在factorial.c程序中看上去也有一些問題,它仍然給錯誤的階乘值。
因此,在第10行放置斷點,並且繼續下一節的說明。
步驟6:繼續,單步執行-gdb命令
當程序停止在斷點處時,這裡有三種你可以選擇的gdb操作。它們是繼續執行到下一個斷點,單步執行進入函數,或者單步執行到下一個程序行。
# c 或者 continue:調試器將繼續執行直到下一個斷點。
# n 或者 next:調試器將執行下一行作為單個指令;
# s 或者step:與next一樣,但是不把函數作為單個指令,替代進入到函數中一行行的執行。
通過繼續或者單步執行,你能發現問題是因為我們沒有在for循環中使用<=條件檢查。因此改變<為<=將解決這個問題。
Gdb命令快捷方式
使用下面最常用的gdb操作的快捷方式:
# l – list
# p – print
# c – continue
# s – step
# n – next
# ENTER: 輸入回車鍵將再次執行前一個執行的命令。
萬能的Gb命令
# l 命令:使用gdb命令l或list打印調試模式下的源代碼,使用<l 行號>來查看指定行號或<l函數>查看指定的函數。
# bt:backtrack – 打印所有堆棧幀的信息,或者內部最多COUNT幀。
# help — 查看特別gdb主題的幫助— help 主題命
# quit – 退出gdb調試器。www.2cto.com