gdb调试利器的学习

本文出自:http://blog.youkuaiyun.com/edroid1530/article/details/68946136 作为程序员,调试程序是不可避免的,在windows下常用的IDE比如 keil 软件会有集成的debug图形化调试工具,使用起来非常简单易懂。在Linux下虽然没有图形化调试工具,但是gdb作为文本界面的调试工具其功能也是非常强大的,在这里简单介绍gdb的用法。


一.调试准备


1.首先我们编写一个测试程序:

  1. [lwn@VM_255_164_centos temp2]vim&nbsp;gdbtest.c&nbsp;&nbsp;</span></span></li><li><span><span class="comment">/*********************************************************************************</span>&nbsp;</span></li><li class="alt"><span><span class="comment">&nbsp;&nbsp;2&nbsp;&nbsp;*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Copyright:&nbsp;&nbsp;(C)&nbsp;2017&nbsp;SCUEC</span>&nbsp;</span></li><li><span><span class="comment">&nbsp;&nbsp;3&nbsp;&nbsp;*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;All&nbsp;rights&nbsp;reserved.</span>&nbsp;</span></li><li class="alt"><span><span class="comment">&nbsp;&nbsp;4&nbsp;&nbsp;*</span>&nbsp;</span></li><li><span><span class="comment">&nbsp;&nbsp;5&nbsp;&nbsp;*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Filename:&nbsp;&nbsp;gdbtest.c</span>&nbsp;</span></li><li class="alt"><span><span class="comment">&nbsp;&nbsp;6&nbsp;&nbsp;*&nbsp;&nbsp;&nbsp;&nbsp;Description:&nbsp;&nbsp;This&nbsp;file</span>&nbsp;</span></li><li><span><span class="comment">&nbsp;&nbsp;7&nbsp;&nbsp;*</span>&nbsp;</span></li><li class="alt"><span><span class="comment">&nbsp;&nbsp;8&nbsp;&nbsp;*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Version:&nbsp;&nbsp;1.0.0(04/01/17)</span>&nbsp;</span></li><li><span><span class="comment">&nbsp;&nbsp;9&nbsp;&nbsp;*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Author:&nbsp;&nbsp;LI&nbsp;WJNG&nbsp;&lt;liwjng@gmail.com&gt;</span>&nbsp;</span></li><li class="alt"><span><span class="comment">&nbsp;10&nbsp;&nbsp;*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ChangeLog:&nbsp;&nbsp;1,&nbsp;Release&nbsp;initial&nbsp;version&nbsp;on&nbsp;"04/01/17&nbsp;15:19:12"</span>&nbsp;</span></li><li><span><span class="comment">&nbsp;11&nbsp;&nbsp;*</span>&nbsp;</span></li><li class="alt"><span><span class="comment">&nbsp;12&nbsp;&nbsp;********************************************************************************/</span><span>&nbsp;&nbsp;</span></span></li><li><span>&nbsp;13&nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;14&nbsp;#include&nbsp;&lt;stdio.h&gt;&nbsp;&nbsp;</span></li><li><span>&nbsp;15&nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;16&nbsp;<span class="datatypes">int</span><span>&nbsp;func(</span><span class="datatypes">int</span><span>&nbsp;n)&nbsp;&nbsp;</span></span></li><li><span>&nbsp;17&nbsp;{&nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;18&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="datatypes">int</span><span>&nbsp;sum=0,i;&nbsp;&nbsp;</span></span></li><li><span>&nbsp;19&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">for</span><span>(i=0;i&lt;n;i++)&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;20&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;</span></li><li><span>&nbsp;21&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sum&nbsp;+=&nbsp;i;&nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;22&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li><li><span>&nbsp;23&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">return</span><span>&nbsp;sum;&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;24&nbsp;}&nbsp;&nbsp;</span></li><li><span>&nbsp;25&nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;26&nbsp;&nbsp;</span></li><li><span>&nbsp;27&nbsp;<span class="comment">/********************************************************************************</span>&nbsp;</span></li><li class="alt"><span><span class="comment">&nbsp;28&nbsp;&nbsp;*&nbsp;&nbsp;Description:</span>&nbsp;</span></li><li><span><span class="comment">&nbsp;29&nbsp;&nbsp;*&nbsp;&nbsp;&nbsp;Input&nbsp;Args:</span>&nbsp;</span></li><li class="alt"><span><span class="comment">&nbsp;30&nbsp;&nbsp;*&nbsp;&nbsp;Output&nbsp;Args:</span>&nbsp;</span></li><li><span><span class="comment">&nbsp;31&nbsp;&nbsp;*&nbsp;Return&nbsp;Value:</span>&nbsp;</span></li><li class="alt"><span><span class="comment">&nbsp;32&nbsp;&nbsp;********************************************************************************/</span><span>&nbsp;&nbsp;</span></span></li><li><span>&nbsp;33&nbsp;<span class="datatypes">int</span><span>&nbsp;main&nbsp;(</span><span class="datatypes">int</span><span>&nbsp;argc,&nbsp;</span><span class="datatypes">char</span><span>&nbsp;**argv)&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;34&nbsp;{&nbsp;&nbsp;</span></li><li><span>&nbsp;35&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="datatypes">int</span><span>&nbsp;i;&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;36&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="datatypes">long</span><span>&nbsp;result&nbsp;=&nbsp;0;&nbsp;&nbsp;</span></span></li><li><span>&nbsp;37&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="datatypes">int</span><span>&nbsp;sum&nbsp;=&nbsp;0;&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;38&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sum&nbsp;&nbsp;=&nbsp;func(10);&nbsp;&nbsp;</span></li><li><span>&nbsp;39&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">for</span><span>(i=0;i&lt;100;i++)&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;40&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;</span></li><li><span>&nbsp;41&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;result&nbsp;+=&nbsp;i;&nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;42&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li><li><span>&nbsp;43&nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;44&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf(<span class="string">"the&nbsp;result&nbsp;is&nbsp;add&nbsp;1&nbsp;to&nbsp;100&nbsp;is&nbsp;%d\n"</span><span>,result);&nbsp;&nbsp;</span></span></li><li><span>&nbsp;45&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf(<span class="string">"the&nbsp;sum&nbsp;is&nbsp;add&nbsp;1&nbsp;to&nbsp;%d&nbsp;is&nbsp;%d\n"</span><span>,10,sum);&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;46&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">return</span><span>&nbsp;0;&nbsp;&nbsp;</span></span></li><li><span>&nbsp;47&nbsp;}&nbsp;<span class="comment">/*&nbsp;-----&nbsp;End&nbsp;of&nbsp;main()&nbsp;-----&nbsp;*/</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;48&nbsp;&nbsp;</span></li></ol><div class="save_code tracking-ad" style="display: none;" data-mod="popu_249"><a href="javascript:;" target="_blank"><img src="http://static.blog.youkuaiyun.com/images/save_snippets.png"></a></div></div><pre class="cpp" style="display: none;" name="code" snippet_file_name="blog_20170401_1_6673937" code_snippet_id="2306771">[lwn@VM_255_164_centos temp2]vim gdbtest.c /********************************************************************************* 2 * Copyright: (C) 2017 SCUEC 3 * All rights reserved. 4 * 5 * Filename: gdbtest.c 6 * Description: This file 7 * 8 * Version: 1.0.0(04/01/17) 9 * Author: LI WJNG <liwjng@gmail.com> 10 * ChangeLog: 1, Release initial version on “04/01/17 15:19:12” 11 * 12 ********************************************************************************/ 13 14 #include <stdio.h> 15 16 int func(int n) 17 { 18 int sum=0,i; 19 for(i=0;i<n;i++) 20 { 21 sum += i; 22 } 23 return sum; 24 } 25 26 27 /******************************************************************************** 28 * Description: 29 * Input Args: 30 * Output Args: 31 * Return Value: 32 ********************************************************************************/ 33 int main (int argc, char **argv) 34 { 35 int i; 36 long result = 0; 37 int sum = 0; 38 sum = func(10); 39 for(i=0;i<100;i++) 40 { 41 result += i; 42 } 43 44 printf(“the result is add 1 to 100 is %d\n”,result); 45 printf(“the sum is add 1 to %d is %d\n”,10,sum); 46 return 0; 47 } /* —– End of main() —– */ 48

    2.编译程序

    要使用gdb调试,编译的时候一定要加上 -g 选项,如:gcc -g test.c,否则在gdb命令中l的时候会出现:No symbol table is loaded.  Use the “file” command.错误提示;

    1. [lwn@VM_255_164_centos temp2]&nbsp;gcc&nbsp;-g&nbsp;gdbtest.c&nbsp;-o&nbsp;test&nbsp;&nbsp;</span></span></li><li><span>[lwn@VM_255_164_centos&nbsp;temp2] ls  
    2. gdbtest.c  test  
    [lwn@VM_255_164_centos temp2]$ gcc -g gdbtest.c -o test
    [lwn@VM_255_164_centos temp2]$ ls
    gdbtest.c  test
    


    3.使用gdb命令进入调试界面

    如果直接使用gdb test 会打印gdb的版本信息等,为了显示简洁一点,使用gdb -q可以不显示版本信息
    1. [lwn@VM_255_164_centos temp2]&nbsp;gdb&nbsp;-q&nbsp;test&nbsp;&nbsp;</span></span></li><li><span>Reading&nbsp;symbols&nbsp;from&nbsp;/home/lwn/mysrc/temp2/test...done.&nbsp;&nbsp;</span></li><li class="alt"><span>(gdb)&nbsp;&nbsp;</span></li></ol><div class="save_code tracking-ad" data-mod="popu_249"><a href="javascript:;" target="_blank"><img src="http://static.blog.youkuaiyun.com/images/save_snippets.png"></a></div></div><pre class="cpp" style="display: none;" name="code" snippet_file_name="blog_20170401_3_1036547" code_snippet_id="2306771">[lwn@VM_255_164_centos temp2] gdb -q test Reading symbols from /home/lwn/mysrc/temp2/test…done. (gdb)

    二.gdb调试命令:


    在gdb调试界面下可以直接使用gdb的调试命令,enter继续执行上条命令。



    下面逐条分析:

    1.使用list(简写:l) 命令,将看到部分源程序清单。

    list:                显示源程序1-10行
    list +行号:      显示行号前后若干行
    list +函数名:          显示函数前后若干行
    这里就不一一列举了,所有有关list的相关操作可以使用 help list 命令进行查看
    如:
    1. (gdb) l main  
    2. 29       *   Input Args:  
    3. 30       *  Output Args:  
    4. 31       * Return Value:  
    5. 32       ********************************************************************************/  
    6. 33      int main (int argc, char **argv)  
    7. 34      {  
    8. 35          int i;  
    9. 36          long result = 0;  
    10. 37          int sum = 0;  
    11. 38          sum  = func(10);  
    12. (gdb) help list //可以看到有关list的命令说明  
    13. List specified function or line.  
    14. With no argument, lists ten more lines after or around previous listing.  
    15. ”list -“ lists the ten lines before a previous ten-line listing.  
    16. One argument specifies a line, and ten lines are listed around that line.  
    17. Two arguments with comma between specify starting and ending lines to list.  
    18. Lines can be specified in these ways:  
    19.   LINENUM, to list around that line in current file,  
    20.   FILE:LINENUM, to list around that line in that file,  
    21.   FUNCTION, to list around beginning of that function,  
    22.   FILE:FUNCTION, to distinguish among like-named static functions.  
    23.   *ADDRESS, to list around the line containing that address.  
    24. With two args if one is empty it stands for ten lines away from the other arg.  
    (gdb) l main
    29       *   Input Args:
    30       *  Output Args:
    31       * Return Value:
    32       ********************************************************************************/
    33      int main (int argc, char **argv)
    34      {
    35          int i;
    36          long result = 0;
    37          int sum = 0;
    38          sum  = func(10);
    (gdb) help list //可以看到有关list的命令说明
    List specified function or line.
    With no argument, lists ten more lines after or around previous listing.
    "list -" lists the ten lines before a previous ten-line listing.
    One argument specifies a line, and ten lines are listed around that line.
    Two arguments with comma between specify starting and ending lines to list.
    Lines can be specified in these ways:
      LINENUM, to list around that line in current file,
      FILE:LINENUM, to list around that line in that file,
      FUNCTION, to list around beginning of that function,
      FILE:FUNCTION, to distinguish among like-named static functions.
      *ADDRESS, to list around the line containing that address.
    With two args if one is empty it stands for ten lines away from the other arg.
    


    2.运行程序:run(简写:r),break(简写:b) ,continue(简写:c) ,until(简写:u)

      run命令可以让程序全速运行,直到遇到断点处才停下来。如果没有设置断点,那么程序将一直运行到程序结束。
      break命令用来设置断点,
      break +行号:将断点设置在固定某行
      break +函数名:将断点设置在函数开始处
      info break:列出所有的断点
     clear +行号:取消某行设置的断点
      contin命令让程序继续运行到下一处断点,如果后面没有断点将一直运行到程序末尾。 
      until+行号:让程序执行到固定某行,其作用等同于 break+ 行号,再continu;使用until命令的前提是程序已经在运行状态
    例如:
    1. (gdb) l main  
    2. 29       *   Input Args:  
    3. 30       *  Output Args:  
    4. 31       * Return Value:  
    5. 32       ********************************************************************************/  
    6. 33      int main (int argc, char **argv)  
    7. 34      {  
    8. 35          int i;  
    9. 36          long result = 0;  
    10. 37          int sum = 0;  
    11. 38          sum  = func(10);  
    12. (gdb) b main //在main函数开始出设置断点  
    13. Breakpoint 1 at 0x40056d: file gdbtest.c, line 36.  
    14. (gdb) b 38  //在第38行设置断点  
    15. Breakpoint 2 at 0x40057c: file gdbtest.c, line 38.  
    16.   
    17. (gdb) i b //命令info break列出所有的断点  
    18. Num     Type           Disp Enb Address            What  
    19. 1       breakpoint     keep y   0x000000000040056d in main at gdbtest.c:36  
    20.         breakpoint already hit 1 time  
    21. 2       breakpoint     keep y   0x000000000040057c in main at gdbtest.c:38  
    22.         breakpoint already hit 1 time  
    23.   
    24. (gdb) r  //r命令让程序全速运行  
    25. Starting program: /home/lwn/mysrc/temp2/test  
    26.   
    27. Breakpoint 1, main (argc=1, argv=0x7fffffffe5c8) at gdbtest.c:36 //遇到刚刚设置的第一个断点36行停了下来  
    28. 36          long result = 0;  
    29. Missing separate debuginfos, use: debuginfo-install glibc-2.17-106.el7_2.8.x86_64  
    30. (gdb) c //命令contin让程序继续运行  
    31. Continuing.  
    32.   
    33. Breakpoint 2, main (argc=1, argv=0x7fffffffe5c8) at gdbtest.c:38 //运行到设置的第二个断点听了下来  
    34. 38          sum  = func(10);  
    35.   
    36. (gdb) u 38//让程序执行到固定某一行  
    37. main (argc=1, argv=0x7fffffffe5c8) at gdbtest.c:38  
    38. 38          sum  = func(10);  
    (gdb) l main
    29       *   Input Args:
    30       *  Output Args:
    31       * Return Value:
    32       ********************************************************************************/
    33      int main (int argc, char **argv)
    34      {
    35          int i;
    36          long result = 0;
    37          int sum = 0;
    38          sum  = func(10);
    (gdb) b main //在main函数开始出设置断点
    Breakpoint 1 at 0x40056d: file gdbtest.c, line 36.
    (gdb) b 38  //在第38行设置断点
    Breakpoint 2 at 0x40057c: file gdbtest.c, line 38.
    
    (gdb) i b //命令info break列出所有的断点
    Num     Type           Disp Enb Address            What
    1       breakpoint     keep y   0x000000000040056d in main at gdbtest.c:36
            breakpoint already hit 1 time
    2       breakpoint     keep y   0x000000000040057c in main at gdbtest.c:38
            breakpoint already hit 1 time
    
    (gdb) r  //r命令让程序全速运行
    Starting program: /home/lwn/mysrc/temp2/test
    
    Breakpoint 1, main (argc=1, argv=0x7fffffffe5c8) at gdbtest.c:36 //遇到刚刚设置的第一个断点36行停了下来
    36          long result = 0;
    Missing separate debuginfos, use: debuginfo-install glibc-2.17-106.el7_2.8.x86_64
    (gdb) c //命令contin让程序继续运行
    Continuing.
    
    Breakpoint 2, main (argc=1, argv=0x7fffffffe5c8) at gdbtest.c:38 //运行到设置的第二个断点听了下来
    38          sum  = func(10);
    
    (gdb) u 38//让程序执行到固定某一行
    main (argc=1, argv=0x7fffffffe5c8) at gdbtest.c:38
    38          sum  = func(10);
    



    3.单步运行next(简写:n) 和step(简写:s) 

    如果希望程序逐条语句地执行程序,不停地b、c太过于麻烦,gdb提供了更加step 和next命令,其作用是运行当前行。区别在于如果当前行设计函数调用,next命令会把函数当做一条语句整体执行完毕,而step命令会进入到函数内部继续单步运行,下面来看例子:
    1. l (gdb) l //列出相关行的源程序  
    2. 31       * Return Value:  
    3. 32       ********************************************************************************/  
    4. 33      int main (int argc, char **argv)  
    5. 34      {  
    6. 35          int i;  
    7. 36          long result = 0;  
    8. 37          int sum = 0;  
    9. 38          sum  = func(10);  
    10. 39          for(i=0;i<100;i++)  
    11. 40          {  
    12. (gdb) b 38 //在调用函数的行设置断点  
    13. Breakpoint 3 at 0x40057c: file gdbtest.c, line 38.  
    14. (gdb) r  
    15. The program being debugged has been started already.  
    16. Start it from the beginning? (y or n) y  
    17. Starting program: /home/lwn/mysrc/temp2/test  
    18.   
    19. Breakpoint 3, main (argc=1, argv=0x7fffffffe5c8) at gdbtest.c:38  
    20. 38          sum  = func(10);  
    21. (gdb) n //可以看到使用next命令之后程序跳到了39行执行  
    22. 39          for(i=0;i<100;i++)  
    23.   
    24. ————————————————————————————————————————————————————————————————————————————————————————————————————  
    25. Breakpoint 3, main (argc=1, argv=0x7fffffffe5c8) at gdbtest.c:38  
    26. 38          sum  = func(10);  
    27. (gdb) s //同样使用step命令之后可以看到程序进入到了func函数去执行  
    28. func (n=10) at gdbtest.c:18  
    29. 18          int sum=0,i;  
    l (gdb) l //列出相关行的源程序
    31       * Return Value:
    32       ********************************************************************************/
    33      int main (int argc, char **argv)
    34      {
    35          int i;
    36          long result = 0;
    37          int sum = 0;
    38          sum  = func(10);
    39          for(i=0;i<100;i++)
    40          {
    (gdb) b 38 //在调用函数的行设置断点
    Breakpoint 3 at 0x40057c: file gdbtest.c, line 38.
    (gdb) r
    The program being debugged has been started already.
    Start it from the beginning? (y or n) y
    Starting program: /home/lwn/mysrc/temp2/test
    
    Breakpoint 3, main (argc=1, argv=0x7fffffffe5c8) at gdbtest.c:38
    38          sum  = func(10);
    (gdb) n //可以看到使用next命令之后程序跳到了39行执行
    39          for(i=0;i<100;i++)
    
    ————————————————————————————————————————————————————————————————————————————————————————————————————
    Breakpoint 3, main (argc=1, argv=0x7fffffffe5c8) at gdbtest.c:38
    38          sum  = func(10);
    (gdb) s //同样使用step命令之后可以看到程序进入到了func函数去执行
    func (n=10) at gdbtest.c:18
    18          int sum=0,i;
    

    4.打印相关信息info(简写:i),print(简写:p),display(简写:disp)

    程序运行到某个位置的时候,我们使用info和print命令可以打印出一些变量的值
    info local:打印局部变量的值
    p + 变量名:打印该变量的值
    display +变量名:每次程序停下来都自动打印该变量的值
    来看例子:
    1. (gdb) r  
    2. Starting program: /home/lwn/mysrc/temp2/test  
    3.   
    4. Breakpoint 1, main (argc=1, argv=0x7fffffffe5c8) at gdbtest.c:36  
    5. 36          long result = 0;  
    6. Missing separate debuginfos, use: debuginfo-install glibc-2.17-106.el7_2.8.x86_64  
    7. (gdb) p result //打印result变量的值  
    8. $1 = 140737488348608 //因为第36行语句还没执行,所以现在result还未被初始化,现在是一个垃圾值  
    9. (gdb) i lo //打印所有局部变量的值  
    10. i = 0  
    11. result = 140737488348608  
    12. sum = 0  
    13. (gdb) disp result //每次遇到程序停下来都将显示变量result的值  
    14. 1: result = 140737488348608  
    15. (gdb) c  
    16. Continuing.  
    17.   
    18. Breakpoint 2, main (argc=1, argv=0x7fffffffe5c8) at gdbtest.c:38  
    19. 38          sum  = func(10);  
    20. 1: result = 0 //result被初始化为0  
    21. (gdb) c  
    22. Continuing.  
    23.   
    24. Breakpoint 3, main (argc=1, argv=0x7fffffffe5c8) at gdbtest.c:44  
    25. 44          printf(”the result is add 1 to 100 is %d\n”,result);  
    26. 1: result = 4950 //result为最终的计算值  
    (gdb) r
    Starting program: /home/lwn/mysrc/temp2/test
    
    Breakpoint 1, main (argc=1, argv=0x7fffffffe5c8) at gdbtest.c:36
    36          long result = 0;
    Missing separate debuginfos, use: debuginfo-install glibc-2.17-106.el7_2.8.x86_64
    (gdb) p result //打印result变量的值
    $1 = 140737488348608 //因为第36行语句还没执行,所以现在result还未被初始化,现在是一个垃圾值
    (gdb) i lo //打印所有局部变量的值
    i = 0
    result = 140737488348608
    sum = 0
    (gdb) disp result //每次遇到程序停下来都将显示变量result的值
    1: result = 140737488348608
    (gdb) c
    Continuing.
    
    Breakpoint 2, main (argc=1, argv=0x7fffffffe5c8) at gdbtest.c:38
    38          sum  = func(10);
    1: result = 0 //result被初始化为0
    (gdb) c
    Continuing.
    
    Breakpoint 3, main (argc=1, argv=0x7fffffffe5c8) at gdbtest.c:44
    44          printf("the result is add 1 to 100 is %d\n",result);
    1: result = 4950 //result为最终的计算值
    

    5.条件控制断点

    在for循环中,有时候我们想让循环变量i为某个固定值的时候停下来查看某一变量,如果一直单步运行工作量有可能会很大。gdb提供了一个命令cond命令
    话不多说,来看例子:
    1. 39  for(i=0;i<100;i++)  
    2.  40         {  
    3.  41             result += i;  
    4.  42         }  
    39  for(i=0;i<100;i++)
     40         {
     41             result += i;
     42         }
    
    在这个循环中,当i=10的时候我想看看result的值怎么办呢?很好办,往下看
    首先在41行设置断点,然后使用cond 2 i==10
    1. (gdb) b 41 //在41行设置断点  
    2. Breakpoint 1 at 0x400592: file gdbtest.c, line 41.  
    3. (gdb) cond 1 i==10 //当i等于10的时候程序停下来  
    4. (gdb) r  
    5. Starting program: /home/lwn/mysrc/temp2/test  
    6.   
    7. Breakpoint 1, main (argc=1, argv=0x7fffffffe5c8) at gdbtest.c:41  
    8. 41              result += i;  
    9. (gdb) p i  
    10. 1&nbsp;=&nbsp;10&nbsp;&nbsp;</span></li><li class="alt"><span>(gdb)&nbsp;p&nbsp;result<span class="comment">//可以看到当i=10的时候&nbsp;result&nbsp;的值为45</span><span>&nbsp;&nbsp;</span></span></li><li><span>2 = 45  
    (gdb) b 41 //在41行设置断点
    Breakpoint 1 at 0x400592: file gdbtest.c, line 41.
    (gdb) cond 1 i==10 //当i等于10的时候程序停下来
    (gdb) r
    Starting program: /home/lwn/mysrc/temp2/test
    
    Breakpoint 1, main (argc=1, argv=0x7fffffffe5c8) at gdbtest.c:41
    41              result += i;
    (gdb) p i
    $1 = 10
    (gdb) p result//可以看到当i=10的时候 result 的值为45
    $2 = 45
    

    在大多数情况下,灵活使用这些命令已经能够高效的调试程序了,如果对于这些gdb命令还有疑问的可以使用help命令获得详细的帮助信息。




评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值