• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
main(void)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