clone/fork/vfork之后,父子进程有不同的return地址

After clone/fork/vfork, parent and child processes have different return addresses

我在 centos 6.6 上工作,想为 clone 添加一个 post-clone 挂钩。我已经将 syscall_table[__NR_clone] 更改为我的函数,我将堆栈上的 return 地址更改为我的 post-clone 函数,然后让它跳转到实际的 clone 系统调用所以在实际的系统调用之后,程序将 return 返回到我的 post-clone 函数。由于我在实际 clone 发生之前更改了堆栈上的 return 地址,因此父进程和子进程都应该具有相同的 return 地址。但是,只有父进程 return 回到我的 post-clone,而子进程 return 回到实际的 return 地址。希望有人能帮我弄清楚为什么它会这样。

终于弄明白为什么clone/fork/vfork后父进程和子进程的地址return不一样了。系统调用 clone 将在 kernel/fork.c 中调用 copy_process()copy_process() 会将 current 任务结构复制到变量 p。然后p传给copy_thread(),其中p的指令指针(ip)由ret_from_fork赋值,是entry.S中的汇编函数(或entry_32.Sentry_64.S)。 64 位版本略有不同,但思路相同。

子进程ip改为ret_from_fork,父进程ip不变。因此,系统调用clone/fork/vfork后,父子进程的地址return不同