美文网首页开发环境搭建C/C++
gdb调试C/C++程序的方法

gdb调试C/C++程序的方法

作者: XDgbh | 来源:发表于2018-07-04 23:25 被阅读51次

    一般来说GDB主要调试的是C/C++的程序。要调试C/C++的程序,首先在编译时,我们必须要把调试信息加到可执行文件中。使用编译器(cc/gcc/g++)的 -g 参数可以做到这一点。如:

    #gcc -g hello.c -o hello 
    #g++ -g hello.cpp -o hello 
    

    如果没有-g,你将看不见程序的函数名、变量名,所代替的全是运行时的内存地址。当你用-g把调试信息加入之后,并成功编译目标代码以后,让我们来看看如何用gdb来调试他。

    启动GDB的方法有以下几种:

    1、#gdb program
    program也就是你的执行文件,如上面的hello,一般在当然目录下。
    2、#gdb core
    用gdb同时调试一个运行程序和core文件,core是程序非法执行后core dump后产生的文件。

    (在命令行运行这些命令后,启动gdb后,就你被带入gdb的调试环境中,就可以使用gdb的命令开始调试程序了)

    详情举例见:https://blog.csdn.net/dadalan/article/details/3758025

    一个调试示例

    ——————

    源程序:tst.c

    1 #include 
    2 
    3 int func(int n) 
    4 { 
    5   int sum=0,i; 
    6   for(i=0; i<7; i++) {
    8     sum+=i; 
    9   } 
    10 return sum; 
    11 } 
    12 
    13 
    14 int main() 
    15 { 
    16   int i; 
    17   long result = 0; 
    18   for(i=1; i<=100; i++) 
    19   { 
    20     result += i; 
    21   } 
    22 
    23   printf("result[1-100] = %d /n", result ); 
    24   printf("result[1-250] = %d /n", func(250) ); 
    25 } 
    
    • 编译生成执行文件:(Linux下)
      # gcc -g tst.c -o tst
      使用GDB调试:
      # gdb tst <---------- 启动GDB
    GNU gdb 5.1.1 
    Copyright 2002 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-suse-linux"... 
    
    (gdb) l <-------------------- l命令相当于list,从第一行开始例出原码。 
    1 #include 
    2 
    3 int func(int n) 
    4 { 
    5 int sum=0,i; 
    6 for(i=0; i 7 { 
    8 sum+=i; 
    9 } 
    10 return sum; 
    (gdb) <-------------------- 直接回车表示,重复上一次命令 
    11 }
    12 
    13 
    14 int main() 
    15 { 
    16 int i; 
    17 long result = 0; 
    18 for(i=1; i<=100; i++) 
    19 { 
    20 result += i; 
    
    (gdb) break 16 <-------------------- 设置断点,在源程序第16行处。break命令也可简写成b 
    Breakpoint 1 at 0x8048496: file tst.c, line 16. 
    
    (gdb) break func <-------------------- 设置断点,在函数func()入口处。 
    Breakpoint 2 at 0x8048456: file tst.c, line 5. 
    
    (gdb) info break <-------------------- 查看断点信息。 
    Num Type Disp Enb Address What 
    1 breakpoint keep y 0x08048496 in main at tst.c:16 
    2 breakpoint keep y 0x08048456 in func at tst.c:5 
    
    (gdb) r <--------------------- 运行程序,run命令简写 
    Starting program: /home/hchen/test/tst 
    Breakpoint 1, main () at tst.c:17 <---------- 在断点处停住。 
    17 long result = 0; 
    
    (gdb) n <--------------------- 单条语句执行,next命令简写。 
    18 for(i=1; i<=100; i++) 
    
    (gdb) n 
    20 result += i; 
    
    (gdb) n 
    18 for(i=1; i<=100; i++) 
    
    (gdb) n 
    20 result += i; 
    
    (gdb) c <--------------------- 继续运行程序,continue命令简写。 
    Continuing. 
    result[1-100] = 5050 <----------程序输出。 
    Breakpoint 2, func (n=250) at tst.c:5 
    5 int sum=0,i; 
    
    (gdb) n 
    6 for(i=1; i<=n; i++) 
    
    (gdb) p i <--------------------- 打印变量i的值,print命令简写。 
    $1 = 134513808 
    
    (gdb) n 
    8 sum+=i; 
    
    (gdb) n 
    6 for(i=1; i<=n; i++)
    
    (gdb) p sum 
    $2 = 1 
    
    (gdb) n 
    8 sum+=i; 
    
    (gdb) p i 
    $3 = 2 
    
    (gdb) n 
    6 for(i=1; i<=n; i++) 
    
    (gdb) p sum 
    $4 = 3 
    
    (gdb) bt <--------------------- 查看函数堆栈。 
    #0 func (n=250) at tst.c:5 
    #1 0x080484e4 in main () at tst.c:24 
    #2 0x400409ed in __libc_start_main () from /lib/libc.so.6 
    
    (gdb) finish <--------------------- 退出函数。 
    Run till exit from #0 func (n=250) at tst.c:5 
    0x080484e4 in main () at tst.c:24 
    24 printf("result[1-250] = %d /n", func(250) ); 
    Value returned is $6 = 31375 
    
    (gdb) c <--------------------- 继续运行。 
    Continuing. 
    result[1-250] = 31375 <----------程序输出。 
    Program exited with code 027. <--------程序退出,调试结束。 
    
    (gdb) q <--------------------- quit,退出gdb。 
    hchen/test$    回到linux命令行
    

    以上示例展示了:进入gdb调试环境方式gcc -g,加断点命令break,开始执行命令run,单步执行next,继续连续执行命令continue,打印变量命令print,退出函数命令finish,退出gdb调试环境命令quit。

    命令总结

    gcc -g main.c -o main            //把调试信息加到可执行文件中
    gdb main                //进入gdb调试环境
    (gdb) start                        //开始调试
    (gdb) n                            //一条一条执行
    (gdb) step/s                        //执行下一条,如果函数进入函数
    (gdb) backtrace/bt                  //查看函数调用栈帧
    (gdb) info/i locals                //查看当前栈帧局部变量
    (gdb) frame/f                      //选择栈帧,再查看局部变量
    (gdb) print/p                      //打印变量的值
    (gdb) finish                        //运行到当前函数返回
    (gdb) set var sum=0                //修改变量值
    (gdb) list/l 行号或函数名            //列出源码
    (gdb) display/undisplay sum        //每次停下显示变量的值/取消跟踪
    (gdb) break/b  行号或函数名          //设置断点
    (gdb) continue/c                    //连续运行
    (gdb) info/i breakpoints            //查看已经设置的断点
    (gdb) delete breakpoints 2          //删除某个断点
    (gdb) disable/enable breakpoints 3  //禁用/启用某个断点
    (gdb) break 9 if sum != 0          //满足条件才激活断点
    (gdb) run/r                        //重新从程序开头连续执行
    (gdb) watch input[4]                //设置观察点
    (gdb) info/i watchpoints            //查看设置的观察点
    (gdb) x/7b input                    //打印存储器内容,b--每个字节一组,7--7组
    (gdb) disassemble                  //反汇编当前函数或指定函数
    (gdb) si                            // 一条指令一条指令调试 而 s 是一行一行代码
    (gdb) info registers                // 显示所有寄存器的当前值
    (gdb) x/20 $esp                    //查看内存中开始的20个数
    

    相关文章

      网友评论

        本文标题:gdb调试C/C++程序的方法

        本文链接:https://www.haomeiwen.com/subject/gituuftx.html