title: About catching the SIGSEGV in multithreaded environment
body: <p>I'd like to know if it is possible/the recommended way to catch the <code>SIGSEGV</code> signal in multithreaded environment. I am particularly interested in handling the <code>SIGSEGV</code> raised by something like <code>*((int *)0) = 0</code>.</p>
  
  <p>Some reading on this topic led me to <code>signal()</code> and <code>sigaction()</code>, which install a signal handler. While neither seem promising in multithreaded environment. I then tried the <code>sigwaitinfo()</code>, receiving the signals in one thread with a prior <code>pthread_sigmask()</code> call that blocks the signal on the others. It worked to the extent upon which the signal <code>SIGSEGV</code> was raised, using raise(), inside a thread or when it was sent to the process by something like <code>kill -SIGSEGV</code>; however, <code>\*((int*)0) = 0</code> still kills the process. My test program is as follows</p>
  
  <pre><code>void block_signal()
  {
          sigset_t set;
  
          sigemptyset(&amp;set);
          sigaddset(&amp;set, SIGSEGV);
          sigprocmask(SIG_BLOCK, &amp;set, NULL);
  
          if (pthread_sigmask(SIG_BLOCK, &amp;set, NULL)) {
                  fprintf(stderr, "pthread_sigmask failed\n");
                  exit(EXIT_FAILURE);
          }
      }
  
  void *buggy_thread(void *param)
  {
          char *ptr = NULL;
          block_signal();
  
          printf("Thread %lu created\n", pthread_self());
  
          // Sleep for some random time
          { ... }
  
          printf("About to raise from %lu\n", pthread_self());
  
          // Raise a SIGSEGV
          *ptr = 0;
  
          pthread_exit(NULL);
  }
  
  void *dispatcher(void *param)
  {
          sigset_t set;
          siginfo_t info;
          int sig;
  
          sigemptyset(&amp;set);
          sigaddset(&amp;set, SIGSEGV);
  
          for (;;) {
                  sig = sigwaitinfo(&amp;set, &amp;info);
                  if (sig == -1)
                          fprintf(stderr, "sigwaitinfo failed\n");
                  else
                          printf("Received signal SIGSEGV from %u\n", info.si_pid);
          }
  }
  
  int main()
  {
          int i;
          pthread_t tid;
          pthread_t disp_tid;
  
          block_signal();
  
          if (pthread_create(&amp;disp_tid, NULL, dispatcher, NULL)) {
                  fprintf(stderr, "Cannot create dispatcher\n");
                  exit(EXIT_FAILURE);
          }
  
          for (i = 0; i &lt; 10; ++i) {
                  if (pthread_create(&amp;tid, NULL, buggy_thread, NULL) {
                          fprintf(stderr, "Cannot create thread\n");
                          exit(EXIT_FAILURE);
                  }
          }
  
          pause();
  }
  </code></pre>
  
  <p>Unexpectedly, the program dies with a segmentation fault instead of printing the raiser's thread id.</p>