【问题标题】:Linux Process Creation : User mode stackLinux进程创建:用户模式堆栈
【发布时间】:2023-03-11 16:45:01
【问题描述】:

我是 Linux 新手,从用户模式了解到,如果一个进程调用系统调用 fork(),那么该进程在系统模式下开始执行,并使用新的内核模式空间创建一个新的子进程(它包括堆栈也)分配给新创建的子进程。 我的问题是, 1>如何以及何时为这个新创建的进程创建用户模式堆栈? 2>内核如何知道这个新创建的进程的用户模式堆栈在哪里? 3>内核可以在新创建的进程上下文中以内核模式执行时访问用户模式堆栈吗?

如果我的问题或理解有误,请纠正我。

提前感谢您的指导。

问候 比贝克

【问题讨论】:

    标签: linux


    【解决方案1】:

    我的答案是:

    1. 为新进程复制整个虚拟内存,包括任何堆栈。内核对它的处理与其他任何页面没有区别
    2. 内核不需要知道用户模式堆栈在哪里来实现这一点,它只是复制整个地址空间。
    3. 它不需要访问用户模式堆栈来执行此操作。

    唯一的区别是内核给父母和孩子的返回值。

    当 fork() 系统调用返回时,它会回到父子节点中相同的地址,但返回值不同(子节点始终为 0,父节点获取子节点的 pid)。因为他们每个人都有自己的堆栈副本(这将是写时复制,但很快就会被写入),这没问题。

    【讨论】:

      【解决方案2】:
      1. 通常,当您调用 exec() 或创建新的线程时,程序会获取新的用户模式堆栈。如果您想手动执行此操作,请使用mmap() 系统调用。 注意:一个进程可以有多个堆栈(绿色线程或信号堆栈)。

      2. 当您进行系统调用时,您的寄存器会被保存——这包括堆栈地址。

      3. 大部分内核函数无法直接访问用户模式堆栈。但是,当然,在 ring-0 中,内核可以调整权限并在需要时对其进行评估。在未修改的内核中,这仅限于少数选定的功能。 (在您的内核源代码中搜索copy_to_usercopy_from_user

      【讨论】:

        【解决方案3】:

        fork() 复制分配给分叉进程(父进程)的整个内存映射。它创建一个相同的进程,然后独立于父进程进行。

        两者以相同的堆和堆栈开始。指向当前堆栈位置的 x86 寄存器指向父进程和子进程的相同内存地址(因为它们的内存映射相同)。

        【讨论】:

          猜你喜欢
          • 2011-12-22
          • 1970-01-01
          • 2019-03-16
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-04-24
          • 2019-12-07
          相关资源
          最近更新 更多