C 用克隆模拟vfork

C 用克隆模拟vfork,c,clone,fork,C,Clone,Fork,是否可以用clone模拟vfrok的行为?到目前为止我有 pid=clone(fn,cStack,SIGCHLD|CLONE_FS | CLONE_FILES | CLONE_VM | CLONE_VFORK,NULL); 但是我仍然需要传递我自己的堆栈,因此新进程在不同的堆栈帧中工作,但在相同的地址空间中工作(因为CLONE_VM),正如我所理解的,如果调用vWork并且不使用exec中的某些函数,那么新进程将在与父进程相同的地址空间中工作,并且它使用相同的堆栈帧 那么,是否可以使用克隆创建

是否可以用clone模拟vfrok的行为?到目前为止我有

pid=clone(fn,cStack,SIGCHLD|CLONE_FS | CLONE_FILES | CLONE_VM | CLONE_VFORK,NULL);
但是我仍然需要传递我自己的堆栈,因此新进程在不同的堆栈帧中工作,但在相同的地址空间中工作(因为CLONE_VM),正如我所理解的,如果调用vWork并且不使用exec中的某些函数,那么新进程将在与父进程相同的地址空间中工作,并且它使用相同的堆栈帧


那么,是否可以使用克隆创建一个新进程,该克隆在相同的地址空间中运行,并且使用与父进程相同的堆栈帧

不在汇编程序中编写函数是不可能的。这是一个根本问题,不能"解决",;对于大多数arch(返回地址存储在堆栈上的任何arch),即使是
vWork
syscall包装器本身也必须用汇编而不是C编写。这是因为在子级使用与父级相同的堆栈运行后,它可能会覆盖父级中函数(
vfork
clone
或其他一些包装器)需要返回的返回地址


在汇编程序中,在进行系统调用之前,只需将返回地址保存在寄存器中。

+1用于指出堆栈的复杂性。但是为什么手册很随便地说
vfork()是克隆(2)
的特例呢??这似乎表明
vWork
可以通过
clone
实现?它可以通过
clone
系统调用轻松实现。但是当您想要共享堆栈时,不能像这样包装C函数调用。你必须在asm中编写基于
clone
vfork
版本。因此,如果我理解正确,最接近克隆函数的vfork是我在第一篇文章中编写的调用?我得到了相同的内存空间,停止父级直到子级退出,共享文件描述符表和相同的文件系统信息,但它们不像vWork中那样共享堆栈?是的,这是正确的。就我个人而言,我认为你的版本更好。我发现
fork
vfork
的“返回两次”习惯用法既难看又容易出错;在子进程中启动新函数(在新堆栈上)要干净得多。有趣的是,这种技术要求系统调用和常规函数调用约定有所不同:内核必须保留至少一个通常由调用方保存的寄存器的值。