GDB断点实现

GDB breakpoint implementation

我在 aarch64 上使用 gdb 时遇到问题。我不能描述很多关于平台的细节,但这不是必需的。问题是断点处理。只有断点的第一站运行良好,在没有再次插入连续断点之后,程序将 运行 没有后续断点停止。这会导致更多错误,例如内部 gdb 断点不能正常工作,动态库不能正确自动加载。

据我了解,gdb 会在感兴趣的位置插入特殊的 bp 指令(类似于 x86-64 上的 INT 3),这会在执行期间生成 SIGTRAP,由 gdb 处理(用于 bp 停止、符号加载等) .当继续执行时,gdb 必须再次插入该指令。

我在 aarch64 和 x86-64 上都遇到了这种错误(用于理解正确的行为)继续后立即:

infrun: skipping breakpoint: stepping past insn at: <bp addr>

这是因为gdb在continue之后会经过bp处(原来的指令还没有执行),会导致无限停止

但在 x86-64 上,我看到 gdb 在从 bp 之后的 下一条指令 继续后处理另一个 SIGTRAP,此时 bp 可以正确插入(因为 bp 地址是已经过去了)。但是在我的 aarch64 平台上,我只从 bp 位置得到了 1 个 SIGTRAP,仅此而已。据我了解,这导致再次不插入 bp。

我调试了 GDB(是的,先生),发现 x86-64 上的下一条指令没有 bp 插入。因此,我无法调查 aarch64 的同一个地方并了解错误的来源。

我是否正确理解 bp 实现?哪些代码影响了 "hidden" 第二代 SIGTRAP?

更新: 我发现,带有 request=PTRACE_SINGLESTEP 的 ptrace 在 aarch64 上不起作用(程序将继续运行直到终止)。还有,aarch64用的是软件单步执行,但是aarch64_software_single_step returns 0(异常完成),也许这就是来源。

我还没有发现错误。但至少我明白在这种情况下如何继续处理。对于使用 request=PTRACE_SINGLESTEP 继续命令 gdb 调用 ptrace,这将导致在劣质进程中执行 1 个命令并在之后停止。