【问题标题】:pthread_exit in signal handler causes segmentation fault信号处理程序中的 pthread_exit 导致分段错误
【发布时间】:2011-09-16 06:11:49
【问题描述】:

下面的程序为整个进程设置 SIG_ALRM 处理程序,创建一个线程,向新创建的线程发送 SIG_ALRM 信号。 在 SIG_ALRM 处理程序中调用 pthread_exit。 结果 - 分段错误。 如果你在发送信号之前睡觉 - 好的。

看起来在 pthread_exit 的那一刻新线程还没有启动。 我尝试使用 gdb 定位分段错误,但无法使用 gdb 重现崩溃。

什么导致分段错误?

谢谢!

#include <signal.h>
#include <pthread.h>
#include <iostream>
#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;
}

输出:

主:140130531731232
alrm_handler: 140130504095488
分段错误

【问题讨论】:

    标签: linux pthreads segmentation-fault signals


    【解决方案1】:

    为要完成的线程初始化进程提供更改。所以只需取消注释下面的行是正确的方法。

      usleep(1000); 
    

    【讨论】:

    • Johh,你有没有明确说明的参考资料?谢谢!
    • @Ayrat:我找不到。但我刚刚分析了核心转储。由于线程还没有启动(所以它可能没有完全初始化),程序以SIGSEGV退出。
    【解决方案2】:

    pthread_exit 不是异步信号安全的。除非您可以确定信号处理程序没有中断异步信号不安全函数,否则您不能从信号处理程序调用它。特别是,调用 pthread_create 和进入新线程的启动函数之间的时间必须被认为是异步信号不安全的 - 这在标准中从未明确说明,但您可以认为新线程仍然是“在pthread_create"(这是异步信号不安全)中,如果你愿意的话。

    【讨论】:

    • 是的,我摆脱了在 signal_handler 中调用丑陋的出口。)谢谢 R..!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-10-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多