【问题标题】:What happens to the parameters to execv?execv 的参数会发生什么变化?
【发布时间】:2015-12-06 13:16:34
【问题描述】:

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

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

求知者向任何知道的人求问。

【问题讨论】:

  • 我认为this 可能是最好的答案。
  • 操作系统需要设置新的地址空间,以便程序启动所需的一切都可用 - 这可能包括复制参数。
  • 没有所谓的“从主调用返回位置”。当main 返回时,程序结束。

标签: c execv


【解决方案1】:

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

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

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

【讨论】:

    【解决方案2】:

    只是 DATA 段?

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

    分配给进程的所有内容?堆栈?堆?

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

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

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

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

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

    【讨论】:

    • 对,这就是我所说的坏事会发生的意思。我只是没有发现将参数存储传递给旧宇宙已经不复存在的新宇宙之间的脱节。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-11
    • 2014-10-29
    • 2019-05-23
    • 2013-07-02
    相关资源
    最近更新 更多