'How do I create a child process with clone and use waitpid to wait until its done?

The code below is wrong for at least 2 reasons. I'll be rewriting this in assembly so I'll need the solution to be only linux system calls. What I'd like to do is create a thread then wait on it until it's done

It appears to create and execute the thread just fine. But the first problem is waitpid says there's no child thread. I can't seem to wait on it/the process at all. The second problem is I appear to be exiting the thread wrong because sometimes I get a segfault

I think this has to do with SIGCHLD but I don't understand the notes in both clone and waitpid. I tried specifying SIGCHLD in clone and called wait with different options with no luck

Output:

clone() returned 12345
Waitpid: No child processes
12==5. 31==255? waitpid=-1

Code (C++ version, I'll need the answer to be syscalls/assembly friendly):

#include <sys/wait.h>
#include <sched.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <syscall.h>

int globalValue;

static int thread_func(void*arg)
{
    fprintf(stderr, "Global value was %d\n", globalValue);
    globalValue += 7;
    //syscall(__NR_exit, 31);
    return 31;
}

int main(int argc, char *argv[])
{
    auto stack_size = 1024 * 1024;
    auto stack = (char*)mmap(NULL, stack_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK, -1, 0);
    if (stack == MAP_FAILED) { perror("mmap"); exit(EXIT_FAILURE); }
    globalValue = 5;
    //auto pid = clone(thread_func, stack + stack_size, CLONE_THREAD|CLONE_VM|CLONE_SIGHAND, (void*)getpid());
    auto pid = clone(thread_func, stack + stack_size, CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID, (void*)getpid());
    if (pid == -1) { perror("clone"); exit(EXIT_FAILURE); }
    fprintf(stderr, "clone() returned %d\n", pid);
    int status=-1;
    int wait_res = waitpid(pid, &status, 0);
    perror("Waitpid");
    fprintf(stderr, "12==%d. 31==%d? waitpid=%d\n", globalValue, WEXITSTATUS(status), wait_res);
    return 0;
}


Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source