2017-08-19 7 views
0

は、私は次のコードを持っている:Cのクローン関数はCLONE_NEWPIDで実行されていません。 SIGCHLDフラグ

#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_fnchild_pidあるPIDが、割り当てられますなかったことを意味します。しかしprintfの中のchild_fnは実行されなかったか、別のstdoutスコープで印刷されている可能性がありますか?いずれにせよ、これの理由とそれをデバッグする方法。私はちょうど名前空間から始まっているので、それらについてはあまり知らない。

答えて

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] 
関連する問題