每天学点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 == 0) {
        ptrace(PTRACE_TRACEME, 0, NULL, NULL);
        execl("/bin/ls", "ls", NULL);
    }
    else {
        wait(NULL);
        orig_eax = ptrace(PTRACE_PEEKUSER,
                          child, 4 * ORIG_EAX,
                          NULL);
        printf("The child made a "
               "system call %ld\n", orig_eax);
        ptrace(PTRACE_CONT, child, NULL, NULL);
    }
    return 0;
}

执行结果为

The child made a system call 11

参考资料

  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

 

 

posted @ 2013-09-05 22:48  徽沪一郎  阅读(422)  评论(0编辑  收藏  举报