一 单步执行和跟踪函数调用

先给出一段代码,可以用下面介绍的例子。
#include <stdio.h>
int add_range(int low, int high)
{
int i, sum;
for (i = low; i <= high; i++)
sum = sum + i;
return sum;
} int main(void)
{
int result[];
result[] = add_range(, );
result[] = add_range(, );
printf("result[0]=%d\nresult[1]=%d\n", result[],
result[]);
return ;
}
1.  在编译时要加上-g选项,生成的可执行文件才能用gdb进行源码级调试。
    $ gcc -g main.c -o main
    $ gdb main
 
    当然在加-tui 在格式上会比较直观好看一些
    $ gcc -g main.c -o main
    $ gdb -tui main
 
  gdb加-g编译时并不是把整个源文件嵌入到可执行文件中,所以在调试时必须保证gdb能找到源文件。
2. 帮助命令
    (gdb) help
    
    进一步查看某一类别中有哪些命令,例如查看files类别下有哪些命令可用:
    (gdb) help files
    
3.  list命令
    (gdb) list
   
     一次只列10行。
     gdb的很多常用命令有简写形式,例如list命令可以写成l,要列一个函数的源代码也可以用函数名做参数:
    (gdb) l add_range
    
4. 退出gdb的环境
    (gdb) quit 或 q
 
5. start命令开始执行程序
    (gdb) start    
    Breakpoint 1 at 0x80483ad: file main.c, line 14.
    Starting program: /home/akaedu/main 
    main () at main.c:14
    14 result[0] = add_range(1, 10);
    (gdb)
 
6. next命令(简写为n)控制这些语句一条一条地执行。
    (gdb) n
    15 result[1] = add_range(1, 100);
    (gdb) (直接回车)    
    16 printf("result[0]=%d\nresult[1]=%d\n", result[0], 
    result[1]);
    (gdb) (直接回车)
    result[0]=55
    result[1]=5105
    17 return 0;
 
7. 用step命令(简写为s) 进入某一个模块。钻进add_range函数中去跟踪执行
    (gdb) s    
    add_range (low=1, high=10) at main.c:6
    6 for (i = low; i <= high; i++)
 
8. backtrace命令(简写为bt)可以查看函数调用的栈帧
    (gdb) bt    
    #0 add_range (low=1, high=10) at main.c:6
    #1 0x080483c1 in main () at main.c:14
 
9. info命令(简写为i)查看add_range函数局部变量的值:
    (gdb) i locals
    i = 0
    sum = 0
    
10. frame命令(简写为f)选择1号栈帧然后再查看局部变量:
    (gdb) f 1
    #1 0x080483c1 in main () at main.c:14
    14 result[0] = add_range(1, 10);
    (gdb) i locals 
    result = {0, 0, 0, 0, 0, 0, 134513196, 225011984, -1208685768, -1081160480, 
    ...
    -1208623680}
 
11. 用print命令(简写为p)打印出变量sum的值:
    gdb) (直接回车)
    6 for (i = low; i <= high; i++)
    (gdb) p sum
    $1 = 3
 
12. finish命令让程序一直运行到从当前函数返回为止:
    (gdb) finish
    Run till exit from #0 add_range (low=1, high=10) at main.c:6
    0x080483c1 in main () at main.c:14
    14 result[0] = add_range(1, 10);
    Value returned is $2 = 55
 
 
二  断点
实际运用中用的比较最多,可能就是断点了。在程序某一个地方设置一个断点,当程序运行到这人一行时,就会在此停止,此时你可以查看一些变量的情况 。
例子源码:
#include <stdio.h>
int main(void)
{
int sum = , i = ;
char input[];
while ()
{
scanf("%s", input);
for (i = ; input[i] != '\0'; i++)
sum = sum* + input[i] - '';
printf("input=%d\n", sum);
}
return ;
}
1. display命令使得每次停下来的时候都显示当前sum的值,然后继续往下走。
2. undisplay命令可以取消跟踪显示,变量sum的编号是1,可以用undisplay 1命令取消它的跟踪显示
    (gdb) display sum
    1: sum = -1208103488
    (gdb) n
    9 scanf("%s", input);
    1: sum = 0
    (gdb) 
    123
    10 for (i = 0; input[i] != '\0'; i++)
    1: sum = 0
 
2. break命令的参数也可以是函数名,表示在某个函数开头设断点。现在用continue命令(简写为c)连续运行而非单步运行,程序到达断点会自动停下来,这样就可以停在下一次循环的开头。
    (gdb) l
    5 int sum = 0, i;
    6 char input[5];
    7 
    8 while (1) {
    9 scanf("%s", input);
    10 for (i = 0; input[i] != '\0'; i++)
    11 sum = sum*10 + input[i] - '0';
    12 printf("input=%d\n", sum);
    13 }
    14 return 0;
    (gdb) b 9
    Breakpoint 2 at 0x80483bc: file main.c, line 9.
    (gdb) c
    Continuing.
    input=123
    Breakpoint 2, main () at main.c:9
    9 scanf("%s", input);
    1: sum = 123
 
3. 用info命令可以查看已经设置的断点
    Breakpoint 3 at 0x8048411: file main.c, line 12.
    (gdb) i breakpoints
    Num Type Disp Enb Address What
    2 breakpoint keep y 0x080483c3 in main at main.c:9
    breakpoint already hit 1 time
    3 breakpoint keep y 0x08048411 in main at main.c:12
  
4. 每个断点都有一个编号,可以用编号指定删除某个断点:  
    (gdb) delete breakpoints 2
    (gdb) i breakpoints 
    Num Type Disp Enb Address What
    3 breakpoint keep y 0x08048411 in main at main.c:12
 
5. 有时候一个断点暂时不用可以禁用掉而不必删除,这样以后想用的时候可以直接启用,而不必重新
   从代码里找应该在哪一行设断点:
    (gdb) disable breakpoints 3
    (gdb) i breakpoints     
    Num Type Disp Enb Address What
    3 breakpoint keep n 0x08048411 in main at main.c:12
    (gdb) enable 3
    (gdb) i breakpoints     
    Num Type Disp Enb Address What
    3 breakpoint keep y 0x08048411 in main at main.c:12
    (gdb) delete breakpoints     
    Delete all breakpoints? (y or n) y
    (gdb) i breakpoints    
    No breakpoints or watchpoints.
 
6. gdb的断点功能非常灵活,还可以设置断点在满足某个条件时才激活。
  条件断点是语法是:break  [where] if [condition],
  这种断点真是非常管用尤其是在一个循环或递归中,或是要监视某个变量。
  注意,这个设置是在gdb中的,只不过每经过那个断点时gdb会帮你检查一下条件是否满足。
  例如我们仍然在循环开头设置断点,但是仅当sum不等于0时才中断,然后用run命令(简写为r)重新从程序开头连续运行:
    (gdb) break 9 if sum != 0    
    Breakpoint 5 at 0x80483c3: file main.c, line 9.
    (gdb) i breakpoints 
    Num Type Disp Enb Address What
    5 breakpoint keep y 0x080483c3 in main at main.c:9
    stop only if sum != 0
    (gdb) r
    The program being debugged has been started already.
    Start it from the beginning? (y or n) y
    Starting program: /home/akaedu/main 
    123
    input=123
    Breakpoint 5, main () at main.c:9
    9 
 
 三 观察点
(gdb) watch input[5]
Hardware watchpoint 2: input[5]
(gdb) i watchpoints 
Num Type Disp Enb Address What
2 hw watchpoint keep y input[5]
 
 四 段错误
如果程序运行时出现段错误,用gdb可以很容易定位到究竟是哪一行引发的段错误,例如这个小程
序:
 
#include <stdio.h>
int main(void)
{
int man = ;
scanf("%d", man);
return ;
}
调试过程如下:
$ gdb main
...
(gdb) r
Starting program: /home/akaedu/main 
123
Program received signal SIGSEGV, Segmentation fault.
0xb7e1404b in _IO_vfscanf () from /lib/tls/i686/cmov/libc.so.6
(gdb) bt
#0 0xb7e1404b in _IO_vfscanf () from /lib/tls/i686/cmov/libc.so.6
#1 0xb7e1dd2b in scanf () from /lib/tls/i686/cmov/libc.so.6
#2 0x0804839f in main () at main.c:6
 
# 五 调试宏
在gdb下,我们无法print宏定义,因为宏是预编译的.所以要在gcc编译程序的时候,加上-ggdb3参数 就可以了。
另外,你可以使用下述的gdb的宏调试命令 来查看相关的宏。
info macro – 你可以查看这个宏在哪些文件里被引用了,以及宏定义是什么样的。
macro – 你可以查看宏展开的样子。
 
 
 
 

gdb 基本知识的更多相关文章

  1. GDB基础知识

    GDB 基础知识 GDB 基础知识 一.简介 支持命令补全功能 GDB 的调用与退出 二.GDB 的基本指令 1. run/r 2. break/b 3. info breakpoints 4. de ...

  2. gdb 预备知识

    1.gcc的-g选项 如果要使用gdb进行调试,必须在编译时在gcc中加入-g选项,使用参数 -g 表示将源代码调试信息编译到可执行文件中. #include <stdio.h> int ...

  3. gdb调试知识

    之前一直不怎么用gdb,现在要用做一下记录 用gdb启动程序 gdb ./demo intel风格反汇编main函数,一共两行第一行设置汇编风格,第二行才是反汇编main函数 set disassem ...

  4. 基于TQ2440和Qemu的GDB+串口调试(1)

    作者 彭东林 pengdonglin137@163.com   平台 TQ2440 + Linux-4.10.17 Qemu(vexpress-ca9) + Linux-4.10.17   概述 下面 ...

  5. Linux 基础入门 第二周9.21~9.27

    一.学习内容 本周主要学习内容主要贴合: 在进行<深入理解计算机系统>这门课的实验中没有遇到什么大问题,学习内容与上周实验<linux基础入门>有相似之处.本实验中的内容比较贴 ...

  6. Linux知识(5)----LINUX下GDB调试

    命令 解释 示例   file 加载被调试的可执行程序文件.因为一般都在被调试程序所在目录下执行GDB,因而文本名不需要带路径. (gdb) file gdb-sample     r c Run的简 ...

  7. linux中的调试知识---基础gdb和strace查看系统调用信息,top性能分析,ps进程查看,内存分析工具

    1 调试一般分为两种,可以通过在程序中插入打印语句.有点能够显示程序的动态过程,比较容易的检查出源程序中的有关信息.缺点就是效率比较低了,而且需要输入大量无关的数据. 2 借助相关的调试工具. 3 有 ...

  8. GDB配置与.gdbinit的编写

    GDB配置与.gdbinit的编写 当 GDB(即 GNU Project Debugger)启动时,它在当前用户的主目录中寻找一个名为 .gdbinit 的文件:如果该文件存在,则 GDB 就执行该 ...

  9. GDB深入研究——20135308芦畅

    GDB深入研究 一.GDB代码调试 (一)GDB调试实例 在终端中编译一个示例C语言小程序,保存到文件 gdb-sample.c 中,用GCC编译之 #include <stdio.h> ...

随机推荐

  1. ActiveMQ的集群方案对比及部署

    转载:http://blog.csdn.net/lifetragedy/article/details/51869032 ActiveMQ的集群 内嵌代理所引发的问题: 消息过载 管理混乱 如何解决这 ...

  2. 推荐几款jquery图片切换插件

    一.前言 毕业季到了,大家都在匆匆忙忙的记录大学里最美好的时光,照片中各种花式.各种姿势都涌现出来了.这么多的照片怎么展示出来给自己的好友看呢?有人选择做成视频,有人选择ps之后做成图片集,而我选择利 ...

  3. ASP.NET Core管道深度剖析(3):管道是如何处理HTTP请求的?

    我们知道ASP.NET Core请求处理管道由一个服务器和一组有序的中间件组成,所以从总体设计来讲是非常简单的,但是就具体的实现来说,由于其中涉及很多对象的交互,我想很少人能够地把它弄清楚.为了让读者 ...

  4. CRL2.3(ORM开发框架)源码github发布

    简介 CRL是一个面向对象的轻便型ORM业务框架 此框架追求的是使用简单,方便,因此设计为: 不需要代码生成器生成对象类,按标准方式写即可 依托lambda,实现语法解析转换为等效的SQL查询,完全以 ...

  5. xDebug + webgrind 对 php 程序进行性能分析

    环境 macOs Sierra php 7.0.8 MAMP Pro 集成环境 背景 最近有一个需要在微信朋友圈上线的 h5,本人做了一个抽奖的接口,也没多想,直接上 php ci(CodeIgnit ...

  6. C#基础-MD5验证

    一.前言 MD5验证主要用于更新文件功能方面,服务器告知客户端要下载哪些更新文件并提供给客户端其MD5值,客户端从服务器将更新文件下载到本地并计算下载文件的MD5值,将本地接收的MD5值与服务器提供的 ...

  7. 使用图片视频展示插件blueimp Gallery改造网站的视频图片展示

    在很多情况下,我们网站可能会展示我们的产品图片.以及教程视频等内容,结合一个比较好的图片.视频展示插件,能够使得我们的站点更加方便使用,也更加酷炫,在Github上有很多相关的处理插件可以找来使用,有 ...

  8. [C1] 优化 C1FlexGrid 单元格边框

    一  优化理由 如下图所示,如果按照 C1FlexGrid 自带的单元格边框设置,即对每个单元格的 CellStyle 的 BorderThickness 进行设置,会得到如下图的效果: 其中,明显可 ...

  9. WPF绑定到集合

    什么是集合视图? 集合视图是位于绑定源集合顶部的一层,您可以通过它使用排序.筛选和分组查询来导航和显示源集合,而无需更改基础源集合本身.集合视图还维护着一个指向集合中的当前项的指针.如果源集合实现了 ...

  10. ASP.NET用QQ,网易发送邮件以及添加附件

    教程:ASP.NET用QQ,网易发送邮件以及添加附件 这是我用QQ邮箱出现的异常: 命令顺序不正确. 服务器响应为:Error: need EHLO and AUTH first !无法从传输连接中读 ...