Home | History | Annotate | Download | only in solaris
      1 /* Tests that Valgrind retains control over blocked signals.
      2    If synchronous signals (SIGSEGV) would be blocked, kernel would
      3    simply kill the process. When operating properly, Valgrind involves
      4    its synchronous signal handler and reports on the signal delivery.
      5 
      6    Valgrind and libc all retain their sigmasks and lie to us politely
      7    about what the actual sigmask is. One of reliable tests is to fork
      8    another process (because libc thinks it blocks all signals before fork
      9    and the forked process inherits the sigmask) and try to SIGSEGV it.
     10  */
     11 
     12 #include <assert.h>
     13 #include <errno.h>
     14 #include <stdio.h>
     15 #include <stdlib.h>
     16 #include <unistd.h>
     17 #include <sys/wait.h>
     18 
     19 int main(void)
     20 {
     21    pid_t pid = fork();
     22    if (pid < 0) {
     23       perror("fork");
     24       exit(1);
     25    } else if (pid == 0) {
     26       /* Causes SIGSEGV. */
     27       char *s = NULL;
     28       s[0] = 1;
     29    } else {
     30       pid_t ret;
     31       int status;
     32 
     33       while ((ret = waitpid(pid, &status, 0)) != pid) {
     34          if (errno != EINTR) {
     35             perror("waitpid");
     36             exit(1);
     37          }
     38       }
     39 
     40       if (WIFSIGNALED(status)) {
     41          assert(WTERMSIG(status) != 0);
     42 
     43          if (WTERMSIG(status) == SIGSEGV) {
     44             printf("PASS\n");
     45          } else {
     46             fprintf(stderr, "Child process died with unexpected signal %d.\n",
     47                     WTERMSIG(status));
     48          }
     49       } else if (WIFEXITED(status)) {
     50          if (WEXITSTATUS(status) == 0) {
     51             fprintf(stderr, "Child process exited without expected SIGSEGV "
     52                     "signal.\n");
     53          } else {
     54             fprintf(stderr, "Child process exited with unexpected status %d.\n",
     55                     WEXITSTATUS(status));
     56          }
     57       } else {
     58          fprintf(stderr, "Unrecognized status of child proces %x?\n", status);
     59       }
     60    }
     61 
     62    return 0;
     63 }
     64 
     65