开发者

pthread_exit in signal handler causes segmentation fault

The program below sets SIG_ALRM handler for the whole process, creates a thread, sends SIG_ALRM signal to new created thread. In SIG_ALRM handler pthread_exit is called. The result - segmentation fault. If you sleep before sending signal - OK.

It looks like new thread has not been started at the moment of pthread_exit. I tried to locate segmentation fault with gdb but couldn't reproduce the crash with gdb.

What causes segmentation fault?

Thanks!

#include <signal.h>
#include <pthread.h>
#include <iostream>
#开发者_Python百科include <cassert>
using namespace std;

void* threadFunc(void* arg) {
    cout << "thread: started. sleeping..: " << pthread_self() << endl;
    sleep(10);
    cout << "thread: exit" << endl;
    return NULL;
}

void alrm_handler(int signo) {
    cout << "alrm_handler: " << pthread_self() << endl;

    pthread_exit(NULL); //if comment - no segmentation fault
}

int main() {
    cout << "main: " << pthread_self() << endl;

    struct sigaction act;
    act.sa_handler = alrm_handler;
    act.sa_flags = 0;
    sigemptyset(&act.sa_mask);
    sigaction(SIGALRM, &act, NULL);

    pthread_t t;
    int rc = pthread_create(&t, NULL, threadFunc, NULL);
    assert(rc == 0);

//  usleep(1000); //if Uncomment - no segmentation fault
    rc = pthread_kill(t, SIGALRM);
    assert(rc == 0);

    pthread_join(t, NULL);

    cout << "main: exit" << endl;
    return 0;
}

The output:

main: 140130531731232

alrm_handler: 140130504095488

Segmentation fault


pthread_exit is not async-signal-safe. You cannot call it from signal handlers unless you can be sure the signal handler is not interrupting an async-signal-unsafe function. In particular, the time between calling pthread_create and the entry to your new thread's start function must be considered async-signal-unsafe - this is never explicitly spelled out in the standard, but you can think of the new thread as still being "in pthread_create" (which is async-signal-unsafe) if you like.


Give change for thread initialization process to be completed. so just uncomment the below line is the right approach.

  usleep(1000); 
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜