Java断点可以返回 java 断点原理_取值

这些就是调试寄存器组,Dr0 ~ Dr7。Dr0,Dr1,Dr2,Dr3是用于设置硬件断点的,由于只有4个硬件断点寄存器,所以同时最多只能设置4个硬件断点。产生的异常是STATUS_SINGLE_STEP(单步异常)。Dr4,Dr5是系统保留的。Dr7是一些控制位,用于控制断点的方式,Dr6是用于显示哪个硬件调试寄存器引发的断点,如果是Dr0 ~ Dr3的话,相应位会被置1。即如果是Dr0引发的断点,则Dr6的第0位被置1,如果是Dr1引发的断点,则Dr6的第1位被置1,依次类推。因为硬件断点同时只会触发一个,所以Dr6的低4位最多只有一位被置1,所以在进入单步后,我们可以通过检测Dr6的低4位是否有1的位,就可以判断该单步是否是因为硬件断点被断下的。如果是硬件断点被断下的,进而可以通过Dr6的哪一位为1来判断是由Dr0~Dr3中的哪个断点断下的。

调试控制寄存器Dr7比较重要,其32位结构如下:

 

Java断点可以返回 java 断点原理_Java断点可以返回_02

位0 L0和位1 G0:用于控制Dr0是全局断点还是局部断点,如果G0为1则是全局断点,如果L0为1则为局部断点。G0,L0 ~G3,L3分别用于控制Dr1~Dr3。

 

LE和GE:P6 family和之后的IA32处理器都不支持这两位。当设置时,使得处理器会检测触发数据断点的精确的指令。当其中一个被设置的时候,处理器会放慢执行速度,这样当命令执行的时候可以通知这些数据断点。建议在设置数据断点时需要设置其中一个。切换任务时LE会被清除而GE不会被清除。为了兼容性,Intel建议使用精确断点时把LE和GE都设置为1。 

 

LEN0到LEN3:指定调试地址寄存器DR0到DR3对应断点所下断的长度。如果R/Wx位为0(表示执行断点),则LENx位也必须为0(表示1字节),否则会产生不确定的行为。LEN0到LEN3其可能的取值如下:

(1)00 1字节
(2)01 2字节
(3)10 保留
(4)11 4字节

 

R/W0到R/W3:指定各个断点的触发条件。它们对应于DR0到DR3中的地址以及DR6中的4个断点条件标志。可能的取值如下:
(1) 00 只执行
(2) 01 写入数据断点
(3) 10 I/O端口断点(只用于pentium+,需设置CR4的DE位,DE是CR4的第3位 )
(4) 11 读或写数据断点

 

GD位:用于保护DRx,如果GD位为1,则对Drx的任何访问都会导致进入1号调试陷阱(int 1)。即IDT的对应入口,这样可以保证调试器在必要的时候完全控制Drx。

此时Dr0为4271B5,表示4271B5地址处被设置了硬件断点。现在我们来看看CONTEXT结构。

Java断点可以返回 java 断点原理_取值_03