Raw Clone system call

2019-08-07 08:30发布

问题:

I am trying to use the raw clone system, but I could not find any proper documentation. I tried to write a small program to try it, but this ends up with a segmentation fault.

I cannot understand where I am wrong.

here is the small application :

define STACK_SIZE 0x10000
define BUFSIZE 200

#define _GNU_SOURCE

void hello (){
    fprintf(stderr,"Hello word\n"); 
    _exit(0); 
}


int main()  
{

int res; 
void *stack = mmap(0, STACK_SIZE, PROT_READ|PROT_WRITE,
                       MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
  pid_t ptid, tid; 

  printf("Stack %p\n", stack + STACK_SIZE);
  memset(stack, 0, STACK_SIZE); 

  res= syscall(SYS_clone,CLONE_SIGHAND|CLONE_FS|CLONE_VM|CLONE_FILES,stack + STACK_SIZE, &tid,&ptid,NULL );

  if (!res)
      hello(); 

  printf("Clone result %x\n", res); 
  waitpid(-1, NULL, __WALL); 

 return 0; 
}

回答1:

I can't say I recommend going with clone if you can use pthreads. I've had bad experience with functions such as malloc() in relation to clone.

Have you looked at the man page for documentation?

Here is an example that runs for me. I didn't really examine your code to see why it might be crashing.

#define _GNU_SOURCE
#include <stdio.h>
#include <sched.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <linux/sched.h>
#include <stdlib.h>
#include <unistd.h>
#include <assert.h>

// Allow us to round to page size
#define ROUND_UP_TO_MULTIPLE(a,b) \
( ( (a) % (b) == 0) ? (a) : ( (a) + ( (b) - ( (a) % (b) ) ) ) )

struct argsy {
    int threadnum;
};

int fun(void * args) {
    struct argsy * arguments = (struct argsy *) args;
    fprintf(stderr, "hey!, i'm thread %d\n", arguments->threadnum);
    return 0;
}

#define N_THREADS 10
#define PAGESIZE 4096

struct argsy arguments[N_THREADS];

int main() {
    assert(PAGESIZE==getpagesize());

    const int thread_stack_size = 256*PAGESIZE;
    void * base = malloc((((N_THREADS*thread_stack_size+PAGESIZE)/PAGESIZE)*PAGESIZE));
    assert(base);
    void * stack = (void *)ROUND_UP_TO_MULTIPLE((size_t)(base), PAGESIZE);

    int i = 0;
    for (i = 0; i < N_THREADS; i++) { 
        void * args = &arguments[i];
        arguments[i].threadnum = i;
        clone(&fun, stack+((i+1)*thread_stack_size), 
            CLONE_FILES | CLONE_VM,
            args);
    }

    sleep(1);

    // Wait not implemented
    return 0;
}