I'd like to know if it is possible/the recommended way to catch the SIGSEGV signal in multithreaded environment. I am particularly interested in handling the SIGSEGV raised by something like *((int *)0) = 0.
Some reading on this topic led me to signal() and sigaction(), which install a signal handler. While neither seem promising in multithreaded environment. I then tried the sigwaitinfo(), receiving the signals in one thread with a prior pthread_sigmask() call that blocks the signal on the others. It worked to the extent upon which the signal SIGSEGV was raised, using raise(), inside a thread or when it was sent to the process by something like kill -SIGSEGV; however, \*((int*)0) = 0 still kills the process. My test program is as follows
void block_signal()
{
        sigset_t set;
        sigemptyset(&set);
        sigaddset(&set, SIGSEGV);
        sigprocmask(SIG_BLOCK, &set, NULL);
        if (pthread_sigmask(SIG_BLOCK, &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(&set);
        sigaddset(&set, SIGSEGV);
        for (;;) {
                sig = sigwaitinfo(&set, &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(&disp_tid, NULL, dispatcher, NULL)) {
                fprintf(stderr, "Cannot create dispatcher\n");
                exit(EXIT_FAILURE);
        }
        for (i = 0; i < 10; ++i) {
                if (pthread_create(&tid, NULL, buggy_thread, NULL) {
                        fprintf(stderr, "Cannot create thread\n");
                        exit(EXIT_FAILURE);
                }
        }
        pause();
}
Unexpectedly, the program dies with a segmentation fault instead of printing the raiser's thread id.