加入你正在使用GDB7.0以上版本的调试器并且运行在支持反向调试的平台,你就可以用以下几条命令来调试程序:

reverse-continue

反向运行程序知道遇到一个能使程序中断的事件(比如断点,观察点,异常)。

reverse-step

反向运行程序到上一次被执行的源代码行。

reverse-stepi

反向运行程序到上一条机器指令

reverse-next

反向运行到上一次被执行的源代码行,但是不进入函数。

reverse-nexti

反向运行到上一条机器指令,除非这条指令用来返回一个函数调用、整个函数将会被反向执行。

reverse-finish

反向运行程序回到调用当前函数的地方。

set exec-direction [forward | reverse]

设置程序运行方向,可以用平常的命令step和continue等来执行反向的调试命令。

上面的反向运行也可以理解为撤销后面运行的语句所产生的效果,回到以前的状态。

好的,接下来我们来试试看如何反向调试。

首先确认自己的平台支持进程记录回放(Process Record and Replay),当在调试器启用进程记录回放功能时,调试器会记录下子进程,也就是被调试进程的每一步的运行状态与上一步运行状态的差异,需要撤销的时候就可以很方便回到上一步。

假设我们有以下C程序:

  1. int main(int argc, const char *argv[])
  2. {
  3. int a = 0;
  4. a = 1;
  5. a = 2;
  6. return 0;
  7. }

将它编译并加上调试符号:

  1. $ gcc -Wall -g a.c

开始调试:

  1. $ gdb a.out

查看一下源代码:

  1. (gdb) l
  2. 1   int main(int argc, const char *argv[])
  3. 2   {
  4. 3     int a = 0;
  5. 4     a = 1;
  6. 5     a = 2;
  7. 6     return 0;
  8. 7   }

接下来设置一个断点在第三行:

  1. (gdb) b 3
  2. Breakpoint 1 at 0x804839a: file a.c, line 3.

运行,程序会在第三行的地方停下来:

  1. (gdb) r
  2. Starting program: /home/cheryl/a.out
  3. Breakpoint 1, main (argc=1, argv=0xbffff3e4) at a.c:3
  4. 3     int a = 0;

给变量a设置监视点方便我们观察:

  1. (gdb) watch a
  2. Hardware watchpoint 2: a

启动进程记录回放:

  1. (gdb) record

现在每运行一步调试器都会记录下变化,以便回溯。我们连续执行3条语句。

  1. (gdb) n
  2. 4     a = 1;
  3. (gdb)
  4. Hardware watchpoint 2: a
  5. Old value = 0
  6. New value = 1
  7. main (argc=1, argv=0xbffff3e4) at a.c:5
  8. 5     a = 2;
  9. (gdb)
  10. Hardware watchpoint 2: a
  11. Old value = 1
  12. New value = 2
  13. main (argc=1, argv=0xbffff3e4) at a.c:6
  14. 6     return 0;

可以看到,a的值先是从0变为了1,然后变为2,如果想让程序倒退回到以前的状态怎么办?可以用reverse-next命令:

  1. (gdb) reverse-next
  2. Hardware watchpoint 2: a
  3. Old value = 2
  4. New value = 1
  5. main (argc=1, argv=0xbffff3e4) at a.c:5
  6. 5     a = 2;
  7. (gdb)
  8. Hardware watchpoint 2: a
  9. Old value = 1
  10. New value = 0
  11. main (argc=1, argv=0xbffff3e4) at a.c:4
  12. 4     a = 1;
  13. (gdb)
  14. No more reverse-execution history.
  15. main (argc=1, argv=0xbffff3e4) at a.c:3
  16. 3     int a = 0;
  17. (gdb)

这样程序就倒退到了我们启动进程记录回放的地方,a的值经过两步回到了最初的状态。

若需要关闭进程记录回放,可以使用record stop:

  1. (gdb) record stop
  2. Process record is stoped and all execution log is deleted.

参考:《Reverse Debugging with GDB》 --- http://sourceware.org/gdb/wiki/ReverseDebug

gdb调试4--回退的更多相关文章

  1. gdb 调试入门,大牛写的高质量指南

    引用自:http://blog.jobbole.com/107759/ gdb 调试 ncurses 全过程: 发现网上的“gdb 示例”只有命令而没有对应的输出,我有点不满意.gdb 是 GNU 调 ...

  2. gdb 调试 ncurses 全过程:

    转载地址: http://blog.jobbole.com/107759/ gdb 调试 ncurses 全过程: 发现网上的“gdb 示例”只有命令而没有对应的输出,我有点不满意.gdb 是 GNU ...

  3. GDB调试命令小结

    1.启动调试 前置条件:编译生成执行码时带上 -g,如果使用Makefile,通过给CFLAGS指定-g选项,否则调试时没有符号信息.gdb program //最常用的用gdb启动程序,开始调试的方 ...

  4. GDB调试汇编堆栈过程分析

    GDB调试汇编堆栈过程分析 分析过程 这是我的C源文件:click here 使用gcc - g example.c -o example -m32指令在64位的机器上产生32位汇编,然后使用gdb ...

  5. gdb调试器的使用

    想要使用gdb调试程序的话,首先需要gcc -g main.c -o test 然后运行gdb test对程序进行调试 l (小写的l,是list的首字母),用以列出程序 回车    是运行上一个命令 ...

  6. 20145212——GDB调试汇编堆栈过程分析

    GDB调试汇编堆栈过程分析 测试代码 #include <stdio.h> short val = 1; int vv = 2; int g(int xxx) { return xxx + ...

  7. gdb调试PHP扩展错误

    有时候,使用PHP的第三方扩展之后,可能会发生一些错误,这个时候,可能就需要更底层的方式追踪调试程序发生错误的地方和原因,熟悉linux下C编程的肯定不陌生gdb 首先,使用ulimit -c命令,查 ...

  8. gdb调试汇编堆栈过程的学习

    gdb调试汇编堆栈过程的学习 以下为C源文件 使用gcc - g code.c -o code -m32指令在64位的机器上产生32位汇编,然后使用gdb example指令进入gdb调试器: 进入之 ...

  9. gdb调试

    ·代码(实验楼中的代码,改了部分数值)命名为test.c int g(int x) { return x + 7; } int f(int x) { return g(x); } int main(v ...

  10. 20145223《信息安全系统设计基础》 GDB调试汇编堆栈过程分析

    20145223<信息安全系统设计基础> GDB调试汇编堆栈过程分析 分析的c语言源码 生成汇编代码--命令:gcc -g example.c -o example -m32 进入gdb调 ...

随机推荐

  1. partprobe命令详解

    基础命令学习目录首页 原文链接:https://www.jb51.net/LINUXjishu/389836.html linux上,在安装系统之后,可否创建分区并且在不重新启动机器的情况下系统能够识 ...

  2. ftp部署及使用

    常用软件安装及使用目录 http://www.jb51.net/article/106604.htm   ftp部署 本篇文章主要介绍了CentOS7.0下安装FTP服务的方法,小编觉得挺不错的,现在 ...

  3. Vue 入门之数据绑定

    什么是双向绑定? Vue 框架很核心的功能就是双向的数据绑定. 双向是指:HTML 标签数据 绑定到 Vue 对象,另外反方向数据也是绑定的.通俗点说就是,Vue 对象的改变会直接影响到 HTML 的 ...

  4. 【quickhybrid】JS端的项目实现

    前言 API实现阶段之JS端的实现,重点描述这个项目的JS端都有些什么内容,是如何实现的. 不同于一般混合框架的只包含JSBridge部分的前端实现,本框架的前端实现包括JSBridge部分.多平台支 ...

  5. 第31次Scrum会议(11/19)【欢迎来怼】

    一.小组信息 队名:欢迎来怼 小组成员 队长:田继平 成员:李圆圆,葛美义,王伟东,姜珊,邵朔,阚博文 小组照片 二.开会信息 时间:2017/11/19 17:05~17:34,总计29min. 地 ...

  6. 20162314 Experiment 2 - Tree

    Experiment report of Besti course:<Program Design & Data Structures> Class: 1623 Student N ...

  7. 对cnblogs.com的用户体验

    1.你是什么样的用户, 有什么样的心理, 对cnblogs 的期望值是什么? 我们是计算机专业学生,是奔向神奇的代码世界的旅人.希望在cnblogs上找到自己感兴趣的技术,并学到更多的知识,提升自己的 ...

  8. react+webpack+wepack-dev-server的环境中ant design图标离线的方法

    1.首先说说我老姜对官方提供的demo的理解, 在理解的过程也学到了不少知识. 上图(图0)展示的官网demo的目录结构,node_modules是自己用node下载的, iconfont中是自己的离 ...

  9. 调研Android的开发环境的发展演变

    在 知道要做基于移动端的项目实践时,我就选定了Android,回来的时候查了很多相关的知识,很多人都在问开发安卓软件,使用eclipse还是用 Android studio?其实,也没有一个准确的答案 ...

  10. mabatis报错 Result Maps collection already contains value for gamedataserver.dao.one.ChargeRecordMapper.BaseResultMap

    1.解决这种报错看看英文"already ",也就是已经存在,其实是因为存在了两个id相同的返回,以下可以看看,根据这种例子看看自己项目是不是这种问题