原始克隆系统调用

时间:2013-07-11 22:15:05

标签: c linux linux-kernel fork system-calls

我正在尝试使用原始克隆系统,但我找不到任何适当的文档。 我试着编写一个小程序来尝试它,但最终会出现分段错误。

我无法理解我错在哪里。

这是一个小应用程序:

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 个答案:

答案 0 :(得分:-1)

如果可以使用pthreads,我不能说我建议使用clone。我对与clone相关的函数(例如malloc())有过不好的经验。

您是否查看过man page文档?

这是一个适合我的例子。我没有真正检查你的代码,看看它为什么会崩溃。

#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;
}