为什么克隆包装器需要堆栈参数?

为什么克隆包装器需要堆栈参数?

我一直在仔细阅读clone()的linux手册页,并且我理解clone()包装器和“原始”系统调用之间的区别。但我不明白的是为什么父进程需要为子进程分配堆栈,即使包装器中没有使用 CLONE_VM 。

如果不使用 CLONE_VM,包装器是否会简单地忽略堆栈参数?那为什么还需要它呢?原始系统调用允许它为空,这是有道理的,但我不明白为什么包装器需要这个。即使您不告诉它,包装器会让孩子和父母共享内存吗?

答案1

所需的堆栈参数与论证fn。原始内核系统调用并不总是需要堆栈,因为它的行为类似于fork:子级中的执行在系统调用返回时开始。然后,libc 包装器需要设置调用的内容fn,并执行此操作,它需要堆栈(和一直都是这样做的)。

因此,在调用包装器时始终需要堆栈,以便通过系统clone调用将信息传递给调用函数的代码fnthread_start在 glibc 代码中)。

答案2

我相信我自己已经找到了答案。查看克隆包装器 (clone.s) 的 x86-64 源文件,我发现了这段有趣的代码:

movq %rdi,0(%rsi)

这会将函数指针放入子进程堆栈中。这发生在克隆系统调用之前。如果我的理解是正确的,那么这会导致子进程返回到传递给包装器的函数。这解释了为什么包装器需要一个堆栈参数,以便它可以将函数地址放在上面。这似乎意味着堆栈只需要足够大以容纳函数指针和参数。我不确定为什么手册页没有解释这一点,或者我在阅读时错过了一些东西

相关内容