断点后GDB如何恢复指令

Bob*_*421 3 gdb

我已经读到 GDB 在目标程序内存中的所需地址处放置了一个 int 3(操作码 CC)。

Si 这个操作是擦除程序存储器中的一条指令(1 个字节)。我的问题是:当程序继续时,GDB 如何以及何时替换原始操作码?

当我在 GDB 中键入反汇编时,我看不到 CC 操作码。这是因为 GDB 知道是他放了 CC 吗?有没有办法进行原始反汇编,以便准确查看此时内存中加载了哪些操作码?

Emp*_*ian 5

当程序继续时,GDB 如何以及何时替换原始操作码?

我用这个作为面试问题;-)

在 Linux 上,要继续越过断点,0xCC将替换为原始指令,然后ptrace(PTRACE_SINGLESTEP, ...)完成。当线程在下一条指令处停止时,原始代码再次被0xCC操作码替换(以恢复断点),线程继续其愉快的方式。

在没有这样的x86平台PTRACE_SINGLESTEP陷阱标志被设置EFLAGS通过ptrace(PTRACE_SETREGS, ...)和线程继续。陷阱标志使线程立即再次停止(在下一条指令上,就像PTRACE_SINGLESTEP会那样)。

当我在 GDB 中键入反汇编时,我看不到 CC 操作码。这是因为 GDB 知道是他放了 CC 吗?

正确的。程序可以检查和打印自己的指令流,您可以通过0xCC这种方式观察断点操作码。

有没有办法进行原始反汇编,以便准确查看此时内存中加载了哪些操作码?

我不相信有。您可以使用(gdb) set debug infrun来观察 GDB 对劣等(被调试)进程做了什么。

事实上,我不明白的是 SIGTRAP 的确切作用。谁在发送/接收这个信号?调试器还是目标程序?

两者都不是:在 之后PTRACE_ATTACH内核停止下级,然后通过使调试器wait返回来通知调试器它已经这样做了。

我在 ptrace 附加后看到一个等待(NULL)。这个等待的意义是什么?

请参阅上面的解释。

线程特定的断点?

对于特定于线程的断点,调试器插入一个进程范围的断点(通过0xCC操作码),然后简单地立即恢复命中断点的任何线程,除非该线程是您想要停止的特定线程。