我对这一点C魔法总是有些模糊。当你调用execv时,你正在“替换过程映像”。这到底是什么意思呢?只是DATA部分?分配给流程的一切?堆栈?堆?
我的问题是你传递给execv的参数所使用的存储会发生什么?如果它们是调用execv的函数的局部变量,那么它们就在堆栈中。但是如果你替换了进程映像,并调用了新进程的main()函数,那么当main()返回时会发生不好的事情,因为指向主调用返回位置的堆栈信息被新进程映像替换。 变量也一样,是吗?如果这些变量是在堆上分配的呢?
询问的人正在向任何知道的人询问。
答案 0 :(得分:2)
exec
系列函数替换了进程批发 - 数据,堆栈,文本,堆,所有内容。某些文件描述符可以保持打开状态(由原始进程打开但未设置FD_CLOEXEC
的文件描述符)。但除此之外,您几乎可以获得一个全新的流程 - 请参阅所有详细信息的链接。
您传入的参数会发生什么问题是操作系统的问题 - 它必须确保它们以符合标准的方式传递给新进程的main
函数,但我不认为POSIX确切地说明了它是如何做到的。
对于Linux,您可以查看fs/exec.c
文件以查看实现。跳到最后(我发布的第1484行)来查看do_execveat_common
函数,这是实现的主要部分。您将看到参数被复制到新的地址空间(在函数末尾附近调用copy_strings
)。
答案 1 :(得分:2)
只是DATA部分?
不,所有内存映射都会被删除并为新的可执行文件重新创建
分配给流程的所有内容?堆栈?堆?
是的,所有记忆。一些内核资源(记录为here)继承自父进程,例如文件描述符。这些资源由内核管理,不属于进程内存。所有这些都是特定于操作系统的,但只要它符合上面提到的exec()文档,它就可以通过各种方式实现这一点。
您传递给execv的参数所使用的存储会发生什么?
通常,内核会复制这些参数,并将它们注入新可执行文件的内存中。
但是如果你替换过程映像,并调用新进程的main()函数,那么当main()返回时会发生坏事,
不,当main()返回时,该进程结束。调用exec()的原始进程的代码和内存不再存在,没有什么可以返回。