gpt4 book ai didi

c - 为什么 _do_fork() 的 kretprobe 只返回一次?

转载 作者:可可西里 更新时间:2023-11-01 11:52:00 25 4
gpt4 key购买 nike

当我使用 fork 编写一个小脚本时,系统调用返回两次进程(每个进程一次):

#include <stdio.h>
#include <unistd.h>

int main(int argc, char *argv[]) {
int pid = fork();

if (pid == 0) {
// child
} else if (pid > 0) {
// parent
}
}

如果我用 systemtap 对其进行检测,我只会找到一个返回值:

// fork() in libc calls clone on Linux
probe syscall.clone.return {
printf("Return from clone\n")
}

(SystemTap installes probes on _do_fork 而不是克隆,但这不应该改变任何东西。)

这让我很困惑。几个相关的问题:

  • 为什么系统调用只返回一次?
  • 如果我理解 _do_fork code正确地,该过程被克隆在函数的中间。 (copy_processwake_up_new_task)。后面的代码不应该在两个进程中运行吗?
  • 系统调用之后的内核代码是否与系统调用之前的用户代码在同一线程/进程中运行?

最佳答案

  1. 创建 child 可能会失败,因此必须检测和处理错误
  2. child 有不同的返回值,这也必须处理
  3. 可能是 parent 有清理/其他操作要做

因此,代码必须区分作为父项和子项执行。但是没有这种检查,这已经是一个强烈的暗示, child 一开始就没有执行这段代码。因此,应该寻找一个新的 child 返回的专用场所。

由于代码又大又多毛,人们可以尝试作弊并在 arch-specific 代码中寻找“fork”,这很快就会揭示 ret_from_fork。

通过 -> do_fork -> copy_process -> copy_thread_tls http://lxr.free-electrons.com/source/arch/x86/kernel/process_64.c#L158 设置起点

因此

Why does the syscall only return once?

它不会返回一次。有 2 个返回线程,除了另一个使用不同的代码路径。由于探测器仅安装在第一个上,您看不到另一个。另见下文。

If I understand the _do_fork code correctly, the process is cloned in the middle of the function. (copy_process and wake_up_new_task). Shouldn't the subsequent code run in both processes?

我之前指出这是错误的。真正的问题是让 child 返回与 parent 相同的地方有什么好处。我没有看到任何东西,这会很麻烦(额外的特殊外壳,如上所述)。重申一下:让 child 返回 elsehwere 让调用者不必处理返回的 child 。他们只需要检查错误。

Does the kernel code after a syscall run in the same thread / process as the user code before the syscall?

什么是“系统调用后的内核代码”?如果你是线程X,进入内核,你还是线程X。

关于c - 为什么 _do_fork() 的 kretprobe 只返回一次?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43277675/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com