gdb

转载 2017年01月03日 16:30:56

1、gdb调试命令

  描述
backtrace(或bt) 查看各级函数调用及参数
finish 连续运行到当前函数返回为止,然后停下来等待命令
frame(或f) 帧编号 选择栈帧
info(或i) locals 查看当前栈帧局部变量的值
list(或l) 列出源代码,接着上次的位置往下列,每次列10行
list 行号 列出从第几行开始的源代码
list 函数名 列出某个函数的源代码
next(或n) 执行下一行语句
print(或p) 打印表达式的值,通过表达式可以修改变量的值或者调用函数
quit(或q) 退出gdb调试环境
set var 修改变量的值
start 开始执行程序,停在main函数第一行语句前面等待命令
step(或s) 执行下一行语句,如果有函数调用则进入到函数中

比如还有几个命令如下

wath     观察一个变量

current 跳转到下个断点,或则跳转到观察点

quit  退出gdb调试


二、分析例子

代码如下:

[html] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. #include <stdio.h>  
  2.   
  3.   
  4. int add_range(int low, int high);  
  5.   
  6. int add (int a, int b);  
  7.   
  8. int add (int a, int b) {  
  9.     int result = a + b;  
  10.     return result;  
  11. }  
  12.   
  13. int add_range(int low, int high)  
  14. {  
  15.     int i = 0sum = 0;  
  16.     for (i = low; i <= high; i++)  
  17.         sum = sum + i;  
  18.     return sum;  
  19. }  
  20.   
  21. int main(void)  
  22. {  
  23.     int result[100];  
  24.     result[0] = add_range(1, 10);  
  25.     result[1] = add_range(1, 100);  
  26.     printf("result[0]=%d\nresult[1]=%d\n", result[0], result[1]);  
  27.     int a = 9b = 10;  
  28.         int result1 = a + b;  
  29.         int result2 = a * b;  
  30.         printf("result1 = %d, result2 = %d", result1, result2);  
  31.         int result3 = add(result1, result2) ;  
  32.         printf("result3=%d", result3);  
  33.         if (result3 == 10) {  
  34.            printf("result3 = %d", result3);  
  35.         } else {  
  36.            printf("result != 10");   
  37.     }  
  38.         return 0;  
  39. }  


在编译时要加上-g选项,生成的可执行文件才能用gdb进行源码级调试:

 命令如下:

[html] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. gcc -g main.c -o hello1  
  2. gdb hello1  

如下图


然后我们怎么查看源代码呢?命令如下

[html] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. list 1  



然后我们还要看下面的代码可以怎么样操作,你可以  回车 或则 输入l  之后回车(因为list 简写 l)注意很多gdb命令都可以简写成首字母,或则输入 list 2 回车也可以

我们退出gdb命令如下

[html] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. quit  

我们这里先不退出

我们先运行程序用下面命令

[html] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. start  
如下图

我们用next命令执行下一条语句,next命令简写为n,输入下民命令

[html] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. n  

我们也可是使用step命令进入函数内入跟踪,简写命令s,再输入命令n执行下一步,输入下面命令

[html] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. s  

在函数中有几种查看状态的办法,backtrace命令(简写为bt)可以查看函数调用的栈帧:

可见当前的add_range函数是被main函数调用的,main传进来的参数是low=1, high=100main函数的栈帧编号为1,add_range的栈帧编号为0。现在可以用info命令(简写为i)查看add_range函数局部变量的值:

i locals

如果想查看main函数当前局部变量的值也可以做到,先用frame命令(简写为f)选择1号栈帧然后再查看局部变量:

(gdb) f 1

输入下面命令

[html] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. i locals  

我们还可以用p打印出当前值

我们也可以修改sum的值

[html] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. set var sum = 0  

比如我们不要运行这个函数了,要运行这个函数下面的程序,我们可以用finish 

[html] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. finish   

quit     退出命令

3、总结

      我们熟悉了gdb基本的调试命令,然后下篇博客来讲gdb怎么打断点,怎么调试,怎么watch变量。


=========================     断点    ===========================

1 、安装GDB

[html] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. sudo apt-get install gdb  

2 、怎么打断点

1 、源文件的某一行设置断点

[html] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. break 行号  

2、一个特定的函数设置断点

[html] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. break 函数名  

3、设置条件断点

[html] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. break 行号 if 条件  

3、举例分析

hello2.c源文件如下

[html] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. #include<stdio.h>  
  2.   
  3. int main() {   
  4.    int a = 1b = 2c = 3;  
  5.    int i;  
  6.    printf("hello chenyu");    
  7.    for (i = 0 ; i < 100; i++) {  
  8.         ++a;  
  9.         if (i > 90) {  
  10.             ++b;  
  11.         } else {  
  12.             ++c;  
  13.         }  
  14.    }   
  15.    printf("a = %d, b = %d, c = %d", a, b, c);  
  16.    int cc = 0;  
  17.    for (cc; cc < 9; cc++) {  
  18.         printf("c %d", i);  
  19.    }  
  20.    return 0;  
  21. }  

比如我们在 ++b (第10行)这行和printf("c %d", i)(第18行)这两行打断点命名如下

1、编译

[html] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. gcc -g hello2.c  

2、gdb调试

[html] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. gdb hello2  

3、显示代码行数命令如下

[html] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. list  
3次回车

4 、然后输入下面打断点命令

[html] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. break 10  
  2.   
  3. break 18  

图片如下:


5 、 运行并且跳转到断点

1、运行

[html] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. start  

2 、跳转到断点命令(countine 简写c)

[html] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. c  

程序就到到++b 这行来,上面2个步骤也可以用这个run (简写 r)命令代码

[html] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. r  

我们这里代码会跳到这个断点里面来,我么就避免了手动循环这么多次,因为这个断点会打很多次,所以我们可以用c命令,还是会在这行,所以打断点一般不要打在循环里面,当这个代码执行完之后,我们再用c命令,就会打印18行的代码

我们也可以用watch命令来观察变量,如果变量的值发生变化,程序就会停止

[html] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. watch b  

我们看变量的值或则单个变量的值可以用下面命令

[html] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. i locals  
  2.   
  3. p c  

进入函数内部用下面命令

[html] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. s  

单步调试往下执行用下面命令

[html] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. n  

删除断点

[html] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. delete 行号  

退出gdb命令

[html] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. quit  

4、如何保存断点

有时候运行时,上次打的断点没了,怎么保存呢?

1、查看断点信息并保存

[html] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. info b  

2 、保存断点

[html] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. save breakpoint fig.dp  

断点保存在fig.dp文件里面

3、调试时候读取保存断点文件

[html] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. gdb hello2 -x fig.dp  

要记住加上参数 -x 

然后再去查看是否有断点

[html] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. info b  

可以看到是有2个断点的

5、总结

       学会了gdb打断点的基本命令,还有一些调试手段,以及断点的保存。


用gdb 查看,执行汇编代码

用gdb 查看汇编代码, 采用disasse ------------------------------------------------------------ 源代码: -----------...
  • hejinjing_tom_com
  • hejinjing_tom_com
  • 2014年05月23日 14:45
  • 22402

gdb调试学习(一) list命令的学习

linx之gdb调试学习,l(list)命令用于列出源码
  • qq_34501940
  • qq_34501940
  • 2016年07月15日 20:22
  • 4375

STM32高级开发(11)-使用GDB调试你的工程

在GNU编译器中,GDB无疑起着无足轻重的位置,常言有道:写工程3分靠写,7分靠调。GDB作为GNU编译器下的标准调试工具,在我们的项目编写即调试过程中会被平凡的使用到。而由于我们在IDE环境下娇生惯...
  • zhengyangliu123
  • zhengyangliu123
  • 2017年02月08日 23:51
  • 2243

使用gdb watch调试代码

本篇文章将使用一个简单的例子说明如何使用gdb watch调试代码。         首先来看以下一段简单的代码                           显然,第7行代码是有问题,那么...
  • ZhongyiGu
  • ZhongyiGu
  • 2015年09月25日 07:25
  • 1521

gdb attach到已经存在的进程进行在线调试------能获取当前栈的所有变量值!

不久前, 我们玩过valgrind定位程序的各类内存问题, 当时非常希望valgrind能对一个已经存在的进程进行attach在线调试, 后来看了valgrind的原理, 发现这样不可行。 只能让va...
  • stpeace
  • stpeace
  • 2017年03月26日 13:21
  • 4881

gdb调试——set

第一个用法,set args作为程序运行时参数: 测试代码 #include int main(int argc,char**argv){ printf("argv[0] is %...
  • huqinweI987
  • huqinweI987
  • 2016年02月21日 00:05
  • 1485

gdb基本使用方法及常用命令

示例代码 plain copy gdbtest.c   -----------------------   #include    #include ...
  • u013525455
  • u013525455
  • 2016年10月14日 10:23
  • 1287

GDB 调试技巧(不断更新中......)

一、break到不同类的同名函数 方法: 在函数前面加类名以及作用域运算符 eg : break A::func //break 到类A的func函数 程序如下://gdb...
  • yangbodong22011
  • yangbodong22011
  • 2017年03月29日 18:44
  • 652

搭建gdb调试环境

1. 下载源码 http://www.gnu.org/software/gdb/download/ 2. su root 切换到root用户 3. 打算安装到/usr/local/arm-gdb目录...
  • dyzhen
  • dyzhen
  • 2016年11月30日 14:42
  • 1038

10个常用GDB高级技巧,让调试更加方便快捷

1)查看宏 默认情况下,在GDB中是不能查看宏的值及定义的,但通过如下方法,则可以达到目的: 编译源代码时,加上“-g3-gdwarf-2”选项,请注意不是“-g”,必须为“-g3”,查看宏的值使用命...
  • lida2003
  • lida2003
  • 2016年04月12日 09:57
  • 2349
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:gdb
举报原因:
原因补充:

(最多只允许输入30个字)