如何使用gdb调试C程序

时间:2021-02-22 16:38:48

本文中,我们讨论如何在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调试器。