ptrace是process和trace的简写,直译为进程的跟踪。它是操作系统提供给应用程序调试器诸于gdb,strace的系统调用接口(API)。
具体过程为: 父进程首先进行fork调用,并在子进程中执行Ptrace函数,将PTRACE_TRACEME赋值给request形参,紧接着在子进程中执行exec调用完后。将控制权交给父进程,通过使用PTRACE_ATTACH,父进程开始跟踪子进程,每一次被跟踪的子进程都会向父进程发送一个信号。父进程可以忽略掉大部分信号,仅有的一个例外是SIGKILL信号。在跟踪子进程的过程中,父进程可以查看和修改子进程的内核映像以及寄存器的值,暂停子进程的执行。在跟踪完成后,可以选择子进程继续执行还是终止。
Ptrace函数是高度依赖底层的架构,因此,它的移植性受到一定的限制。下图
ptrace运行在内核空间,而gdb和strace运行在用户空间。由上图可知ptrace构成了应用程序调试的基础。
ptrace系统调用格式如下:
#include
long ptrace(enum __ptrace_request reqest,pid_t
pid,void* addr,void* data);
其中request决定了ptrace执行哪种任务,pid则表示被跟踪和监视的子进程。addr表示子进程用户空间地址的偏移量,data表示子进程的一些数据指针,这些数据是监视它的父进程想要查看的。
request请求一般有如下几种:
PTRACE_TRACEME
PTRACE_PEEKTEXT, PTRACE_PEEKDATA
PTRACE_PEEKUSR
PTRACE_POKETEXT, PTRACE_POKEDATA
PTRACE_POKEUSR
PTRACE_GETREGS, PTRACE_GETFPREGS
等等
在所有如上请求中,只有PTRACE_TRACEME是在子进程使用,在ptrace函数中的其他参数一般可以忽略。其余的请求一般在父进程使用。在ptrace函数中的其他参数如pid_t表示被监视的子进程进程标识号。addr是子进程的内存地址,而data表示想要获取的数据指针。