执行exec家庭功能

时间:2013-05-10 13:55:44

标签: c linux exec systems-programming

我正在研究exec系列函数。它的man page说,它用一个新的过程映像替换当前的过程映像。如果它替换了二进制文件,那么在返回之后,它如何获取调用exec的进程的先前参数?作为替换进程图像意味着替换其所有内存部分。如果我错了或知识较少,请纠正我。

3 个答案:

答案 0 :(得分:1)

真正的工作是由execve(2)系统调用完成的。所有其他功能(如execvp ...)都在调用execve

execve是一个非常复杂的系统调用。 成功后,它不会返回。但是过程状态(包括地址空间)已经[几乎]完全重写了。

基本上,地址空间正在变得新鲜。它包含二进制可执行文件中的段。

程序参数,环境等已经被复制(在堆栈段的底部)到新的地址空间。因此它们是有限的(通过ARG_MAX,通常是128Kbytes - 但你可以通过重新编译你的内核来提高它。)

地址空间的变化实际上主要是懒惰地进行(使用copy on write);实际上,分页是无效的,随后的访问会出现页面错误,内核通过提供新页面等来提供服务......

在Linux上,我建议调查/proc/(有关详情,请参阅proc(5))。特别是,请尝试cat /proc/self/maps,它会显示运行cat的流程的地址空间地图。

当然execve通常在fork(2)之后使用,也可能在dup2(2)和/或pipe(2)之后使用,还有一些等待系统调用,如waitpid(2)或{ {3}},也许处理SIGCHLD信号 - 见wait4(2)& signal(7)。请阅读,例如sigaction(2)(您可以在线阅读)。

您还可以考虑使用advanced linux programmingpopen(3)(他们为pipe调用popen,然后调用fork& execve { {1}} /bin/sh ....)。

答案 1 :(得分:0)

分配新的内存块。参数将复制到此块。只有这样才能释放旧可执行文件内存中的页面。请注意,两者之间可能还有其他步骤。例如,在释放旧的可执行文件之前,新的可执行文件将映射到内存中。

答案 2 :(得分:0)

在Linux中使用fork + exec创建子进程。 fork()创建新进程,exec函数将作为exec()参数给出的image / executable重写/覆盖到进程空间并开始执行。