GDB 反向调试

2024-09-07 11:32
文章标签 调试 gdb 反向

本文主要是介绍GDB 反向调试,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

使用调试器时最常用的功能就是step, next, continue,这几个调试命令都是“往下执行”的, 但是很多时候会有这种需求:你在调试的过程中多跳过了几步而错过中间过程,这时候不得不重头调试一遍,非常麻烦。而GDB从7.0版本开始支持反向调试功能,也就是允许你倒退着运行程序,或者说撤销程序执行的步骤从而会到以前的状态。

 

直观地来看,加入你正在使用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程序:

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

 

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

[python] view plain copy print?
  1. $ gcc -Wall -g a.c  
 

开始调试:

[python] view plain copy print?
  1. $ gdb a.out  
 

查看一下源代码:

[python] view plain copy print?
  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   }  
 

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

[python] view plain copy print?
  1. (gdb) b 3  
  2. Breakpoint 1 at 0x804839a: file a.c, line 3.  
 

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

[python] view plain copy print?
  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设置监视点方便我们观察:

[python] view plain copy print?
  1. (gdb) watch a  
  2. Hardware watchpoint 2: a  
 

启动进程记录回放:

[python] view plain copy print?
  1. (gdb) record  
 

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

[python] view plain copy print?
  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命令:

[python] view plain copy print?
  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:

 

 

[python] view plain copy print?
  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

 From: http://blog.csdn.net/CherylNatsu/article/details/6436570

附注:因多次调试感觉很浪费时间 故此寻找gdb的该项技术,幸好系统的gdb版本是支持的:)

这篇关于GDB 反向调试的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1144936

相关文章

ASIO网络调试助手之一:简介

多年前,写过几篇《Boost.Asio C++网络编程》的学习文章,一直没机会实践。最近项目中用到了Asio,于是抽空写了个网络调试助手。 开发环境: Win10 Qt5.12.6 + Asio(standalone) + spdlog 支持协议: UDP + TCP Client + TCP Server 独立的Asio(http://www.think-async.com)只包含了头文件,不依

如何在Visual Studio中调试.NET源码

今天偶然在看别人代码时,发现在他的代码里使用了Any判断List<T>是否为空。 我一般的做法是先判断是否为null,再判断Count。 看了一下Count的源码如下: 1 [__DynamicallyInvokable]2 public int Count3 {4 [__DynamicallyInvokable]5 get

计算机毕业设计 大学志愿填报系统 Java+SpringBoot+Vue 前后端分离 文档报告 代码讲解 安装调试

🍊作者:计算机编程-吉哥 🍊简介:专业从事JavaWeb程序开发,微信小程序开发,定制化项目、 源码、代码讲解、文档撰写、ppt制作。做自己喜欢的事,生活就是快乐的。 🍊心愿:点赞 👍 收藏 ⭐评论 📝 🍅 文末获取源码联系 👇🏻 精彩专栏推荐订阅 👇🏻 不然下次找不到哟~Java毕业设计项目~热门选题推荐《1000套》 目录 1.技术选型 2.开发工具 3.功能

vscode中文乱码问题,注释,终端,调试乱码一劳永逸版

忘记咋回事突然出现了乱码问题,很多方法都试了,注释乱码解决了,终端又乱码,调试窗口也乱码,最后经过本人不懈努力,终于全部解决了,现在分享给大家我的方法。 乱码的原因是各个地方用的编码格式不统一,所以把他们设成统一的utf8. 1.电脑的编码格式 开始-设置-时间和语言-语言和区域 管理语言设置-更改系统区域设置-勾选Bata版:使用utf8-确定-然后按指示重启 2.vscode

起点中文网防止网页调试的代码展示

起点中文网对爬虫非常敏感。如图,想在页面启用调试后会显示“已在调试程序中暂停”。 选择停用断点并继续运行后会造成cpu占用率升高电脑卡顿。 经简单分析网站使用了js代码用于防止调试并在强制继续运行后造成电脑卡顿,代码如下: function A(A, B) {if (null != B && "undefined" != typeof Symbol && B[Symbol.hasInstan

php 7之PhpStorm + Nginx + Xdebug运行调试

操作环境: windows PHP 7.1.10 PhpStorm-2017.2.4 Xdebug 2.5.4 Xdebug helper 1.6.1 nginx-1.12.2 注意查看端口占用情况 netstat -ano //查看所以端口netstat -aon|findstr "80" //查看指定端口占用情况 比如80端口查询情况 TCP 0.0.0.0:8

【2025】基于Python的空气质量综合分析系统的设计与实现(源码+文档+调试+答疑)

博主介绍:     ✌我是阿龙,一名专注于Java技术领域的程序员,全网拥有10W+粉丝。作为CSDN特邀作者、博客专家、新星计划导师,我在计算机毕业设计开发方面积累了丰富的经验。同时,我也是掘金、华为云、阿里云、InfoQ等平台的优质作者。通过长期分享和实战指导,我致力于帮助更多学生完成毕业项目和技术提升。 技术范围:     我熟悉的技术领域涵盖SpringBoot、Vue、SSM、HLMT

GDB调试程序入门

http://blog.csdn.net/haoel/article/details/2880 用GDB调试程序 GDB概述 ———— GDB是GNU开源组织发布的一个强大的UNIX下的程序调试工具。或许,各位比较喜欢那种图形界面方式的,像VC、BCB等IDE的调试,但如果你是在UNIX平台下做软件,你会发现GDB这个调试工具有比VC、BCB的图形化调试器更强大的功能。所谓“寸有所

VS Code 调试go程序的相关配置说明

用 VS code 调试Go程序需要在.vscode/launch.json文件中增加如下配置:  // launch.json{// Use IntelliSense to learn about possible attributes.// Hover to view descriptions of existing attributes.// For more information,