我已经读过GDB将int 3(操作码CC)放在目标程序存储器中的所需地址。
Si此操作正在擦除程序存储器中的一条指令(1个字节)。 我的问题是:当程序继续时,GDB如何以及何时替换原始操作码?
当我在GDB中键入反汇编时,我看不到CC操作码。这是因为GDB知道他放置了CC吗? 有没有办法进行原始的反汇编,以便在此刻确切地看到内存中加载了哪些操作码?
答案 0 :(得分:4)
当程序继续时,GDB如何以及何时替换原始操作码?
我用它作为面试问题; - )
在Linux上,要继续通过断点,0xCC
将替换为原始指令,并且ptrace(PTRACE_SINGLESTEP, ...)
已完成。当线程在下一条指令停止时,原始代码再次被0xCC
操作码替换(以恢复断点),并且线程继续以其快乐的方式。
在没有PTRACE_SINGLESTEP
的x86平台上,EFLAGS
通过ptrace(PTRACE_SETREGS, ...)
设置PTRACE_SINGLESTEP
,线程将继续。陷阱标志使线程立即再次停止(在下一条指令上,就像0xCC
那样)。
当我在GDB中键入反汇编时,我看不到CC操作码。这是因为GDB知道是他放置了CC吗?
正确。程序可以检查并打印自己的指令流,您可以通过这种方式观察断点(gdb) set debug infrun
操作码。
有没有办法进行原始反汇编,以便在此刻确切地看到内存中加载了哪些操作码?
我不相信有。您可以使用PTRACE_ATTACH
来观察GDB对劣质(正在调试)的过程所做的事情。
我实际上不明白的是SIGTRAP的确切作用。谁在发送/接收此信号?调试器或目标程序?
两者都没有:在wait
之后,内核停止下级,然后通过调试器的0xCC
返回来通知调试器它已经这样做了。
我在ptrace附加后看到等待(NULL)。这等待的意思是什么?
见上面的解释。
线程特定断点?
对于特定于线程的断点,调试器会插入一个进程范围的断点(通过height: auto
操作码),然后只需立即恢复任何命中断点的线程,除非该线程是您想要的特定线程停止。