2011-10-07 54 views
5

我得到一个分段错误,而在一个子线程加入,我已经用尽了我能想到的调试的所有选项,找对堆栈溢出和互联网的休息! :)我会尽可能详尽地为 。代码用C++编写,并在OSX 10.6.8上用GNU GCC编译。我使用'-pthread'参数链接了'pthread'库。我也试过'-lphtread'。没有不同。在pthread_join与分段故障间歇性崩溃的OSX

我使用以下全局变量:

pthread_t gTid; 

pthread_attr_t gAttr; 

int gExitThread = 0; 

我创建从我执行主线程子线程:

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; 
} 

里面“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); 
} 

使用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; 
} 

为“在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 

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 

任何帮助将不胜感激。

回答

8

看来,threadHandler内while循环之后的代码导致段错误。如果在线程内部生成一个信号(例如SIGSEGV),则该进程本身将被终止。

尝试使用GDBthread apply all bt以获得所有线程的回溯。

+0

谢谢米兰。这就是它!原来,在我的线程中,我将一个NULL指针转换为类类型,然后在访问该实例的数据成员时崩溃。不仅它是固定的,我更多地了解线程和gdb :) – lawrenceB