Linux 在当前进程中添加观察点(不在gdb中,不用于调试)
我想知道是否可以在当前进程中添加观察点,以便在读取或写入内存(取决于标志)时调用回调 有一些相关的问题,但它们都是关于使用gdb或其他调试器进行调试的。这不是为了调试,也不是为了跟踪另一个进程。我希望进程本身在自己的地址空间中的内存位置设置一个观察点。通常对于这种情况,我会使用ptrace,但据我从手册页了解(“ptrace()系统调用提供了一种方法,通过这种方法,一个进程(“跟踪器”)可以观察和控制另一个进程的执行(“tracee”),…“--我的重点)它不能用于在当前进程中添加观察点Linux 在当前进程中添加观察点(不在gdb中,不用于调试),linux,breakpoints,ptrace,watchpoint,Linux,Breakpoints,Ptrace,Watchpoint,我想知道是否可以在当前进程中添加观察点,以便在读取或写入内存(取决于标志)时调用回调 有一些相关的问题,但它们都是关于使用gdb或其他调试器进行调试的。这不是为了调试,也不是为了跟踪另一个进程。我希望进程本身在自己的地址空间中的内存位置设置一个观察点。通常对于这种情况,我会使用ptrace,但据我从手册页了解(“ptrace()系统调用提供了一种方法,通过这种方法,一个进程(“跟踪器”)可以观察和控制另一个进程的执行(“tracee”),…“--我的重点)它不能用于在当前进程中添加观察点 有没有
有没有一种不使用ptrace的方法可以做到这一点?或者我可以在当前进程中使用ptrace来执行此操作吗?监视点通常通过配置嵌入CPU本身的调试功能(即硬件监视点)来工作。 实际上,您将要监视的地址范围加载到特殊寄存器中 每个CPU架构都需要专门的代码。 以下是gdbserver在ARM CPU上设置观察点的操作: 注意,调用
update\u registers\u callback()
-gdbserver必须使用ptrace
功能来更新tracee上下文中的寄存器。如果您想让进程监视自己,它可以直接访问这些寄存器
以下是您的流程如何注意到自己的观察点被击中:
它接收SIGTRAP信号,详细信息指示观察点。
在gdbserver上下文中,必须再次通过ptrace
传递通知。在您自己的过程中,您可以直接在SIGTRAP的处理程序中检查信号信息。代码摘录(适用于ARM):
进一步阅读后发现,跟踪器通过ptrace
访问的硬件断点“寄存器”并不是真正的东西,而是在Linux内核中实现的抽象
其中涉及到一个“hw断点”框架,它从CPU细节中抽象出来。找到以下概述:
虽然这给了人们希望,实际上可以使用进程本身应用的ptrace()
syscall,以一种相当便携的方式安装硬件监视点,但这并不可行——请参见下文
您需要此ptrace()
请求代码(通常手册页中没有记录):
进一步试验后:
- 进程不能
自身(权限被拒绝)ptrace()
- 一个进程可以调用
,然后一个线程可以成功地clone()
另一个线程ptrace(ptrace\u-jack)
- 此时,您还可以使用tracer
gdb进行监视exec()
- x86和x86_64似乎都没有实现PTRACE_SETHBPREGS(从内核4.15开始)
- aarch64有,但到目前为止,我只设法提出了一些总线错误
ptrace()
作为以任何便携方式设置硬件监视点的选项
/* This must be a hardware breakpoint. */
if (siginfo.si_signo != SIGTRAP
|| (siginfo.si_code & 0xffff) != 0x0004 /* TRAP_HWBKPT */)
return 0;
/* If we are in a positive slot then we're looking at a breakpoint and not
a watchpoint. */
if (siginfo.si_errno >= 0)
return 0;
/* Cache stopped data address for use by arm_stopped_data_address. */
lwp->arch_private->stopped_data_address
= (CORE_ADDR) (uintptr_t) siginfo.si_addr;
PTRACE_SETHBPREGS