好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

linux下如何使用gdb调试

from test...done. (gdb)

 

有没有觉得这个世界一下子清净了许多。

也可以先进入gdb模式,然后再加载文件。

wang@king:~$ gdb - q
(gdb) file test
Reading symbols   from   test...done.
(gdb)  

好了,现在开始调试了,但是我还想看看我的代码怎么办,gdb提供了一条命令,可以让你的程序显示出来。

(gdb)                                        //  list默认一次显示10行 
 1     #include<stdio.h>
 2      int  func( int   n)
  3      {
  4          int   i;
  5          int  sum= 0  ;
  6          for (i= 0 ;i<n;i++ )
  7              {
  8                 sum+= i;
  9              }
  10          return   sum;
(gdb)                                         //  直接输入回车重复上次命令,显示接下来的10行 
 11      }
  12      int   main()
  13      {
  14          int   n;
  15         printf( "  请输入n的值  "  );
  16         scanf( "  %d  " ,& n);
  17         printf( "  1+2+..+%d=%d  "  ,n,func(n));
  18          return   0  ;
  19      }
(gdb) 
             

list默认参数可以用show listsize来查看,如果感觉10行太多或者太少,还可以用set listsize <count>来更改。

list 还可以加上其他参数,比如:
list 5,10   显示第5行到第10行的代码;

list func   显示func函数周围的代码,显示范围和list参数有关;

list test.c:5,10  显示源文件test.c第5行到第10行的代码,一般用于调试含多个源文件的程序。

gdb 还支持字符串查找,search str,从当前行开始,向前查找含str的字符串;

reverse-search str,从当前行开始,向后查找含str的字符串。

现在你的屏幕应该被占满了吧?想清空屏幕,可是还在gdb里面呀,怎么办?其实,gdb也支持运行linux命令的,可以在gdb的提示符中,输入shell,然后在输入你需要的命令就可以了

(gdb) shell clear

这样也能达到清屏的效果。

看了程序的代码,感觉第6行代码可能有点问题,现在就需要我就需要设置一个断点,让程序停在第6行之前。

(gdb)  break   6  
Breakpoint   1  at  0x80484c8 : file test.c, line  6  .
(gdb)  

下面一行的 信息,1说明我设置的这个断点是第一个断点,断点所在内存地址为0x80484c8,它在文件test.c的第6行。

gdb还可以以条件表达式设置断点。

(gdb)  break   7   if  n== 6  
Breakpoint   2  at  0x80484d1 : file test.c, line  7  .
(gdb)  

这个断点的含义是,如果n的值为6,则程序运行到第7行停止。

当然,还可以直接在某个函数处设置断点;直接break 函数名就可以了,

然后我们想看下设置的断点信息,可以使用info breakpoints命令。

 (gdb) info breakpoints
Num     Type           Disp Enb Address    What
  1        breakpoint     keep y    0x080484c8   in  func at test.c: 6 
 2        breakpoint     keep y    0x080484d1   in  func at test.c: 7  
    stop only   if  n== 6 
 4        breakpoint     keep y    0x080484c1   in  func at test.c: 5  
(gdb)  

Num表示断点的编号;Type表示断点的断点的类型,第二个断点类型还加上了条件;Disp表示中断点在执行一次之后是否失去作用,dis为是,keep为不是;Enb表示当前中断点是否有效,y为是,n为否;Address表示中断点所处的内存地址;What指出断点所处的位置。

如果不需要程序在该断点暂停时,有两种方法,一种是使该断点失效,一种是直接删除该断点。

(gdb) disable  1  
(gdb) info breakpoints
Num     Type           Disp Enb Address    What
  1        breakpoint     keep n    0x080484c8   in  func at test.c: 6 
 2        breakpoint     keep y    0x080484d1   in  func at test.c: 7  
    stop only   if  n== 6 
 3        breakpoint     keep y    0x080484c1   in  func at test.c: 5  
(gdb)  

可以看到,第一个断点的Enb变为n了,表示该断点已经无效了,如果需要恢复,可以使用enable命令。这里需要注意的是,disable后面的参数为断点的编号。而不是行号。

直接删除该断点,可以使用clear命令和delete命令。

(gdb) clear  6  
已删除的断点   1   
(gdb)  

clear命令后面的参数为设置断点的行号,clear后面参数还可以加设置断点的函数名。

delete命令后面的参数为断点的编号;可以一次删除多个断点,断点编号之间用空格隔开;如果delete后没有参数,默认删除所以断点,会给出提示选择是否操作。

 (gdb) delete
删除所有断点吗? (y or n)  

断点设置好了,现在就可以调试了,

(gdb) run                                                 //  开始执行程序 
Starting program: /home/wang/ test 
请输入n的值10

Breakpoint   1 , func (n= 10 ) at test.c: 6       //  设置的第一个断点,程序在第6行暂停 
 6          for (i= 0 ;i<n;i++ )
(gdb)   continue                                        //  让程序继续运行,直到下个断点或者结束 
 Continuing.

Breakpoint   2 , func (n= 10 ) at test.c: 8      //  第二个断点设置的是i==6时停止 
 8                 sum+= i;
(gdb) print i                                            //  用print命令打印出i的值 
$ 1  =  6  
(gdb) print sum
$  2  =  15  
(gdb) next                                            //  继续执行下一条语句,只执行一条。 
 6          for (i= 0 ;i<n;i++ )
(gdb) next    
  8                 sum+= i;
(gdb) print i
$  3  =  7  
(gdb)   continue      
Continuing.
  1 + 2 +..+ 10 = 45 [Inferior  1  (process  23636  ) exited normally]    
(gdb) quit                                               //  退出gdb调试 
                                            

 上面出现了很多命令,下面就来说说都是怎么用的。

run,开始运行程序;

continue,程序暂停时继续运行程序的命令;

print 变量名或表达式,打印该变量或者该表达式的值。whatis 变量名或者表达式,可以显示该变量或表达式的数据类型。

print  变量=值,这种形式还可以给对应的变量赋值;类似的还有set variable 变量=值。作用和用print赋值相同。

next,继续执行下一条语句;还有一条命令step,与之类似,不同的是,当下一条语句遇到函数调用的时候,next不会跟踪进入函数,而是继续执行下面的语句,而step命令则会跟踪进入函数内部。

 (gdb) run
Starting program:  /home/wang/ test 

Breakpoint   1 , main () at test.c: 16 
 16         scanf( "  %d  " ,& n);
(gdb) next
请输入n的值10  
  17         printf( "  1+2+..+%d=%d  "  ,n,func(n));
(gdb) next                                               //  next命令直接执行下一行,没有进入func函数   
 18          return   0  ;
(gdb) 

 

 (gdb) run
Starting program:  /home/wang/ test 

Breakpoint   1 , main () at test.c: 16 
 16         scanf( "  %d  " ,& n);
(gdb) n
请输入n的值10
  17         printf( "  1+2+..+%d=%d  "  ,n,func(n));
(gdb) step                    //  step命令跟踪进入了func函数   
func (n= 10 ) at test.c: 5 
 5          int  sum= 0  ;
(gdb)  


 还有nexti和stepi命令,这两个是单步执行一条机器指令,比如(i=0;i<n;i++)这条语句需要输入多个nexti才能执行完;两个的区别和上面相同。

quit,退出gdb调试,如果调试中想要退出,可以直接输入该命令,会出现提示选择是否退出。kill命令,结束当前程序的调试,(不会退出gdb)。

 (gdb) quit
A debugging session   is   active.

    Inferior   1  [process  32229 ] will be killed.

Quit anyway? (y or n) 

linux下如何使用gdb调试

标签:

查看更多关于linux下如何使用gdb调试的详细内容...

  阅读:27次