- #include <stdio.h>
- int add_range(int low, int high)
- {
- int i,sum;
-
- for(i=low; i<=high; ++i)
- {
- sum += i;
- }
- return sum;
- }
- int main()
- {
- int result[100];
-
- result[0] = add_range(1,10);
- result[1] = add_range(1,100);
- printf("result[0]=%d\nresult[1]=%d",result[0],result[1]);
- return 0;
- }
注:要想调试一个程序的话,在用gcc编译的时候就需要把调试信息加进去,否则gdb是不会工作的。下面就从上面的程序来讲述gdb的使用。
这个程序的功能就是计算1~10和1~100的和。但是程序结果是:
- result[0]=55
- result[1]=5105
由此看出1~100的计算结果是不正确的。下面用gdb来一步步调试程序结果。
一、首先输入gdb add 或者gdbfile 回车 file add。注意add是可执行文件,但是你要是修改了源文件的名字,gdb也是不会起作用的。
二、list或者l查看源代码,list每次只会显示10行代码,list + 函数名
- (gdb) list 1
- 1 #include <stdio.h>
- 2
- 3 int add_range(int low, int high)
- 4 {
- 5 int i,sum;
- 6
- 7 for(i=low; i<=high; ++i)
- 8 {
- 9 sum += i;
- 10 }
也可以什么都不输直接敲回车,gdb提供了一个很方便的功能,在提示符下直接敲回车表示重复上一条命令。
- gdb)
- 11 return sum;
- 12 }
- 13
- 14 int main()
- 15 {
- 16 int result[100];
- 17
- 18 result[0] = add_range(1,10);
- 19 result[1] = add_range(1,100);
- 20
gdb的很多常用命令有简写形式,例如list命令可以写成l,要列一个函数的源代码也可以用函数名做参数:
- (gdb) l add_range
- 1 #include <stdio.h>
- 2
- 3 int add_range(int low, int high)
- 4 {
- 5 int i,sum;
- 6
- 7 for(i=low; i<=high; ++i)
- 8 {
- 9 sum += i;
- 10 }
gdb提供quit命令退出gdb程序
好,基础就介绍到这里,下面来调试上面的程序:
- [tym@lxy gdb]$ gdb add
- GNU gdb Fedora (6.8-37.el5)
- Copyright (C) 2008 Free Software Foundation, Inc.
- License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
- This is free software: you are free to change and redistribute it.
- There is NO WARRANTY, to the extent permitted by law. Type "show copying"
- and "show warranty" for details.
- This GDB was configured as "i386-redhat-linux-gnu"...
- (gdb) start
- Breakpoint 1 at 0x80483bd: file add.c, line 18.
- Starting program: /home/tym/source/gdb/add
- main () at add.c:18
- 18 result[0] = add_range(1,10);
我们输入start,表示运行程序,到main函数的第一句的前面停止,但是这边为什么是在第二句前面停止呢?
gdb提供一步一步的运行程序,就是next或者n以及step,这两者有什么区别呢,step遇到函数时,会进入函数,next不会。
- (gdb) n
- 19 result[1] = add_range(1,100);
- (gdb) n
- 21 printf("result[0]=%d\nresult[1]=%d",result[0],result[1]);
那我们看看step会是什么状态呢?
- (gdb) s
- add_range (low=1, high=10) at add.c:7
- 7 for(i=low; i<=high; ++i)
下面就是调试add的整个过程:
- [tym@lxy gdb]$ gdb add
- GNU gdb Fedora (6.8-37.el5)
- Copyright (C) 2008 Free Software Foundation, Inc.
- License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
- This is free software: you are free to change and redistribute it.
- There is NO WARRANTY, to the extent permitted by law. Type "show copying"
- and "show warranty" for details.
- This GDB was configured as "i386-redhat-linux-gnu"...
- (gdb) start
- Breakpoint 1 at 0x80483bd: file add.c, line 18.
- Starting program: /home/tym/source/gdb/add
- main () at add.c:18
- 18 result[0] = add_range(1,10);
- (gdb) s
- add_range (low=1, high=10) at add.c:7
- 7 for(i=low; i<=high; ++i)
- (gdb) n
- 9 sum += i;
- (gdb) n
- 7 for(i=low; i<=high; ++i)
- (gdb) n
- 9 sum += i;
- (gdb) n
- 7 for(i=low; i<=high; ++i)
- (gdb) p sum
- $1 = 3
可以推断出1~10的sum是正确的,输入finish,让程序一直运行到从当前函数返回为止。
- (gdb) finish
- Run till exit from #0 add_range (low=1, high=10) at add.c:7
- 0x080483d1 in main () at add.c:18
- 18 result[0] = add_range(1,10);
- Value returned is $2 = 55
- (gdb) s
- 19 result[1] = add_range(1,100);
- (gdb) s
- add_range (low=1, high=100) at add.c:7
- 7 for(i=low; i<=high; ++i)
- (gdb) info loacls
- Undefined info command: "loacls". Try "help info".
- (gdb) info locals
- i = 11
- sum = 55
- (gdb) n
- 9 sum += i;
- (gdb) i locals
- i = 1
- sum = 55
从上面的调试你可以看出问题,sum的值并没有变化。所以1~100的值的不正确的。这样也就知道怎么修改程序了。
下面介绍下这章讲到的命令:
backtrace(或bt) 查看各级函数调用及参数
- (gdb) bt
- #0 add_range (low=1, high=100) at add.c:9
- #1 0x080483eb in main () at add.c:19
从结果可以看出add_range函数是被main函数调用的,main传进来的参数是low=1, high=10。main函数的栈帧编号为1,add_range的栈帧编号为0。
frame(或f) 帧编号 选择栈帧
- (gdb) f 1
- #1 0x080483eb in main () at add.c:19
- 19 result[1] = add_range(1,100);
info(或i) locals 查看当前栈帧局部变量的值
list(或l) 列出源代码,接着上次的位置往下列,每次列10行
list 函数名 列出某个函数的源代码
list 行号 列出从第几行开始的源代码
next(或n) 执行下一行语句
print(或p) 打印表达式的值,通过表达式可以修改变量的值或者调用函数
quit(或q) 退出gdb调试环境
set var 修改变量的值
start 开始执行程序,停在main函数第一行语句前面等待命令
step(或s) 执行下一行语句,如果有函数调用则进入到函数中
阅读(934) | 评论(0) | 转发(1) |