Linux系统中包含了GNU 调试程序gdb,它是一个用来调试C和 C++ 程序的调试器。可以使程序开发者在程序运行时观察程序的内部结构和内存的使用情况。
GDB提供了一下一些功能:
(1)监视程序中变量的值;
(2)设置断点以使程序在制定的代码上上运行;
(3)一行一行的执行代码。
gdb程序调试的对象是可执行文件,,需在执行gcc指令编译程序时,加上-g参数,指定程序在编译时包含调试信息。调试信息包含程序里的每个变量的类型和在可执行文件里的地址映射以及源代码的行号。gdb 利用这些信息使源代码和机器码相关联。
启动gdb后,可以在命令行制定很多选项,也可以用下面的方式在命令行中指定想要调试的文件名:
$ gdb filename
此时,gdb会装入名为filename的可执行文件,用这种方式运行gdb可以直接指定想要调试的程序。也可以用gdb去检查一个因程序异常终止而产生的core文件,或者与一个正在运行的程序相连。
下面举个实例来介绍如何一步步的用gdb调试程序,显示一个简单的“Hello World!”,再用凡需将此输出。代码如下:
1 /*lxy1.c*/
2 #include<stdio.h>
3 void print1(char *string)
4 {
5 printf("The string is :%s\n",string);
6 }
7 void print2(char *string)
8 {
9 char *string2;
10 int size,i;
11 size = strlen(string);
12 string2 = (*char) malloc(size+1);
13 for(i = 0;i<size;i++)
14 string2[size-i] = string[i];
15 string2[size+1] = ‘\0‘;
16 printf("The string printed backward is:%s\n",string2);
17 free(string2);
18 }
19
20 main()
21 {
22 char test_string []="Hello World!";
23 print1(test_string);
24 print2(test_string);
25 }
$gcc -o lxy1 lxy1.c
编译成功后,执行lxy1:
./lxy1
程序显示的结果如下:
The string is:Hello World!
The string printed backward is:
可知第二行输出时错误的 ,现在用gdb进行调试,重新编译如下:
$gcc -o lxy1 lxy1.c -g
现在可以用gdb对gdbtest进行调试,输入命令如下:
$gdb lxy1
这个命令将载入lxy1可执行文件,进入gdb后,输入run命令运行lxy1,结果如下:
Staring program:/home/lxy/book/src/chapter2/lxy1
The string is:Hello World!
The string printed backward is:
program exited normally
为了找出问题在哪,在gdb下输入list命令可列出源代码。由一系列分析知道在14行设置断点,应该输入下面的命令
(gdb)break 14
Breakpoint 1 at 0x80484ee:file lxy1.c,line 14.
再输入run,将产生如下的输出:
(gdb)run
Staring program:/home/lxy/book/src/chapter2/lxy1
The string is:Hello World!
Breakpoint 1 ,print2(string=0xbffff32d"Hello World!") at lxy1.c:14
14 string2[size-i] = string[i];
由此可知道程序停在13行“string2[size-i]=string[i]”,可以通过设置一个观察点来观察string2[size-i]变量的值,看错误咋产生的。如下:
(gdb)watch string2[size-i]
Hardware watchpoint 2:string2[size-i]
输入命令 C 使程序继续执行,直到停止在下次循环体语句中,这里可知string2[size-i]= string[i]应修正为string2[size-i-1]= string[i].
通过这个例子,知道了gdb程序的调用、在gdb中显示源文件、设置断点、观察变量、单步执行等。需要多加练习。。