第4章断点和单步执行

断点和单步执行是两个经常使用的调试功能,也是调试器的核心功能。本章我们将介绍IA-32 CPU是如何支持断点和单步执行功能的。前两节将分别介绍软件断点和硬件断点,第4.3节介绍用于实现单步执行功能的陷阱标志。在前三节的基础上,第 4.4节将分析一个真实的调试器程序,看它是如何实现断点和单步执行功能的。

4.1  软件断点

x86系列处理器从其第一代产品英特尔8086开始就提供了一条专门用来支持调试的指令,即INT 3。简单地说,这条指令的目的就是使CPU中断(break)到调试器,以供调试者对执行现场进行各种分析。当我们调试程序时,可以在可能有问题的地方插 入一条INT 3指令,使CPU执行到这一点时停下来。这便是软件调试中经常用到的断点(breakpoint)功能,因此INT 3指令又被称为断点指令。

4.1.1  感受INT 3

下面通过一个小实验来感受一下INT 3指令的工作原理。在Visual C++ Studio 6.0(以下简称为VC6)中创建一个简单的HelloWorld控制台程序HiInt3,然后在main()函数的开头通过嵌入式汇编插入一条INT 3指令:

int main(INT argc, char* argv[])
{
// manual breakpoint
_asm INT 3;
printf("Hello INT 3!\n");
return 0;
}

当在VC环境中执行以上程序时,会得到图4-1所示的对话框。点OK按钮后,程序便会停在INT 3指令所在的位置。由此看来,我们刚刚插入的一行(_asm INT 3)相当于在那里设置了一个断点。实际上,这也正是通过注入代码手工设置断点的方法,这种方法在调试某些特殊的程序时还非常有用。

 
图4-1  CPU遇到INT 3指令时会把执行权移交给调试器

此时打开反汇编窗口,可以看到内存地址00401028处确实是INT 3指令:

10:       _asm INT 3;
00401028   int         3

打开寄存器窗口,可以看到程序指针寄存器的值也是00401028。

EAX = CCCCCCCC EBX = 7FFDE000 ECX = 00000000 EDX = 00371588
ESI = 00000000 EDI = 0012FF80
EIP = 00401028 ESP = 0012FF34 EBP = 0012FF80 ……

根据我们在第3章中的介绍,断点异常(INT 3)属于陷阱类异常,当CPU产生异常时,其程序指针是指向导致异常的下一条指令的。但是,现在我们观察到的结果却是指向导致异常的这条指令的。这是为什 么呢?简单地说,是操作系统为了支持调试对程序指针做了调整。我们将在后面揭晓答案。

软件调试之INT 3讲解的更多相关文章

  1. 软件调试——CPU异常列表

    CPU异常主要分为三类:错误类异常,陷阱类异常和终止类异常 1 错误类异常 Fault CPU遇到该类异常后,会先将CS和EIP(当前发生错误的指令,而不是下一条指令)压栈,然后跳到异常处理函数中,执 ...

  2. windows程序员进阶系列:《软件调试》之堆 (一)

    windows程序员进阶系列:<软件调试>之堆 (一) 堆是软件在运行时动态申请内存空间的主要途径.从堆上申请来的空间需要程序员自己申请和释放,且申请和释放操作必须绝对匹配.忘记释放或者多 ...

  3. SPI 核软件调试记录

    SPI 核软件调试记录 1.首先说说int SpiFlashWaitForFlashReady(void)这一函数,基本上其它函数在执行的时候,都会事先执行一次此函数.    因为此函数的作用主要是用 ...

  4. 《软件调试的艺术》学习笔记——GDB使用技巧摘要

    <软件调试的艺术>学习笔记——GDB使用技巧摘要 <软件调试的艺术>,因为名是The Art of Debugging with GDB, DDD, and Eclipse. ...

  5. <读书笔记>软件调试之道 :从大局看调试-理想的调试环境

    声明:本文档的内容主要来源于书籍<软件调试修炼之道>作者Paul Butcher,属于读书笔记.欢迎转载! ---------------------------------------- ...

  6. <读书笔记>软件调试之道 :从大局看调试-零容忍策略

    声明:本文档的内容主要来源于书籍<软件调试修炼之道>作者Paul Butcher,属于读书笔记.欢迎转载! ---------------------------------------- ...

  7. <读书笔记>软件调试之道 :从大局看调试-发现代码存在问题

    声明:本文档的内容主要来源于书籍<软件调试修炼之道>作者Paul Butcher,属于读书笔记.欢迎转载! ---------------------------------------- ...

  8. <读书笔记>软件调试之道 :问题的核心-修复后的反思

    声明:本文档的内容主要来源于书籍<软件调试修炼之道>作者Paul Butcher,属于读书笔记.欢迎转载! ---------------------------------------- ...

  9. <读书笔记>软件调试之道 :问题的核心-如何修复缺陷

    声明:本文档的内容主要来源于书籍<软件调试修炼之道>作者Paul Butcher,属于读书笔记.欢迎转载! 修复缺陷 对于一个好的修复来说,不仅仅是让软件运行正确,还需要为将来奠定基础.一 ...

随机推荐

  1. django 学习-6 定义模型--数据库的使用

    1.service mysqld start  首先数据库是可用的 2.rpm -qa |grep MySQL-python  这个包是存在的 3.vim settings 修改databases 加 ...

  2. FindControl 无法找到控件问题解决方案

    若用 string cdept =((HtmlInputText)FindControl("dept0" + i.ToString())).Value; 提示结果为空值,即无法找到 ...

  3. 怎么改svn的登陆账号

    svn 我想大家都很熟悉.用的也很多.可是上次遇到一个问题 ,就是用别人的svn下载的代码.选择了记住账号密码.结果提交的时候 还是用别人的不大好.结果就想改成自己的账号.第一次改 找了半天.今天给大 ...

  4. 第二十九篇、UICollectionView瀑布流

    1.实现思路 >第一种方案:UIScrollView 镶嵌三个UITableView (不推荐使用) >第二种方案:UIScrollView 镶嵌UIImageView (需要解决循环利用 ...

  5. <Error>: CGContextRestoreGState: invalid context 0x0. If you want to see the backtrace, please set CG_CONTEXT_SHOW_BACKTRACE environmental variable.

    转自这里   出 错原因:设置app的状态栏样式的使用使用了旧的方式,在info.plist里面设置了View controller- based status bar appearance为NO,默 ...

  6. 找不到System.Runtime.Serialization.Json的解决方案

    System.ServiceModel System.ServiceModel.Web System.Runtime.Serialization 三者均要添加引用

  7. js及jQuery实现checkbox的全选、反选和全不选

    html代码: <label><input type="checkbox" id="all"/>全选</label> < ...

  8. Php 数据类型

    数据类型 JS中二大类 基本数据类型 number string boolean undefined null 复合数据类型 array object function php数据类型分为三大类 标量 ...

  9. spring读取加密配置信息

    描述&背景Spring框架配置数据库等连接等属性时,都是交由 PopertyPlaceholderConfigurer进行读取.properties文件的,但如果项目不允许在配置文件中明文保存 ...

  10. [java学习笔记]java语言基础概述之内存的划分&堆和栈

    1.内存的划分 1.寄存器 cpu处理 2.本地方法区 和所在系统相关 3.方法区 方法加载进内存,其实就是开辟了一块该方法的方法区 方法区中还可以有静态区,用于存放静态变量(类变量) 4.栈内存 5 ...