gdb调式程序 .

最近要调试PHP源代码,使用工具GDB.

1. GDB简介

GDB是Linux/Unix下一个GNU调试程序,是用来调试C与C++程序的强力调试器。能够让用户在程序运行时观察程序的内部结构和内存的使用情况。
作用:
1)按照自定义的方式启动运行需要调试的程序。
2)可以使用指定位置和条件表达式的方式来设置断点。
3)程序暂停时的值的监视。
4)动态改变程序的执行环境。

2.  基本操作命令:

这里只介绍常用命令的简单用法,如需读者想更加深入的了解,还请读者参照gdb手册。也可以使用--help查看。
基本命令列表:

命令
解释
简写
file
装入想要调试的可执行文件
list
列出产生执行文件源代码的一部分
l
next
执行一行源代码但不进入函数内部
n
step
执行一行源代码而且进入函数内部
s
run
执行当前被调试的程序
r
continue
继续执行程序
c
quit
终止GDB
q
print
输出当前指定变量的值
p
break
在代码里设置断点
b
info break
查看设置断点的信息
i b
delete
删除设置的断点
d
watch
监视一个变量的值,一旦值有变化,程序停住
wa
help
GDB中的帮助命令
h

3,编程实例

创建c文件:test.c

  1. #include<stdio.h>   
  2. #include<string.h>   
  3. void prints(int i)  
  4. {  
  5.    printf("hello %d\n", i);  
  6. }  
  7. void main ()  
  8.   
  9. {  
  10.   int i =0;  
  11.   for(i=1;i<6;i++){  
  12.      prints(i);  
  13.   }  
  14.   
  15. }  
#include<stdio.h>
#include<string.h>
void prints(int i)
{
   printf("hello %d\n", i);
}
void main ()

{
  int i =0;
  for(i=1;i<6;i++){
     prints(i);
  }

}

编译,其目标文件为test

gcc -o test test.c

这个程序执行

  1. ./test   
./test 

时显示如下结果:

hello 1
hello 2
hello 3
hello 4
hello 5

4 gdb调试程序

如果需要使用gdb调试

在编译test.c的时候,并把调试选项打开:

  1. gcc -o -ggdb test test.c  
gcc -o -ggdb test test.c

调试选项资料:

调试选项(DEBUGGING OPTION)

GNU CC拥有许多特别选项,既可以调试用户的程序,也可以对GCC排错: 
-g 
以操作系统的本地格式(stabs, COFF, XCOFF,或DWARF).产生调试信息. GDB能够使用这些调试信息. 
在大多数使用stabs格式的系统上, `-g'选项启动只有GDB才使用的额外调试信息;这些信息使GDB 调试效果更好,但是有可能导致其他调试器崩溃,或拒绝读入程序.如果你确定要控制是否生成额外的信息, 使用`-gstabs+', `-gstabs', `-gxcoff+', `-gxcoff', `-gdwarf+',或`-gdwarf' (见下文). 
和大多数C编译器不同, GNU CC允许结合使用`-g'和`-O'选项.优化的代码偶尔制造 一些惊异的结果:某些声明过的变量根本不存在;控制流程直接跑到没有预料到的地方;某些语句因为计算结果是常量或已经确定而 没有执行;某些语句在其他地方执行,因为他们被移到循环外面了. 
然而它证明了调试优化的输出是可能的.对可能含有错误的程序使用优化器是合理的. 
如果GNU CC支持输出多种调试信息,下面的选项则非常有用. 
-ggdb 

以本地格式(如果支持)输出调试信息,尽可能包括GDB扩展. 


1)启动

2)载入文件:file命令

file test

结果:

  1. gcc -o -ggdb test test.c  
gcc -o -ggdb test test.c

也可以通过直接启动的方式载入文件:

  1. root@ubuntu:/opt/c++# gdb test  
  2. GNU gdb (Ubuntu/Linaro 7.2-1ubuntu11) 7.2  
  3. Copyright (C) 2010 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 "i686-linux-gnu".  
  9. For bug reporting instructions, please see:  
  10. <http://www.gnu.org/software/gdb/bugs/>...  
  11. Reading symbols from /opt/c++/test...done.  
root@ubuntu:/opt/c++# gdb test
GNU gdb (Ubuntu/Linaro 7.2-1ubuntu11) 7.2
Copyright (C) 2010 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 "i686-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /opt/c++/test...done.

3)list命令

也可以过回车查看源代码

  1. (gdb) list  
  2. 1   #include<stdio.h>  
  3. 2   #include<string.h>  
  4. 3   void prints(int i)  
  5. 4   {  
  6. 5      printf("hello %d\n", i);  
  7. 6   }  
  8. 7   void main ()  
  9. 8     
  10. 9   {  
  11. 10    int i =0;  
  12. (gdb)   
(gdb) list
1	#include<stdio.h>
2	#include<string.h>
3	void prints(int i)
4	{
5	   printf("hello %d\n", i);
6	}
7	void main ()
8	
9	{
10	  int i =0;
(gdb) 

一次只列10行,如果要从11行开始继续列源代码可以输入

(gdb) list

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

回车:

  1. (gdb) list  
  2. 1   #include<stdio.h>  
  3. 2   #include<string.h>  
  4. 3   void prints(int i)  
  5. 4   {  
  6. 5      printf("hello %d\n", i);  
  7. 6   }  
  8. 7   void main ()  
  9. 8     
  10. 9   {  
  11. 10    int i =0;  
  12. (gdb)   
  13. 11    for(i=1;i<6;i++){  
  14. 12       prints(i);  
  15. 13    }  
  16. 14    
  17. 15  }  
  18. 16    
  19. (gdb)   
(gdb) list
1	#include<stdio.h>
2	#include<string.h>
3	void prints(int i)
4	{
5	   printf("hello %d\n", i);
6	}
7	void main ()
8	
9	{
10	  int i =0;
(gdb) 
11	  for(i=1;i<6;i++){
12	     prints(i);
13	  }
14	
15	}
16	
(gdb) 


4)单步逐条执行 next

首先用start命令开始执行程序:

  1. (gdb) start  
  2. Temporary breakpoint 1 at 0x80483e9: file test1.c, line 10.  
  3. Starting program: /opt/c++/test1   
  4.   
  5. Temporary breakpoint 1, main () at test1.c:10  
  6. 10    int i =0;  
  7. (gdb)   
(gdb) start
Temporary breakpoint 1 at 0x80483e9: file test1.c, line 10.
Starting program: /opt/c++/test1 

Temporary breakpoint 1, main () at test1.c:10
10	  int i =0;
(gdb) 

这表示停在main函数中变量定义之后的第一条语句处等待我们发命令,gdb列出这条语句表示它还没执行,并且马上要执行

我们可以用next命令(简写为n)控制这些语句一条一条地执行:

  1. (gdb) next  
  2. 11    for(i=1;i<6;i++){  
  3. (gdb) (直接回车)  
  4. 12       prints(i);  
  5. (gdb)   
  6.   
  7. hello 1  
  8. 11    for(i=1;i<6;i++){  
  9. (gdb)   
  10. 12       prints(i);  
  11. (gdb)   
  12. hello 2  
  13. 11    for(i=1;i<6;i++){  
  14. (gdb)   
  15. 12       prints(i);  
  16. (gdb)   
  17. hello 3  
  18. 11    for(i=1;i<6;i++){  
  19. (gdb)   
  20. 12       prints(i);  
  21. (gdb)   
  22. hello 4  
  23. 11    for(i=1;i<6;i++){  
  24. (gdb)   
  25. 12       prints(i);  
  26. (gdb)   
  27. hello 5  
  28. 11    for(i=1;i<6;i++){  
  29. (gdb)   
  30. 15  }  
  31. (gdb)   
(gdb) next
11	  for(i=1;i<6;i++){
(gdb) (直接回车)
12	     prints(i);
(gdb) 

hello 1
11	  for(i=1;i<6;i++){
(gdb) 
12	     prints(i);
(gdb) 
hello 2
11	  for(i=1;i<6;i++){
(gdb) 
12	     prints(i);
(gdb) 
hello 3
11	  for(i=1;i<6;i++){
(gdb) 
12	     prints(i);
(gdb) 
hello 4
11	  for(i=1;i<6;i++){
(gdb) 
12	     prints(i);
(gdb) 
hello 5
11	  for(i=1;i<6;i++){
(gdb) 
15	}
(gdb) 

5)逐条执行并进入函数:

用start命令重新来过,step命令(简写为s)进入 函数中去执行:

  1. (gdb) start  
  2. Temporary breakpoint 2 at 0x80483e9: file test1.c, line 10.  
  3. Starting program: /opt/c++/test1   
  4.   
  5. Temporary breakpoint 2, main () at test1.c:10  
  6. 10    int i =0;  
  7. (gdb) next  
  8. 11    for(i=1;i<6;i++){  
  9. (gdb) next  
  10. 12       prints(i);  
  11. (gdb) step  
  12. prints (i=1) at test1.c:5  
  13. 5      printf("hello %d\n", i);  
  14. (gdb)   
(gdb) start
Temporary breakpoint 2 at 0x80483e9: file test1.c, line 10.
Starting program: /opt/c++/test1 

Temporary breakpoint 2, main () at test1.c:10
10	  int i =0;
(gdb) next
11	  for(i=1;i<6;i++){
(gdb) next
12	     prints(i);
(gdb) step
prints (i=1) at test1.c:5
5	   printf("hello %d\n", i);
(gdb) 
进入到了函数 prints

在函数中有几种查看状态的办法,backtrace命令(简写为bt)可以查看函数调用的栈帧:

  1. (gdb) bt  
  2. #0  prints (i=1) at test1.c:5  
  3. #1  0x08048407 in main () at test1.c:12  
  4. (gdb)   
(gdb) bt
#0  prints (i=1) at test1.c:5
#1  0x08048407 in main () at test1.c:12
(gdb) 
main传进来的参数是i=1。main函数的栈帧编号为1,prints的栈帧编号为0。

6)在可以用info命令(简写为i)查看局部变量

  1. i  locals  
i  locals

如果想查看main函数当前局部变量的值也可以做到,先用frame命令(简写为f)选择1号栈帧然后再查看局部变量:

  1. (gdb) f 1  
  2. #1  0x08048407 in main () at test1.c:12  
  3. 12       prints(i);  
  4. (gdb)   
(gdb) f 1
#1  0x08048407 in main () at test1.c:12
12	     prints(i);
(gdb) 

7)输出当前指定变量的值 print

  1. (gdb) p i  
  2. $1 = 1  
  3. (gdb)   

http://blog.csdn.net/hguisu/article/details/7420161

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值