2013-07-11 1 views
1

원시 복제 시스템을 사용하려하지만 적절한 문서를 찾을 수 없습니다. 시도해보기 위해 작은 프로그램을 작성하려고했지만 세그먼트 오류로 끝납니다.Raw 복제 시스템 호출

내가 잘못 된 부분을 이해할 수 없습니다.

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; 
} 
+0

'clone' syscall을 사용하지 마십시오. 기본적으로 스레드 라이브러리 작성자 용으로 예약되어 있습니다. 'pthread' 라이브러리를 사용하십시오. –

+0

시스템 호출로 작업하기 때문에이 프로그램을 사용해야합니다. –

+0

'futex' 시스템 콜이 필요합니다.이 시스템 콜은 일부 기계 고유의 어셈블리 코드가 필요합니다. 왜 pthread를 사용할 수 없는지 설명해야하고, 커널 소스 코드에 대해 이해해야합니다. –

답변

-1

난 당신의 pthreads를 사용할 수 있는지가 클론과 함께가는 것이 좋습니다 말할 수 없다 :

여기에 작은 응용 프로그램입니다. 나는 clone과 관련하여 malloc()과 같은 함수에 나쁜 경험을했다.

man page 문서를 보셨습니까?

다음은 나를 위해 실행되는 예입니다. 나는 왜 당신의 코드가 크래쉬 (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; 
} 
+0

이것은 원시 복제가 아닙니다. –

+0

아마도이 프로그램에서'strace' 명령을 사용할 수 있습니다. 따라서이 복제 호출 아래의 "원시 복제본"시스템 호출에 어떤 인수가 들어가는지 볼 수 있습니다. 그런 다음 당신과 당신의 전화가 다른 것을보십시오. – Macattack