Domanda

Sto giocando con waitpid() e signal() e sto cercando casi di test affidabili per restituire WIFSIGNALED(status) = WIFSTOPPED(status) = WIFCONTINUED (status) = true ma non riesco a trovarne nessuno...

Vuoi dirmi come posso assicurarmi che ritornino true in modo da poter eseguire il debug del mio codice?

Inoltre, alcuni suggerimenti su quali segnali dovrei catturare con signal() per testare quelle macro sarebbero utili...

È stato utile?

Soluzione

#include <errno.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <unistd.h>

#define NELEMS(x) (sizeof (x) / sizeof (x)[0])

static void testsignaled(void) {
   kill(getpid(), SIGINT);
}

static void teststopped(void) {
   kill(getpid(), SIGSTOP);
}

static void testcontinued(void) {
   kill(getpid(), SIGSTOP);
   /* Busy-work to keep us from exiting before the parent waits.
    * This is a race.
    */
   alarm(1);
   while(1) {}
}

int main(void) {
   void (*test[])(void) = {testsignaled, teststopped, testcontinued};
   pid_t pid[NELEMS(test)];
   int i, status;
   for(i = 0; i < sizeof test / sizeof test[0]; ++i) {
      pid[i] = fork();
      if(0 == pid[i]) {
         test[i]();
         return 0;
      }
   }
   /* Pause to let the child processes to do their thing.
    * This is a race.
    */
   sleep(1);
   /* Observe the stoppage of the third process and continue it. */
   wait4(pid[2], &status, WUNTRACED, 0);
   kill(pid[2], SIGCONT);
   /* Wait for the child processes. */
   for(i = 0; i < NELEMS(test); ++i) {
      wait4(pid[i], &status, WCONTINUED | WUNTRACED, 0);
      printf("%d%s%s%s\n", i, WIFCONTINUED(status) ? " CONTINUED" : "", WIFSIGNALED(status) ? " SIGNALED" : "", WIFSTOPPED(status) ? " STOPPED" : "");
   }
   return 0;
}

Altri suggerimenti

Manipolazione WIFSIGNALED è facile. Il processo figlio può suicidarsi con la chiamata di sistema kill(). Si può anche verificare la presenza di core dump - alcuni segnali creano loro (SIGQUIT, IIRC); alcuni segnali non (SIGINT).

Movimentazione WIFSTOPPED potrebbe essere più difficile. Il semplice passaggio da provare è per il bambino per inviarsi SIGSTOP con la chiamata di sistema kill() di nuovo. In realtà, credo che dovrebbe funzionare. Si noti che si consiglia di verificare sul SIGTTIN e SIGTTOU e SIGTSTOP - credo che contano per WIFSTOPPED. (C'è anche la possibilità che SIGSTOP funziona solo in modo sano se inviato da un debugger a un processo è in esecuzione tramite la chiamata di sistema non-POSIX, ptrace().)

Movimentazione WIFCONTINUED è una cosa che penso che il genitore ha a che fare; dopo cui si verifichi un processo è stato fermato, il vostro codice chiamante dovrebbe rendere procedi con l'invio di un segnale di SIGCONT (kill() di nuovo). Il bambino non è in grado di fornire questa stessa; che è stato arrestato. Anche in questo caso, non sono sicuro se ci sono le rughe in più di cui preoccuparsi -. Probabilmente

Un qualcosa come il quadro qui sotto ti permette di controllare i risultati degli inviti wait() e waitpid().

pid_t pid = fork();

if (pid == 0) {
    /* child */
    sleep(200);
}
else {
    /* parent */
    kill(pid, SIGSTOP);

    /* do wait(), waitpid() stuff */
}

In realtà non è necessario catturare i segnali (utilizzando signal() o una funzione correlata) che vengono inviati. signal() installa un gestore che ignora il comportamento di default per il segnale specifico - quindi se si vuole verificare la presenza di un segnale di terminazione il processo, scegliere uno che ha quel comportamento predefinito -. "man -s7 signal" vi darà i dettagli il comportamento predefinito di un segnale

Per le macro che hai menzionato l'uso SIGSTOP per WIFSTOPPED(status), SIGCONT per WIFCONTINUED (status) e SIGINT per WIFSIGNALED(status)

Se si desidera una maggiore flessibilità per il test, è possibile utilizzare kill (vedi "man kill") per inviare segnali al processo. kill -l elencherà tutti i segnali che possono essere inviati.

nei tuoi test puoi fork() e inviare segnali specifici ai processi figli?In questo scenario i tuoi processi figli sono casi di test?

MODIFICARE

la mia risposta riguarda la codifica di un test C.Fork, ottieni il PID del processo figlio (il processo con i gestori di segnale installati), quindi puoi inviare il segnale utilizzandolo utilizzando kill(2).In questo modo puoi testare lo stato di uscita

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top