2015-05-04 57 views
0

我们如何注册函数以便在执行系统调用之前调用它。 例如,pthread_atfork()注册将在fork()之前和之后调用的函数。在系统调用之前将被调用的注册函数

下面是Linux系统上的例子。

#include <stdio.h> 
#include <pthread.h> 
#include <unistd.h> 

//http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_atfork.html 

void prepare_function() { 
    printf("%d : In Prepare Function\n", getpid()); 
} 

void parent_fuction() { 
    printf("%d : In Parent Function\n", getpid()); 
} 

void child_function() { 
    printf("%d : In Child Function\n", getpid()); 
} 

int main() { 
    pthread_atfork(prepare_function, parent_fuction, child_function); 

    if (fork() == 0) { 
     //sleep(1); 
     printf("%d : In Child\n", getpid()); 
     return 0; 
    } 

    //sleep(1); 
    printf("%d : In Parent\n", getpid()); 
    return 0; 
} 

我很好奇这是如何实现的。

回答

0

这里的实际目标是什么?

叉具有钩子,因为未定义线程的存在的孩子的状态。所以通过把自己挂钩起来,你可以确保你想要使用的任何机制保持运行(例如,如果fork在你的一个线程发生锁定之后发生,那么该锁仍然会在子进程中被使用 - 现在呢?)。

通常没有为所有系统调用提供钩子的机制。

对于大部分的系统调用所以有这实际上调用内核的几个入口点被包裹在glibc的。有人无聊可能会通过例如黑客攻击。在生成的代码中插入一个跳转,将跳转到他们的例程中。但是这样的例程必须有自己的调用系统调用或黑客的方式。

别急,任何一段代码可以自由调用,无需使用这种包装和这样的代码的系统调用可以动态生成的,所以你可以执行不是二进制补丁之前它。

你可以使用ptrace跟踪syscall的入口/出口,但是你需要一个独立的进程。