简而言之,普通人的话:
由于进入调试状态是处理器X86
中的原子操作,ARM
因此处理器进入调试状态并退出调试状态与架构中的任何其他指令相同。参见gdb 文档解释了它是如何工作的和可以使用的。
以下是 ARM 和 X86 规范的一些亮点:
在ARM中:
SW(软件)断点是通过在单步执行或执行代码之前用特殊的“断点”指令临时替换断点位置的指令操作码来实现的。当内核执行断点指令时,将被强制进入调试状态。SW 断点只能放在 RAM 中,因为它们依赖于修改目标内存。
通过对观察点单元进行编程来设置 HW(硬件)断点,以监视内核总线是否从特定内存位置获取指令。可以在 RAM 或 ROM 中的任何位置设置硬件断点。在调试复制指令(分散加载)、修改或处理器 MMU 重新映射内存区域的代码时,应使用硬件断点。在这些情况下,软件断点是不可靠的,因为它们可能会丢失或被覆盖。
在X86中:
The way software breakpoints work is fairly simple. Speaking about x86
specifically, to set a software breakpoint, the debugger simply writes
an int 3 instruction (opcode 0xCC) over the first byte of the target
instruction. This causes an interrupt 3 to be fired whenever execution
is transferred to the address you set a breakpoint on. When this
happens, the debugger “breaks in” and swaps the 0xCC opcode byte with
the original first byte of the instruction when you set the
breakpoint, so that you can continue execution without hitting the
same breakpoint immediately. There is actually a bit more magic
involved that allows you to continue execution from a breakpoint and
not hit it immediately, but keep the breakpoint active for future use;
I’ll discuss this in a future posting.
正如您可能想象的那样,硬件断点设置有特殊的硬件支持。特别是对于 x86,这涉及到一组特殊的可能鲜为人知的寄存器,称为“Dr”寄存器(用于调试寄存器)。这些寄存器允许您设置最多四个(对于 x86,这是高度特定于平台的)地址,当读取、读/写或执行时,将导致处理器抛出一个特殊异常,导致执行停止并控制转移到调试器