关于GDB调试工具的学习总结

GDB GNU开源组织发布的一个强大的UNIX下的程序调试工具。如果你是在UNIX平台下做软件,你会发现GDB这个调试工具有比VCBCB的图形化调试器更强大的功能。。
下面举一个调试例子对其用法加以说明:
源程序:a.c
      1 #include<stdio.h>
      2 #include<string.h>
      3 int main(int argc,char* argv[])
      4 {
      5     unsigned short s;
      6     int i;
      7     char buf[10];
      8
      9     if(argc < 3)
     10     {
     11         printf("Usage:%s <length><string>\n",argv[0]);
     12         return -1;
     13     }
     14
     15     i=atoi(argv[1]);
     16     s=i;
     17
     18     if(s>=10)
     19     {
     20         printf("string too long!\n");
     21         return -1;
     22     }
     23
     24     memcpy(buf,argv[2],i);
     25     buf[i]='\0';
     26     printf("%s\n",buf);
     27     return 0;
     28  }  
 
操作步骤:
1. gcc -g a.c -o a.out    <- 编译时-g 打开调试选项;
2. gdb a.out                  <- 注意gdb后面跟的是可执行程序;
GNU gdb Red Hat Linux (5.3post-0.20021129.18rh)
Copyright 2003 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "i386-redhat-linux-gnu"...
(gdb)l                               <- l list的缩写,是查看源程序内容的命令;
1       #include<stdio.h>
2       #include<string.h>
3       int main(int argc,char* argv[])
4       {
5                       unsigned short s;
6                       int i;
7                       char buf[10];
8
9                       if(argc < 3)
10                      {
(gdb)<enter>                   <- 直接回车时重复执行上次的命令;
11                                      printf("Usage:%s <length><string>\n",argv[0]);
12                                      return -1;
13                      }
14
15                      i=atoi(argv[1]);
16                      s=i;
17
18                      if(s>=10)
19                      {
20                                      printf("string too long!\n");
(gdb)b 15                   <- b + 数字 是在某一行设置一个断点,可以同时设置多个断点;
Breakpoint 1 at 0x80483c4: file overflow.c, line 15.  ç 显示出断点的信息;
(gdb)r 5 hello  <- 运行程序,在设置的断点处停止。注意程序的运行规则,如加参数等;
Starting program: /root/test/day7/a.out 5 hello
 
Breakpoint 1, main (argc=3, argv=0xbfffdea4) at overflow.c:15 ç 停止在断点处;
15                      i=atoi(argv[1]);
(gdb)p i               <- 查看一下此时变量i的值;
$1 = -1073747112   <- 由于i此时还未有值,出现一个随机的值;
(gdb)n              <- 单步执行程序后半部分;
16                      s=i;      <- 显示执行的是哪一行;
(gdb)p i             <- 查看执行上一步语句之后变量i的值;
$2 = 5
(gdb)info break  <- 查看整个程序断点信息,如断点的个数及其位置;
Num Type           Disp Enb Address    What
1   breakpoint     keep y   0x080483c4 in main at overflow.c:15
        breakpoint already hit 1 time
(gdb)info all      <- 显示整个程序运行到此时,各个寄存器中的值;
eax            0x5      5
ecx            0x0      0
edx            0x5      5
ebx            0x42130a14       1108544020
esp            0xbfffeb20       0xbfffeb20
ebp            0xbfffeb58       0xbfffeb58
esi            0x40015360       1073828704
edi            0x8048474        134513780
eip            0x80483da        0x80483da
eflags         0x10382  66434
cs             0x23     35
ss             0x2b     43
ds             0x2b     43
es             0x2b     43
fs             0x0      0
gs             0x33     51
st0            0        (raw 0x00000000000000000000)
st1            0        (raw 0x00000000000000000000)
st2            0        (raw 0x00000000000000000000)
st3            0        (raw 0x00000000000000000000)
st4            0        (raw 0x00000000000000000000)
st5            0        (raw 0x00000000000000000000)
st6            0        (raw 0x00000000000000000000)
st7            0        (raw 0x00000000000000000000)
fctrl          0x37f    895
fstat          0x0      0
ftag           0xffff   65535
fiseg          0x0      0
fioff          0x0      0
foseg          0x0      0
fooff          0x0      0
fop            0x0      0
xmm0           {v4_float = {0x0, 0x0, 0x0, 0x0}, v2_double = {0x0, 0x0}, v16_int8 = {0x0 <repeats 16 times>}, v8_int16 = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
    0x0}, v4_int32 = {0x0, 0x0, 0x0, 0x0}, v2_int64 = {0x0, 0x0}, uint128 = 0x00000000000000000000000000000000}
xmm1           {v4_float = {0x0, 0x0, 0x0, 0x0}, v2_double = {0x0, 0x0}, v16_int8 = {0x0 <repeats 16 times>}, v8_int16 = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
    0x0}, v4_int32 = {0x0, 0x0, 0x0, 0x0}, v2_int64 = {0x0, 0x0}, uint128 = 0x00000000000000000000000000000000}
xmm2           {v4_float = {0x0, 0x0, 0x0, 0x0}, v2_double = {0x0, 0x0}, v16_int8 = {0x0 <repeats 16 times>}, v8_int16 = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
    0x0}, v4_int32 = {0x0, 0x0, 0x0, 0x0}, v2_int64 = {0x0, 0x0}, uint128 = 0x00000000000000000000000000000000}
xmm3           {v4_float = {0x0, 0x0, 0x0, 0x0}, v2_double = {0x0, 0x0}, v16_int8 = {0x0 <repeats 16 times>}, v8_int16 = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
    0x0}, v4_int32 = {0x0, 0x0, 0x0, 0x0}, v2_int64 = {0x0, 0x0}, uint128 = 0x00000000000000000000000000000000}
xmm4           {v4_float = {0x0, 0x0, 0x0, 0x0}, v2_double = {0x0, 0x0}, v16_int8 = {0x0 <repeats 16 times>}, v8_int16 = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
    0x0}, v4_int32 = {0x0, 0x0, 0x0, 0x0}, v2_int64 = {0x0, 0x0}, uint128 = 0x00000000000000000000000000000000}
xmm5           {v4_float = {0x0, 0x0, 0x0, 0x0}, v2_double = {0x0, 0x0}, v16_int8 = {0x0 <repeats 16 times>}, v8_int16 = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
    0x0}, v4_int32 = {0x0, 0x0, 0x0, 0x0}, v2_int64 = {0x0, 0x0}, uint128 = 0x00000000000000000000000000000000}
xmm6           {v4_float = {0x0, 0x0, 0x0, 0x0}, v2_double = {0x0, 0x0}, v16_int8 = {0x0 <repeats 16 times>}, v8_int16 = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
    0x0}, v4_int32 = {0x0, 0x0, 0x0, 0x0}, v2_int64 = {0x0, 0x0}, uint128 = 0x00000000000000000000000000000000}
xmm7           {v4_float = {0x0, 0x0, 0x0, 0x0}, v2_double = {0x0, 0x0}, v16_int8 = {0x0 <repeats 16 times>}, v8_int16 = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
    0x0}, v4_int32 = {0x0, 0x0, 0x0, 0x0}, v2_int64 = {0x0, 0x0}, uint128 = 0x00000000000000000000000000000000}
mxcsr          0x1f80   8064
mm0            {uint64 = 0x0, v2_int32 = {0x0, 0x0}, v4_int16 = {0x0, 0x0, 0x0, 0x0}, v8_int8 = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}}
mm1            {uint64 = 0x0, v2_int32 = {0x0, 0x0}, v4_int16 = {0x0, 0x0, 0x0, 0x0}, v8_int8 = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}}
mm2            {uint64 = 0x0, v2_int32 = {0x0, 0x0}, v4_int16 = {0x0, 0x0, 0x0, 0x0}, v8_int8 = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}}
mm3            {uint64 = 0x0, v2_int32 = {0x0, 0x0}, v4_int16 = {0x0, 0x0, 0x0, 0x0}, v8_int8 = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}}
mm4            {uint64 = 0x0, v2_int32 = {0x0, 0x0}, v4_int16 = {0x0, 0x0, 0x0, 0x0}, v8_int8 = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}}
mm5            {uint64 = 0x0, v2_int32 = {0x0, 0x0}, v4_int16 = {0x0, 0x0, 0x0, 0x0}, v8_int8 = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}}
---Type <return> to continue, or q <return> to quit---
mm6            {uint64 = 0x0, v2_int32 = {0x0, 0x0}, v4_int16 = {0x0, 0x0, 0x0, 0x0}, v8_int8 = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}}
mm7            {uint64 = 0x0, v2_int32 = {0x0, 0x0}, v4_int16 = {0x0, 0x0, 0x0, 0x0}, v8_int8 = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}}
(gdb)file b.out         <- 继续调试另外一个程序;
 
一般来说,GDB主要用到以下几个功能:
1 、可以设置断点(断点可以是条件表达式),然后按照你的设置单步运行程序。
2 、当程序被停住时,可以检查此时你的程序中所发生的事,比如某一个标志性的变量的值的变化是否按照程序的目标运行。
3 、在单步运行过程中,随时查看变量的变化,如果出现异常可立即发现错误语句的位置,然后排错。
4 、动态的查看程序运行中各个寄存器中的值。

你可能感兴趣的:(linux,gdb,职场,休闲,调试工具)