C clone功能未使用CLONE_NEWPID |执行SIGCHLD标志

时间:2017-08-19 22:19:43

标签: c stdout

我有以下代码:

#define _GNU_SOURCE
#include<sched.h>
#include<stdio.h>
#include<stdlib.h>
#include<sys/wait.h>
#include<unistd.h>
#include<errno.h>
#include<string.h>

static char child_stack[2048];

int x = 10;

static int child_fn() {
    printf("Pid: %ld\n", (long) getpid());
    return 0;
}

int main() {
    printf("before= %d\n", x);
    errno = 0;
    pid_t child_pid = clone(&child_fn, (void *) child_stack+1024, CLONE_NEWPID | SIGCHLD, NULL);
    if(child_pid == -1) {
        printf("%s\n", strerror(errno));
        return 0;
    } else {
        printf("clone()= %ld\n", (long) child_pid);
        printf("after= %d\n", x);

        while(waitpid(-1, NULL, 0) < 0 && errno == EINTR) {
            printf("waiting\n");
            continue;
        }

        return 0;
    }
}

我得到的输出是:

before= 10
clone()= 16
after= 10

这意味着child_fn确实被分配了一个Pid,即child_pid。但printf内的child_fn要么没有执行,要么可能在不同的标准范围内打印?无论哪种方式,可能是什么原因,以及如何调试它。我只是从命名空间开始,所以不太了解它们。

1 个答案:

答案 0 :(得分:1)

如果我使用gdb运行原始代码,我发现它失败了SIGSEGV

$ gcc -o clone clone.c
$ sudo gdb ./clone
(gdb) set follow-fork-mode child
(gdb) run
Starting program: /home/lars/tmp/clone 
before= 10
[New process 10768]
clone()= 10768
after= 10

Thread 2.1 "clone" received signal SIGSEGV, Segmentation fault.
[Switching to process 10768]
0x00007ffff7a5e9de in vfprintf () from /lib64/libc.so.6

我怀疑你的child_stack太小了。您已经分配了2048个字节,但是您只使用了一半。如果我将clone调用修改为如下所示:

pid_t child_pid = clone(&child_fn, (void *) child_stack+2048, CLONE_NEWPID | SIGCHLD, NULL);

然后在我的系统上它似乎正确运行:

$ sudo gdb ./clone
(gdb) set follow-fork-mode child
(gdb) run
Starting program: /home/lars/tmp/clone 
Missing separate debuginfos, use: dnf debuginfo-install glibc-2.24-9.fc25.x86_64
before= 10
[New process 10807]
clone()= 10807
after= 10
Pid: 1
[Inferior 2 (process 10807) exited normally]