zoukankan      html  css  js  c++  java
  • ubuntu下gdb代码调试

    1.什么是GDB?

    GDB全称是GNU Project Debugger,当程序执行时,让你可以进入到另一个程序的内部查看,或者当一个程序崩溃的时候它在做什么。

    GDB可以帮助你做如下四种主要的方面,来帮助你捕捉到bug:

    1.启动你的程序,指定可能影响你行为的事情(设定初始的一些变量)

    2.在特殊的条件的时候暂停你的程序执行(在端点的时候可以暂停,或者说是条件的暂停)

    3.当程序暂停的时候,可以查看这个时候发生了什么(查询堆栈,变量)

    4.通过改变程序中的参数,你可以通过实验得出某一个bug所产生的影响,然后继续执行(通过不同的设定,来得到不同的结果,本人理解为测试)

    这个调试程序,可以由Ada, C, C++, Objective-C, Pascal(或者其他语言写成)。这个程序可以执行在一个相同的机器或者是一个远程的机器上。

    2.使用GDB进行调试(快捷键ctrl+d可以退出GDB)

    1.首先当然是一言不合就安装GDB:

    1 sudo apt-get install gdb

    2.接下来本文围绕着一个c语言文件开始调试

    废话不说贴代码来看

    #include<stdio.h>
    int add(int a,int b)
    {
            return a+b;
    }
    int main()
    {
            int i =0;
            int c =0;
            while(i<100)
            {
                    c=add (i,c);
                    printf("c %d",c);
                    i++;
            }
    
            return c;
    }
    

      

    $ gcc -g gdbtest.c -o mytest

    生mytest文件,接下来进行调试

    $ gdb mytest
    

    在main处传入端点,运行到main,调试,其中breakpoint是break的全程,run是r的全程

    (gdb) break main
    (gdb) r
    

    运行到main处暂停

    之后可以单步跟一下,s(step)

    (gdb)s
    

      单步了之后可以查看剩下的代码 l(list)

    (gdb) l
    4               return a+b;
    5       }
    6       int main()
    7       {
    8               int i =0;
    9               int c =0;
    10              while(i<100)
    11              {
    12                      c=add (i,c);
    13                      printf("c %d",c);
    

    之后单步进入到函数中,可以查看堆栈

    (gdb) bt
    #0 add (a=0, b=0) at gdbtest.c:4
    #1 0x0000000000400568 in main () at gdbtest.c:12

    可以通过print来打印变量的值

    (gdb) print c
    $1 = 1

    保存断点(文件名为fig.dp)

    (gdb)save breakpoint fig.dp
    

     

    3.更近一步

       断点可以通过函数名,文件内的行号来设置,也可以先指定文件名再指定行号,还可以指定与暂停位置的偏移量,或者用地址来设置。

         (gdb) break 函数名

         (gdb) break 行号

         (gdb) break 文件名:行号

         (gdb) break 文件名:函数名

         (gdb) break +偏移量

         (gdb) break -偏移量

         (gdb) break *地址

    如果不指定位置,则在当前行的下一行下断点

    (gdb) break 11  //在十一行下端点
    Breakpoint 2 at 0x400559: file gdbtest.c, line 11. //端点2的信息
    (gdb) s    //单步
    10              while(i<100)  //执行的语句
    (gdb) c    //continue,直接进行运行,到达断点停下
    Continuing.    
    
    Breakpoint 2, main () at gdbtest.c:12
    12                      c=add (i,c);
    (gdb) break +2  //在当前运行处下两行下断点
    Breakpoint 3 at 0x40057f: file gdbtest.c, line 14.
    (gdb) break -1  //在当前行的前一行进行下断点
    Note: breakpoint 2 also set at pc 0x400559.
    Breakpoint 4 at 0x400559: file gdbtest.c, line 11.
    (gdb) break *2   //在地址为0x2处下断
    Breakpoint 5 at 0x2
    

      接下来介绍一些条件断点

     条件断点
    (gdb) break 断点 if 条件
    (gdb) break 14 if c>4  //当变量c大于4的时候,才在14行处断点停止仅在特定条件下中断。对于已存在的断点,可使用condition为其添加条件。
    (gdb) break 断点编号 条件  
    而删除指定编号断点的触发条件同样使用condition。
    (gdb) condition 断点编号
    (gdb) condition 2
    Breakpoint 2 now unconditional 
    查询断点
    (gdb) info break

    监视点

         要想找到变量在何处被改变,可以使用 watch 命令(监视点, watchpoint)。

         (gdb) watch <表达式>

         <表达式>发生变化时暂停运行。<表达式>的意思是常量或变量等。

         (gdb) awatch <表达式>

         <表达式>被访问、改变时暂停运行。

         (gdb) rwatch <表达式>

         <表达式>被访问时暂停运行。

    (gdb) watch i >10
    Hardware watchpoint 4: i >10
    (gdb) c
    Continuing.
    Hardware watchpoint 4: i >10
    
    Old value = 0
    New value = 1
    main () at gdbtest.c:10
    10              while(i<100)
    (gdb) print i
    $1 = 11
    

      

     1 (gdb) awatch  i
     2 Hardware access (read/write) watchpoint 5: i
     3 (gdb) c
     4 Continuing.
     5 Hardware access (read/write) watchpoint 5: i
     6 
     7 Old value = 11
     8 New value = 12
     9 main () at gdbtest.c:10
    10 10              while(i<100)

         删除断点和监视点

         用 delete 命令删除断点和监视点。

         (gdb) delete <编号>

      显示栈帧

          backtrace 命令可以在遇到断点而暂停执行时显示栈帧。此外,backtrace 的别名还有 where 和 info stack。

          (gdb) backtrace

          显示所有栈帧。

          (gdb) backtrace N

          只显示开头 N 个栈帧。

          (gdb) backtrace -N

          只显示最后 N 个栈帧。

          (gdb) backtrace full

          (gdb) backtrace full N

          (gdb) backtrace full -N

          不仅显示backtrace,还有显示局部变量。

          显示栈帧之后,就可以看出程序在何处停止(即断点的位置),以及程序的调用路径。

    显示寄存器

         info registers可以显示寄存器。

         (gdb) info registers

    单步执行

    单步执行指的是代码一行行的执行,有两种组成部分s和n,其中s是单步,可以进入函数,而n也是单步,但不进入函数内部。

    调试的时候读取保存的断点

    gdb hello2 -x fig.dp
    

    要记住加上参数 -x 

    然后再去查看是否有断点
     
     
    调试的时候设置参数
    1 (gdb) set args a b c
    2 (gdb) r

    四.上图总结

                                

    五.参考文章 

    http://blog.csdn.net/u011068702/article/details/53931648

    http://blog.csdn.net/hzhsan/article/details/7554328

    纸上得来终觉浅,绝知此事要躬行
  • 相关阅读:
    vue生命周期详细解析
    Chrome浏览器中onunload有时候没反应怎么办
    JavaScript中<button>与<input type="button"..的区别
    java泛型
    hashCode与equals
    HttpClient HttpServlet HttpUrlConnection
    think in java 笔记
    红黑树
    AC自动机
    并查集
  • 原文地址:https://www.cnblogs.com/asheng/p/6442656.html
Copyright © 2011-2022 走看看