重载fork()

kin*_*er1 6 c linux fork system-calls

我已经重载了fork()系统调用并fork()使用RTLD_NEXT 创建了我自己的版本.就是这样dlsym(RTLD_NEXT, fork).这将打到我的版本的fork.在此之后,我想复制实际fork()系统调用的任务,即创建子进程并返回pid,以及一些更多的附加功能.

我无法弄清楚如何做到这一点.我检查了fork()(fork.c)的内核源代码并且无法弄清楚.

这样做:

dlsym(RTLD_NEXT,fork);  
int fork(void) {
    int pid=_fork(); // Trying to call actual fork does not work
    return pid;
}
Run Code Online (Sandbox Code Playgroud)

我怎样才能做到这一点?这是fork的内核源代码的链接:http://lxr.linux.no/linux+v2.6.32/kernel/fork.c#L10

编辑(从评论中提取):

我正在研究泄漏检测工具,当子进程删除父进程分配的内存时,此工具会检测到double free.为了克服这一点,我将覆盖fork(),并且只要有a fork(),父进程的内存分配表将被复制到子进程.

Omn*_*ous 7

你不会从内核源代码中获得任何有用的东西fork.无论您管理什么库技巧,都不允许您的代码执行内核所做的事情.如果不编写内核模块,这是一个难以破解的硬边界.

所有用于forkdo 的库代码都设置完成并执行一个特殊指令,切换到内核模式,内核的fork代码执行.有一种方法可以将这个特殊指令放在您自己的代码中.这是syscall功能.由于fork不带参数,因此使用此函数进行系统调用应该相对容易.

但这不是我建议你做的.我建议你这样做:

typedef int (*forkfunc_t)(void);

int fork(void)
{
     forkfunc_t sysfork = (forkfunc_t)dlsym(RTLD_DEFAULT, "fork");
     return sysfork();
}
Run Code Online (Sandbox Code Playgroud)

基本上,无论你做什么共享库hackery,你基本上应该找到一些方法来检索fork函数的先前值,然后再用它自己替换它.


Fre*_*Foo 3

您应该能够在包含 后调用实际的forkwith 。看。syscall(SYS_fork)<sys/syscall.h>syscall(2)

  • 直接进行系统调用是一个坏主意。需要使用“fork”来调用“pthread_atfork”函数以及执行一些内部同步,以防止具有多线程父级的子级中的 stdio/malloc 状态被损坏,更新强大的互斥列表指针等... (2认同)