2016-04-11 20 views
1

現在、子プロセスのシグナルハンドラで子プロセスのバックトレースを収集しています。収集したバックトレースをメッセージキューを使用して親プロセスに送信することを計画します。 私の問題は、子プロセスがシグナルを受け取るときです。子シグナルハンドラは実行されますが、子プロセスが子プロセスの代わりに正常終了したことを親プロセスに通知します。 は、以下の私のコードです子プロセスのシグナルハンドラが提供された後、子プロセスが親プロセスに通知する

void childProcess() 
{ 
    int h =0 ; 
    for(h=0;h<10;h++) 
    { 
     printf("child for loop running %d\n",h); 
     //sleep(1); 
     int q = 1/0; // generate floating point exception 
    } 

    exit(0); 
} 



void signalhandler(int signum, siginfo_t *si, void *arg) 
{ 
    printf("signal received %s\n",strsignal(signum)); 
    printf("%d\n",signum); 
    void *array[100]; 
    int size = 100; 
    int addrLen = backtrace(&array,size); 
    char ** sym = backtrace_symbols(&array,addrLen); 
    int j = 0; 
    printf("Test crashed due to %s\n",strsignal(signum)); 
    for(j=0;j<addrLen;j++) 
    { 
     printf("%u : %s\n",array[j],sym[j]); 
    } 
    raise(signum);    
    exit(signum); 
} 

void registerSignals() 
{ 

    struct sigaction sa; 
    memset(&sa, 0, sizeof(sa)); 
    sigemptyset(&sa.sa_mask); 
    sa.sa_sigaction = signalhandler; 
    sa.sa_flags = SA_SIGINFO; 

    sigaction(SIGSEGV, &sa, NULL);  
    sigaction(SIGFPE, &sa, NULL); 

} 

int main() 
{ 
    //while(1) 
    { 
     pid_t pid; 
     pid = fork(); 
     if(pid == 0) 
     { 
      // child 
      printf("child process id is %d\n",getpid()); 
      registerSignals(); 
      childProcess(); 
     } 
     else 
     { 
      printf("parent process id is %d\n",getpid()); 
      // parent 
      int iStatus; 
      pid_t childPID = waitpid(pid,&iStatus,0); 
      printf("iStatus is %d\n",WIFEXITED(iStatus)); 
      if(childPID == -1) 
      { 
       printf("wait pid failed\n"); 
      } 
      else if(WIFEXITED(iStatus)==1) 
      { 
       printf("child exited normally!\n"); 
      } 
      else if (WIFSIGNALED(iStatus)==1) 
      { 
       printf("child process terminated abnormally !!\n"); 
       int iSignalnumber = 0; 
       // to fetch the signal number 
       iSignalnumber = WTERMSIG(iStatus); 
       printf("child process terminated due to %s\n",strsignal(iSignalnumber)); 
       // to check core file is generated or not 
       if(WCOREDUMP(iStatus)==1) 
       { 
        printf("core file is generated \n"); 
       } 
       else 
       { 
        printf("core file is not generated \n"); 
       } 
      } 
      int h ; 
      for(h = 0; h<10;h++) 
      { 
       printf("parent executing : %d\n",h); 
      } 
     } 
     printf("while loop executing with pid : %d \n", getpid()); 
     sleep(1); 
    } 

} 

私の要件は、シグナルハンドラが子プロセスに提供された後 親が印刷すべきである「子プロセスが異常終了!!」しかし、私は "子供は正常に終了しました!" wait()'s Linux docsからのメッセージ

+1

'printf()'、 'backtrace()'、 'backtrace_symbols()、' exit() 'はすべて非同期シグナル**安全でない**機能です。 [POSIX標準](http://pubs.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_04.html):*シグナルが安全でない関数を中断し、シグナル捕捉関数が安全でない関数を呼び出す場合、その動作は次のようになります。未定義* http://man7.org/linux/man-pages/man7/signal.7.html –

+0

のLinuxの 'signal'マンページも参照してください@Andewはい私はあなたの意見に同意します。私の問題を解決するにはどうしたらいいですか?私の実際の要件は、クラッシュしないサーバーを実装することです。リクエストはサーバーから来るのでリクエストを使用していくつかの操作を行う子プロセスを与えています。リクエストが子プロセスから処理されると、親プロセスに伝えられます。メッセージキューを使用して終了します。子供に何か悪いことが起こった場合バックトレースを集めて親に与える –

答えて

1

WIFEXITED(wstatus) 戻っ真の子供が(3)または_exit(2)、またはメインから返すことによって、出口を呼び出す ことで、つまり、正常に終了した場合() 。

子信号ハンドラは、exit()を使用してプロセスを終了するので、すべてが指定されたとおりに動作します。

シグナルハンドラからexit()へのコールを削除して、予期した結果を得る。


内部raise()への呼び出しシグナルハンドラが最も可能性の高い再帰呼び出しにつながるので、削除も同様です。

関連する問題