每天学点GDB 13

时间:2023-03-08 16:07:39
每天学点GDB 13

ptrace是gdb实现的基石,本文简要介绍一下ptrace.

ptrace

linux提供的系统调用ptrace,使得一个进程可以attach到另一个进程并进而完整的控制被attach上的进程。

被控制的内容包括但不局限于下述所列

  1. 文件描述符
  2. 内存
  3. 寄存器
  4. 信号

能够观察到被控制进程的单步执行指令,能够设置断点,等等。

ptrace调用接口定义如下所示

#include <sys/ptrace.h>
long int ptrace(enum __ptrace_request request, pid_t pid,
void * addr, void * data)

每个参数的具体含义就不作解释了,可以参考相应的manpage.

与接口相对应的是内核在process最重要的数据结构task_struct中定义了一个ptrace成员变量。这样通过ptrace系统调用接口与相应的进程数据结构挂起钩来。

struct task_struct {
volatile long state; /* -1 unrunnable, 0 runnable, >0 stopped */
void *stack;
atomic_t usage;
unsigned int flags; /* per process flags, defined below */
unsigned int ptrace; int lock_depth; /* BKL lock depth */

Demo

我们可以写一个小的demo程序来演示如何使用ptrace.

#include <sys/ptrace.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <sys/user.h> /* For constants
ORIG_EAX etc */
int main()
{ pid_t child;
long orig_eax;
child = fork();
if(child == ) {
ptrace(PTRACE_TRACEME, , NULL, NULL);
execl("/bin/ls", "ls", NULL);
}
else {
wait(NULL);
orig_eax = ptrace(PTRACE_PEEKUSER,
child, * ORIG_EAX,
NULL);
printf("The child made a "
"system call %ld\n", orig_eax);
ptrace(PTRACE_CONT, child, NULL, NULL);
}
return ;
}

执行结果为

The child made a system call 

参考资料

  1. playing with ptrace http://www.linuxjournal.com/article/6100?page=0,0
  2. process tracing using ptrace http://linuxgazette.net/issue81/sandeep.html
  3. gdb的基本工作原理 http://www.spongeliu.com/240.html