Chinaunix首页 | 论坛 | 博客
  • 博客访问: 149814
  • 博文数量: 23
  • 博客积分: 546
  • 博客等级: 中士
  • 技术积分: 608
  • 用 户 组: 普通用户
  • 注册时间: 2012-07-02 18:04
文章分类

全部博文(23)

文章存档

2012年(23)

我的朋友

分类: LINUX

2012-07-03 08:48:01

1、单步调试和函数的跟踪:

点击(此处)折叠或打开

  1. #include <stdio.h>

  2. int add_range(int low, int high)
  3. {
  4.     int i,sum;
  5.     
  6.     for(i=low; i<=high; ++i)
  7.         {
  8.             sum += i;
  9.         }
  10.     return sum;
  11. }

  12. int main()
  13. {
  14.     int result[100];
  15.     
  16.     result[0] = add_range(1,10);
  17.     result[1] = add_range(1,100);

  18.     printf("result[0]=%d\nresult[1]=%d",result[0],result[1]);

  19.     return 0;
  20. }
注:要想调试一个程序的话,在用gcc编译的时候就需要把调试信息加进去,否则gdb是不会工作的。下面就从上面的程序来讲述gdb的使用。
这个程序的功能就是计算1~10和1~100的和。但是程序结果是:

点击(此处)折叠或打开

  1. result[0]=55
  2. result[1]=5105
由此看出1~100的计算结果是不正确的。下面用gdb来一步步调试程序结果。
 
一、首先输入gdb add 或者gdbfile 回车 file add。注意add是可执行文件,但是你要是修改了源文件的名字,gdb也是不会起作用的。
 
二、list或者l查看源代码,list每次只会显示10行代码,list + 函数名

点击(此处)折叠或打开

  1. (gdb) list 1
  2. 1 #include <stdio.h>
  3. 2
  4. 3 int add_range(int low, int high)
  5. 4 {
  6. 5 int i,sum;
  7. 6
  8. 7 for(i=low; i<=high; ++i)
  9. 8 {
  10. 9 sum += i;
  11. 10 }


也可以什么都不输直接敲回车,gdb提供了一个很方便的功能,在提示符下直接敲回车表示重复上一条命令。

点击(此处)折叠或打开

  1. gdb)
  2. 11 return sum;
  3. 12 }
  4. 13
  5. 14 int main()
  6. 15 {
  7. 16 int result[100];
  8. 17
  9. 18 result[0] = add_range(1,10);
  10. 19 result[1] = add_range(1,100);
  11. 20

gdb的很多常用命令有简写形式,例如list命令可以写成l,要列一个函数的源代码也可以用函数名做参数:

点击(此处)折叠或打开

  1. (gdb) l add_range
  2. 1 #include <stdio.h>
  3. 2
  4. 3 int add_range(int low, int high)
  5. 4 {
  6. 5 int i,sum;
  7. 6
  8. 7 for(i=low; i<=high; ++i)
  9. 8 {
  10. 9 sum += i;
  11. 10 }
gdb提供quit命令退出gdb程序

点击(此处)折叠或打开

  1. (gdb) quit
好,基础就介绍到这里,下面来调试上面的程序:

  1. [tym@lxy gdb]$ gdb add
  2. GNU gdb Fedora (6.8-37.el5)
  3. Copyright (C) 2008 Free Software Foundation, Inc.
  4. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
  5. This is free software: you are free to change and redistribute it.
  6. There is NO WARRANTY, to the extent permitted by law. Type "show copying"
  7. and "show warranty" for details.
  8. This GDB was configured as "i386-redhat-linux-gnu"...
  9. (gdb) start
  10. Breakpoint 1 at 0x80483bd: file add.c, line 18.
  11. Starting program: /home/tym/source/gdb/add
  12. main () at add.c:18
  13. 18 result[0] = add_range(1,10);

我们输入start,表示运行程序,到main函数的第一句的前面停止,但是这边为什么是在第二句前面停止呢?
gdb提供一步一步的运行程序,就是next或者n以及step,这两者有什么区别呢,step遇到函数时,会进入函数,next不会。

点击(此处)折叠或打开

  1. (gdb) n
  2. 19 result[1] = add_range(1,100);
  3. (gdb) n
  4. 21 printf("result[0]=%d\nresult[1]=%d",result[0],result[1]);

 

那我们看看step会是什么状态呢?

点击(此处)折叠或打开

  1. (gdb) s
  2. add_range (low=1, high=10) at add.c:7
  3. 7 for(i=low; i<=high; ++i)

下面就是调试add的整个过程:

点击(此处)折叠或打开

  1. [tym@lxy gdb]$ gdb add
  2. GNU gdb Fedora (6.8-37.el5)
  3. Copyright (C) 2008 Free Software Foundation, Inc.
  4. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
  5. This is free software: you are free to change and redistribute it.
  6. There is NO WARRANTY, to the extent permitted by law. Type "show copying"
  7. and "show warranty" for details.
  8. This GDB was configured as "i386-redhat-linux-gnu"...
  9. (gdb) start
  10. Breakpoint 1 at 0x80483bd: file add.c, line 18.
  11. Starting program: /home/tym/source/gdb/add
  12. main () at add.c:18
  13. 18 result[0] = add_range(1,10);
  14. (gdb) s
  15. add_range (low=1, high=10) at add.c:7
  16. 7 for(i=low; i<=high; ++i)
  17. (gdb) n
  18. 9 sum += i;
  19. (gdb) n
  20. 7 for(i=low; i<=high; ++i)
  21. (gdb) n
  22. 9 sum += i;
  23. (gdb) n
  24. 7 for(i=low; i<=high; ++i)
  25. (gdb) p sum
  26. $1 = 3

可以推断出1~10的sum是正确的,输入finish,让程序一直运行到从当前函数返回为止。

点击(此处)折叠或打开

  1. (gdb) finish
  2. Run till exit from #0 add_range (low=1, high=10) at add.c:7
  3. 0x080483d1 in main () at add.c:18
  4. 18 result[0] = add_range(1,10);
  5. Value returned is $2 = 55
  6. (gdb) s
  7. 19 result[1] = add_range(1,100);
  8. (gdb) s
  9. add_range (low=1, high=100) at add.c:7
  10. 7 for(i=low; i<=high; ++i)
  11. (gdb) info loacls
  12. Undefined info command: "loacls". Try "help info".
  13. (gdb) info locals
  14. i = 11
  15. sum = 55
  16. (gdb) n
  17. 9 sum += i;
  18. (gdb) i locals
  19. i = 1
  20. sum = 55

从上面的调试你可以看出问题,sum的值并没有变化。所以1~100的值的不正确的。这样也就知道怎么修改程序了。

下面介绍下这章讲到的命令:

backtrace(或bt)         查看各级函数调用及参数

点击(此处)折叠或打开

  1. (gdb) bt
  2. #0 add_range (low=1, high=100) at add.c:9
  3. #1 0x080483eb in main () at add.c:19

从结果可以看出add_range函数是被main函数调用的,main传进来的参数是low=1, high=10。main函数的栈帧编号为1,add_range的栈帧编号为0。

frame(或f) 帧编号          选择栈帧

点击(此处)折叠或打开

  1. (gdb) f 1
  2. #1 0x080483eb in main () at add.c:19
  3. 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)                 执行下一行语句,如果有函数调用则进入到函数中

阅读(914) | 评论(0) | 转发(1) |
0

上一篇:没有了

下一篇:gdb的使用二

给主人留下些什么吧!~~