pthread_join在OSX上间歇性地崩溃并出现分段错误

law*_*ceB 5 macos multithreading pthreads thread-safety

我在加入子线程时遇到了分段错误,我已经用尽所有可以考虑调试的选项,看看堆栈溢出和其他互联网!:)我会尽可能彻底.代码用C++编写,在OSX 10.6.8上用GNU GCC编译.我使用'-pthread'参数在'pthread'库中链接.我也试过'-lphtread'.没有不同.

我正在使用以下全局变量:

pthread_t gTid;

pthread_attr_t gAttr;

int gExitThread = 0;
Run Code Online (Sandbox Code Playgroud)

我正在从我的主要执行线程创建一个子线程:

err = pthread_attr_init(&gAttr);
if (err)
{
    throw CONTROLLER_THREAD_ERROR;
}

err = pthread_attr_setdetachstate(&gAttr, PTHREAD_CREATE_JOINABLE);
if (err)
{
    throw CONTROLLER_THREAD_ERROR;
}

err = pthread_create(&gTid,&gAttr,threadHandler,NULL);
if (err)
{
    throw CONTROLLER_THREAD_ERROR;
}
Run Code Online (Sandbox Code Playgroud)

在'threadHandler'中,我使用核心基础API进行以下运行循环:

// Enter run loop
result = CFRunLoopRunInMode(kCFRunLoopDefaultMode, RUN_LOOP_TIMEOUT, false);
while (result == kCFRunLoopRunTimedOut)
{
    if (gExitThread) break;
    result = CFRunLoopRunInMode(kCFRunLoopDefaultMode, RUN_LOOP_TIMEOUT, false);
}
Run Code Online (Sandbox Code Playgroud)

gExitThread全局变量用于表示线程应该正常自杀.RUN_LOOP_TIMEOUT宏设置为2秒(尽管较大和较小的值没有区别).

线程被信号通过主线程中的以下代码段被杀死:

int err = 0;
void* exitValue = NULL;

printf("Stopping controller thread...\n");

gExitThread = 1;
err = pthread_join(gTid, &exitValue);
if (err)
{
    displayError2(err);
    throw CONTROLLER_THREAD_ERROR;
}

err = pthread_attr_destroy(&gAttr);
if (err)
{
    throw CONTROLLER_THREAD_ERROR;
}
Run Code Online (Sandbox Code Playgroud)

在短暂延迟后,对"pthread_join"的调用会因分段错误而崩溃.我还注意到用正常的睡眠替换'pthread_join'的调用让我们说两秒钟,在执行'usleep(2000000)'时会导致完全相同的分段错误!我将复制下面核心转储的后面跟踪'pthread_join'和'usleep'.

在pthread_join:

#0  0x00007fff8343aa6a in __semwait_signal ()
#1  0x00007fff83461896 in pthread_join ()
#2  0x000000010000179d in Controller::cleanup () at src/native/osx/controllers.cpp:335
#3  0x0000000100008e51 in ControllersTest::performTest (this=0x100211bf0) at unittests/src/controllers_test.cpp:70
#4  0x000000010000e5b9 in main (argc=2, argv=0x7fff5fbff980) at unittests/src/verify.cpp:34
Run Code Online (Sandbox Code Playgroud)

usleep(2000000):

#0  0x00007fff8343aa6a in __semwait_signal ()
#1  0x00007fff8343a8f9 in nanosleep ()
#2  0x00007fff8343a863 in usleep ()
#3  0x000000010000177b in Controller::cleanup () at src/native/osx/controllers.cpp:335
#4  0x0000000100008e3d in ControllersTest::performTest (this=0x100211bf0) at unittests/src/controllers_test.cpp:70
#5  0x000000010000e5a5 in main (argc=2, argv=0x7fff5fbff980) at unittests/src/verify.cpp:34
Run Code Online (Sandbox Code Playgroud)

任何帮助将不胜感激.

Mil*_*lan 8

似乎你的while循环中的代码threadHandler导致了段错误.如果在线程内生成信号(例如SIGSEGV),则进程本身将被终止.

尝试使用GDB和thread apply all bt为了获得所有线程的回溯.