debugging - 如何在没有无限循环的情况下在硬件断点后恢复执行?

标签 debugging gdb cpu-architecture breakpoints

据我所知,软件断点的工作方式如下:

BP 设置的指令被 int/trap 指令替代,然后陷阱在陷阱处理程序中处理,在继续时,陷阱被原始指令替换,指令以单步模式执行,现在PC 指向下一条指令,原始指令再次被 int/trap 指令替换。

根据我的理解,硬件断点的工作原理如下:

BP 设置的指令地址写入 HW-BP 寄存器。如果分别命中指令,则 PC 与 HW-BP 寄存器中的地址相匹配,CPU 将引发一个中断,该中断也由陷阱处理程序处理。现在,如果程序返回到原始指令,HW BP 仍然处于事件状态,并且会陷入无限循环。

这个问题是如何处理的?

在继续之前 HW BP 是否被禁用,原始指令是否也在单步模式下执行?或者是原来的指令在进入trap handler之前执行,让trap handler返回到原来指令之后的指令?还是有其他机制?

最佳答案

对于 Intel 64 和 IA-32(“x64/x86”)架构,这是 Resume Flag (RF) 的任务,EFLAGS 中的第 16 位。 (其他支持硬件断点的处理器架构可能有类似的机制。)

参见 Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 3B 中的第 18.3.1.1 节:

Because the debug exception for an instruction breakpoint is generated before the instruction is executed, if the instruction breakpoint is not removed by the exception handler; the processor will detect the instruction breakpoint again when the instruction is restarted and generate another debug exception. To prevent looping on an instruction breakpoint, the Intel 64 and IA-32 architectures provide the RF flag (resume flag) in the EFLAGS register (see Section 2.3, “System Flags and Fields in the EFLAGS Register,” in the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 3A). When the RF flag is set, the processor ignores instruction breakpoints.

[...]

The RF Flag is cleared at the start of the instruction after the check for code breakpoint, CS limit violation and FP exceptions.

[...]

If the RF flag in the EFLAGS image is set when the processor returns from the exception handler, it is copied into the RF flag in the EFLAGS register by IRETD/IRETQ or a task switch that causes the return. The processor then ignores instruction breakpoints for the duration of the next instruction. (Note that the POPF, POPFD, and IRET instructions do not transfer the RF image into the EFLAGS register.) Setting the RF flag does not prevent other types of debug-exception conditions (such as, I/O or data breakpoints) from being detected, nor does it prevent non-debug exceptions from being generated.

(强调我的。)

因此,调试器将在从异常处理程序返回之前设置 RF,以便指令断点对一条指令“静音”,之后处理器自动清除该标志。

请注意,在数据断点的情况下这不是问题,因为它们将在触发读/写操作的指令之后触发。


推荐:我找the slides of "Intermediate x86 Part 4" by Xeno Kovah有助于理解这些东西。他在那里谈论各种话题,但从调试开始。这些信息尤其可以在幻灯片 12-13 中找到:

slide 12 slide 13

图片来源:Xeno Kovah,CC BY-SA 3.0

关于debugging - 如何在没有无限循环的情况下在硬件断点后恢复执行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70954561/

相关文章:

java - Eclipse 调试器 : Threads vs "Daemon" Threads

debugging - 使用命令行参数在 Visual Studio 代码中调试 powershell

java - 日期选择器对话框。设置无效日期时如何重新打开它

ubuntu - 如何设置 Visual Studio Code 以在 Linux 上调试 C 程序?

c - 如何在 gdb 中使用输入文件

c - 覆盖主函数中的EIP

iphone - armv6和i386有什么区别?

java - NetBeans : Unable to attach debugger (getting Connection refused error)

assembly - 为什么x86丑?为什么比别人差?

assembly - 所有程序最终都转换为汇编指令吗?