2016-04-11 11 views
1

Hallo zur Zeit sammle ich Backtrace des Kind Prozesses in Signal Handler des Kindes Prozess. Dann planen Sie, gesammelte Backtrace über die Nachrichtenwarteschlange an den übergeordneten Prozess zu senden. Mein Problem ist, wenn Kindprozess irgendein Signal bekommt. Der Kind-Signal-Handler wird ausgeführt, informiert jedoch den Elternprozess, dass das Kind normal beendet wurde, anstatt das Kind-Signal zu erhalten. unten ist mein CodeInformieren Elternprozess über Kind erhalten Signal nach Signal Handler im Kind Prozess bedient wird

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

} 

Meine Forderung ist nach Signal-Handler in Kindprozess bedient wird die Mutter gedruckt werden soll „Kind-Prozess nicht normal beendet !!“ aber ich bin bekommen "Kind normal beendet!" Nachricht

+1

'printf()', 'backtrace()', 'backtrace_symbols() und' exit() 'sind alle Async-Signal - ** unsicheren ** Funktionen. Nach dem [POSIX-Standard] (http://pubs.opengroup.org/onlinepubs/009695399/functs/xsh_chap02_04.html): * Wenn ein Signal eine unsichere Funktion unterbricht und die Signalfangfunktion eine unsichere Funktion aufruft, ist das Verhalten undefined. * Siehe auch die Linux 'signal'-Manpage unter http://man7.org/linux/man-pages/man7/signal.7.html –

+0

@Andew Ja, ich stimme deinem Standpunkt zu. Wie kann ich mein Problem lösen? Kannst du mir bitte helfen? Meine tatsächliche Anforderung ist es, einen Server zu implementieren, der nicht abstürzt. Anfrage wird vom Server kommen Also Anfrage erhalten Ich gebe Kind Prozess, um einige Operation mit Anfrage zu tun. Wenn die Anfrage von einem Kind verarbeitet wird, erzähle ich dem Elternteil, dass ich fertig bin, indem ich die Nachrichtenwarteschlange benutze und schließe. Wenn etwas Schlechtes im Kind passiert ist, sammeln Sie das Backtrace und geben Sie dem Elternteil –

Antwort

1

Von wait()'s Linux docs:

WIFEXITED (wStatus) gibt true zurück, wenn das Kind normal beendet, das heißt, durch den Aufruf von exit (3) oder _exit (2) oder durch von der Haupt Rückkehr() .

Der untergeordnete Signalhandler beendet den Prozess mit exit(), so dass alles ordnungsgemäß funktioniert.

Entfernen Sie den Aufruf exit()aus dem Signalhandler, um das erwartete Ergebnis zu erhalten.


Der Aufruf von raise()innerhalb der Signal-Handler am wahrscheinlichsten rekursive Aufrufe führt, so entfernen, ist auch.

Verwandte Themen