1

对于这点 C 魔法,我总是有点模糊。当您调用 execv 时,您正在“替换进程映像”。这到底是什么意思呢?只是 DATA 段?一切都分配给进程?堆栈?堆?

我的问题是您传递给 execv 的参数所使用的存储会发生什么变化?如果它们是调用 execv 的函数的局部变量,那么它们就在堆栈上。但是如果你替换进程映像,并调用新进程的 main() 函数,当 main() 返回时会发生不好的事情,因为从主调用指向返回位置的堆栈信息被新进程映像替换。变量也一样,是吗?如果这些变量是在堆上分配的呢?

探究的头脑正在询问任何知道的人。

4

2 回答 2

2

函数系列取代了整个exec过程——数据、堆栈、文本、堆,一切。一些文件描述符可以保持打开状态(那些由原始进程打开而没有FD_CLOEXEC设置的)。但除此之外,您几乎可以获得一个全新的流程 - 请参阅链接了解所有详细信息。

您传入的参数会发生什么是操作系统的问题 - 它必须确保以main符合标准的方式将它们传递给新进程的函数,但我认为 POSIX 并没有明确规定它是如何做到的。

对于 Linux,您可以查看fs/exec.c文件以查看实现。跳到最后(我发布此内容时的第 1484 行)以查看do_execveat_common作为实现主要部分的函数。您会看到参数被复制到新的地址空间中(copy_strings在函数末尾附近调用)。

于 2015-12-06T13:40:19.943 回答
2

只是 DATA 段?

不,所有内存映射都被擦除并为新的可执行文件重新创建

一切都分配给进程?堆栈?堆?

是的,所有的记忆。但是,此处记录的一些内核资源是从父进程继承的,例如文件描述符。这些资源由内核管理,不属于进程内存。尽管所有这些都是操作系统特定的,但只要它符合上述 exec() 文档,它就可以通过各种方式实现这一点。

传递给 execv 的参数使用的存储会发生什么变化?

通常,内核会复制这些参数,并将它们注入到新可执行文件的内存中。

但是如果你替换进程映像,并调用新进程的 main() 函数,当 main() 返回时会发生不好的事情,

不,当 main() 返回时,该过程结束。调用 exec() 的原始进程的代码和内存不再存在,没有什么可返回的。

于 2015-12-06T13:41:25.923 回答