虚拟内存可以用来支持 i386 中的数据断点功能吗?

Can virtual memory be used to support Data Breakpoint feature in i386?

我在我的OS教科书中潜伏,它提到可以在数据断点(用于程序调试)上实现虚拟地址转换。我只知道调试器使用 INT 3 来暂停程序,在调试控制和地址寄存器中以某种方式处理正在处理的局部和全局变量。但经过一番挖掘,我只发现了有关调试寄存器使用中线性地址的信息。根本没有关于虚拟地址相关数据断点背后机制的文章或讨论。那么这到底是如何工作的呢?

线性地址虚拟的,在x86术语中。x86内存寻址是:

  • [ebp + eax*4]这样的寻址模式到“有效地址”(seg:off的偏移部分)。 (并且每个寻址模式都意味着一个段,如果你不手动覆盖 [fs: rdi] 例如。通常 DS,除非基址寄存器是 R/E/BP 或 R/ESP 其中case SS。或者对于作为例如 push rax or stosb 一部分的隐式寻址模式,这取决于指令。)
  • seg:off -> 通过将段基数添加到偏移量来线性。
  • 将该线性地址转换为物理地址。 (如果虚拟化,则从客户物理到真正的物理。)

所有步骤都由CPU硬件完成,首先使用段基址,然后使用CR3指向的页-table。或者缓存该页面翻译的 TLB table.

硬件断点/观察点的硬件调试寄存器使用虚拟地址。 https://en.wikipedia.org/wiki/X86_debug_register 解释如下:

The addresses in these registers are linear addresses. If paging is enabled, the linear addresses are translated into physical addresses by the processor's paging mechanism. If paging is not enabled, these linear addresses are the same as physical addresses.

这意味着当您从 不同 的虚拟地址访问相同的物理地址时,可以触发观察点,而不是您放入调试寄存器的地址。 (如果维基百科上的描述是准确的;我会测试它 and/or 如果重要的话,请查看英特尔或 AMD 的手册。)

其实我不知道细节;知道 x86 有一个 TF 标志和调试寄存器,以及它们可以做的事情的一般概念,但我从未编写代码来使用它们。


I only know that the debugger uses INT 3 to pause the program

“硬件断点”意味着 CPU 将停止 而无需 软件必须将执行代码重写为 0xCC int3。调试寄存器可以做到这一点,还可以通过 any 指令检测对某些内存位置的访问。

所以你可以设置一个观察点,当你的程序在内存中读取或写入某个全局变量时中断,让你找到通过指针或其他东西修改它的代码。由于它支持硬件,您可以 运行 全速运行,而不必单步执行并让软件检查每次访问。

另见

  • How does gdb set software breakpoints in shared library functions?

  • Why Single Stepping Instruction on X86?

  • 英特尔的手册。