2011-10-07 86 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