GDB(GNU Debugger)的调试功能非常强大,甚至可以和Visual C++、Visual Basic、Jbuilder等开发工具的调试器相媲美。但GDB的缺点是没有图形调试界面。
前提
运行命令gcc –g hello.c -o hello
对hello.c进行编译,其中参数g的作用是把调试信息加入生成的test可执行文件中,否则GDB就无法对hello进行调试。
- 进入调试
运行 gdb test
- 查看源代码
(gdb) l //list
显示10行代码,再运行一次l
就会显示下10行的代码。方便源代码的阅读。
- 设置断点
断点是调试程序的重要方法,通过断点我们可以知道程序每一步的执行情况(如当前变量的值,函数是否调用等)。在GDB中通过命令b进行断点设置。如下所示:
(gdb) b 15 //breakpoint
可以看到命令b
在程序的低15行进行了第一个断点的设置,并显示了改断点在内存中的物理地址。
- 查看断点的情况
(gdb) info b
- 运行程序
(gdb) r
B中通过命令”r”来运行程序。gdb默认从代码的首行开始运行(也可以通过命令“r 行数”的方式指定行数开始运行。如果程序有断点,则程序会在断点的前一行暂停运行。
- 查看变量值
(gdb) p n
- 继续运行程序
(gdb) c
查看当前程序的运行情况后,使用命令“c”就可以继续将程序运行下去。
- 单步运行
在GDB中通过命令”s“(step的缩写)和”n“(next的缩写)让程序一步一步的往下运行。其中s可以发生函数调用时进入函数内部运行,而n不会进入到函数内部运行。
工程管理器
在实际的开发过程中,仅仅通过使用 gcc 命令对程序进行编译是非常低效的。原因主要有以下两点。 1)程序往往是由多个源文件组成的,源文件的个数越多,那么gcc的命令行就会越长。此外,各种编译规则也会加大gcc命令行的复杂度。所以在开发调试程序的过程中,通过输入 gcc命令行来编译程序是很麻烦的。 2)在程序的整个开发过程中,调试的工作量占到了整体工作量的 70%以上。在调试程序的过程中,每次调试一般只会修改部分源文件。而在使用gcc命令行编译程序时,gcc会把那些没有被修改的源文件一起编译,这样就会影响编译的总体效率。
Make工程管理器的优越性具体体现在以下两个方面。
(1)使用方便 通过命令“make”就可以启动Make工程管理器对程序进行编译,所以不再需要每次都输入gcc命令行。
(2)调试效率高 为了提高编译程序的效率,Make会检查每个源文件的修改时间(时间戳)。只有在上次编译之后被修改的源文件才会在接下来的编译过程中被编译和链接,这样就能避免多余的编译工作量。
Makefile 文件由以下三项基本内容组成。
1) 需要生成的目标文件(target file)。
2) 生成目标文件所需要的依赖文件(dependency file)。
3) 生成目标文件的编译规则命令行(command)。
这三项内容按照如下格式进行组织:
target file :dependency file command
Makefile规定在书写command命令行前必须加一个键。
举个栗子:vim hello.c
创建hello.c文件
#include<stdio.h>
int main()
{
printf("hello world\n");
return 0;
}
vim Makefile
创建工程管理器
//定义变量
CC = gcc
target = hello
object = hello.o
//Make中的变量用$(变量名)表示
$(target) : $(object)
$(CC) $(object) -o $(target)
//这是<Tab>键
.PHONY : clean
clean :
rm -rf hello *.o
第一次make
时执行
gcc -c -o hello.o hello.c
gcc hello.o -o hello
如果修改了源文件,则重新运行,若没有,则显示
make: “hello”是最新的。