我正在研究exec系列函数。它的man page说,它用一个新的过程映像替换当前的过程映像。如果它替换了二进制文件,那么在返回之后,它如何获取调用exec的进程的先前参数?作为替换进程图像意味着替换其所有内存部分。如果我错了或知识较少,请纠正我。
答案 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 programming或popen(3)(他们为pipe
调用popen
,然后调用fork
& execve
{ {1}} /bin/sh
....)。
答案 1 :(得分:0)
分配新的内存块。参数将复制到此块。只有这样才能释放旧可执行文件内存中的页面。请注意,两者之间可能还有其他步骤。例如,在释放旧的可执行文件之前,新的可执行文件将映射到内存中。
答案 2 :(得分:0)
在Linux中使用fork + exec创建子进程。 fork()创建新进程,exec函数将作为exec()参数给出的image / executable重写/覆盖到进程空间并开始执行。