【发布时间】:2020-02-02 10:37:35
【问题描述】:
我想全面了解在运行 Linux 操作系统的典型 x86 机器上调试过程是如何发生的;假设用于调试的程序是gdb。问题#1:硬件是否促进了调试过程(或者它完全用软件实现?)。如果有,涉及到指令集中的哪些架构特性?
【问题讨论】:
我想全面了解在运行 Linux 操作系统的典型 x86 机器上调试过程是如何发生的;假设用于调试的程序是gdb。问题#1:硬件是否促进了调试过程(或者它完全用软件实现?)。如果有,涉及到指令集中的哪些架构特性?
【问题讨论】:
x86 ISA 包含用于软件断点的单字节 int3 编码。 GDB 默认使用这个(通过 ptrace)作为断点。
(Why Single Stepping Instruction on X86?)
x86 在 EFLAGS 中还有一个陷阱标志 (TF),用于单步模式。 (https://en.wikipedia.org/wiki/Trap_flag)。另见Difference between trap flag (TF) and monitor trap flag?
甚至还有用于设置硬件断点的“调试寄存器”,而无需修改要运行的机器代码。还有对观察点的硬件支持,可以在写入某个地址时中断。这使得 GDB 观察点变得高效,不需要它单步执行并手动解码指令以查看其写入位置。
https://wiki.osdev.org/CPU_Registers_x86#Debug_Registers
Implementing hardware breakpoints using x86 debug register osdev 论坛帖子可能是相关的。
其他一些 ISA 几乎没有对调试的硬件支持。例如如果没有单步标志,调试器可能必须始终解码当前指令(由程序计数器指向)以找到下一条要执行的指令,并在那里设置软件断点。
ARM Linux 曾经这样做是为了实现ptrace 单步,但该反汇编代码已从内核中删除,现在只返回-EIO。 https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=425fc47adb5bb69f76285be77a09a3341a30799e 是删除它的提交。
【讨论】: