• gdb调试4--回退


    加入你正在使用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

  • 相关阅读:
    L2私有专用网 L3私有专用网 互通
    VPLS知识点
    Lab L2tpv3
    L2TP version 3(Layer 2 Tunnel Protocol)
    L2私有专用网 Interworking [IW] 的两种类型
    L2私有专用网 伪线缝补
    Option 2:End-to-End PW between Provider Edge Routers
    Option 1:专用电路互联伪线的 Inter-AS 实现
    ATOM实验
    100、拥塞控制原理听说过吗?101、如何区分流量控制和拥塞控制?
  • 原文地址:https://www.cnblogs.com/guxuanqing/p/5745977.html
Copyright © 2020-2023  润新知