Linux:使用“clone3”和“waitid”

Linux: Using "clone3" and "waitid"

提问人:rempas 提问时间:10/18/2023 更新时间:10/18/2023 访问量:152

问:

我正在尝试使用“clone3”系统调用来了解分叉/克隆过程。我已经阅读了手册页来理解它。除了手册页之外,我只能找到一个如何在线(在互联网上)使用它的示例,它似乎不起作用。此外,该示例使用“waitpid”libc 函数而不是我想使用的“waitid”系统调用。总之,我修改了该示例以将其“转换”为以下代码:

#ifndef _GNU_SOURCE
#define _GNU_SOURCE 1
#endif
#include <bits/types/struct_rusage.h>
#include <errno.h>
#include <linux/sched.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/syscall.h>
#include <sys/wait.h>
#include <unistd.h>

#ifndef CLONE_PIDFD
#define CLONE_PIDFD 0x00001000
#endif

#ifndef __NR_clone3
#define __NR_clone3 -1
struct clone_args {
  __aligned_u64 flags;
  __aligned_u64 pidfd;
  __aligned_u64 child_tid;
  __aligned_u64 parent_tid;
  __aligned_u64 exit_signal;
  __aligned_u64 stack;
  __aligned_u64 stack_size;
  __aligned_u64 tls;
};
#endif

static pid_t sys_clone3(struct clone_args *args) { return syscall(__NR_clone3, args, sizeof(struct clone_args)); }
static int sys_waitid(
  idtype_t type, id_t id, siginfo_t* info,
  struct rusage* usage, int options)
{
  return syscall(247, type, id, info, usage, options);
}

int value = 10;

int main(int argc, char *argv[]) {
  struct clone_args args = {
    .flags = CLONE_VM,
    .exit_signal = SIGCHLD,
  };

  int pid = sys_clone3(&args);
  if (pid < 0) {
    fprintf(stderr, "%s - Failed to create new process\n", strerror(errno));
    exit(EXIT_FAILURE);
  }

  if (pid == 0) {
    printf("Child process with pid %d\n", getpid());
    value = 20;
    printf("Value changed!");
    exit(EXIT_SUCCESS);
  }

  printf("Parent process received child's pid %d\n", pid);

  siginfo_t info;
  struct rusage usage;
  int wait_status = sys_waitid(P_ALL, 0, &info, &usage, __WALL);
  if (wait_status == -1) {
    fprintf(stderr, "Failed to wait on child process (%d)\n", errno);
    exit(EXIT_FAILURE);
  }

  printf("Tha value is: %d\n", value);

  return 0;
}

然而,它不起作用。由于某种原因,克隆进程的块似乎没有执行。此外,如果我连续多次运行该程序,在某些时候,它将无法等待退出代码为“22”的进程。调用错误代码,这意味着 “waitid” 的选项无效(如手册页所述)。但是,这怎么可能不是每次都被执行,而是随机发生呢?我很困惑......EINVAL

我认为这也是一个很好的问题,因为网上关于“clone3”的信息很少。还应该指出的是,我特别需要这两个。我正在编写一个系统的库,我想学习如何使用它们。此外,我正在创建自己的“waitid”版本,因为“libc”版本没有使用“rusage”结构,所以我想 100% 确定没有其他我看不到的事情发生。谢谢!

我希望程序执行新创建的线程的块。

Linux 进程 系统调用 等待

评论

0赞 stark 10/18/2023
您是否期望在父流程中更改值?
0赞 rempas 10/18/2023
我是。但这不是问题所在。现在,我只想要创建的线程(子进程)来执行其代码。这段代码和我链接的示例都不起作用。为了更清楚,当我说“它的代码”时,我说的是第 54 行到第 59 行,它检查“pid”是否为 0(孩子应该如此)。
0赞 stark 10/19/2023
247从何而来?
0赞 stark 10/19/2023
waitid 似乎是 95 elixir.bootlin.com/linux/latest/source/include/uapi/asm-generic/......
0赞 rempas 10/19/2023
从我在网上找到的每一个来源中,他们都列出了“247”作为x86_64上“waitid”的数字。“95”列为 ARM64 的编号。您提供的来源似乎没有指定 Arch(当然,除非我是盲人,就像过去发生的那样)。看看我找到的一些来源:1 2 3 4 5

答: 暂无答案