2011-10-07 11 views
5

Dostaję błąd segmentacji podczas dołączania do wątku podrzędnego i wyczerpałem wszystkie opcje, które mogłem pomyśleć o debugowaniu, patrząc na Stack-overflow i resztę Internetu! :) Będę tak dokładny jak tylko będę mógł . Kod jest napisany w C++ i skompilowany z GNU GCC na OSX 10.6.8. Połączyłem bibliotekę "pthread", używając parametru "-pthread". Próbowałem również "-lphtread". Bez różnicy.pthread_join zawiesza się sporadycznie z błędem segmentacji na OSX

Używam następujące zmienne globalne:

pthread_t gTid; 

pthread_attr_t gAttr; 

int gExitThread = 0; 

Tworzę wątek dziecko z moim głównym wątku wykonania:

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

wewnątrz „threadHandler”, mam następujący uruchom pętlę za pomocą interfejsu API podstawy:

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

Używana jest zmienna globalna gExitThread sygnalizować, że wątek powinien samoczynnie zabić. Makro RUN_LOOP_TIMEOUT jest ustawione na 2 sekundy (chociaż większe i mniejsze wartości nie mają znaczenia).

Nić jest sygnalizowane zostać zabity przez następujący fragment kodu w głównym wątku:

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

Wezwanie do „pthread_join” wywala z winy segmentacji po krótkiej przerwie. Zauważyłem również, że zastąpienie wywołania "pthread_join" normalnym snem, powiedzmy dwie sekundy, powoduje dokładnie ten sam błąd segmentacji podczas wykonywania "usleep (2000000)"! Skopiuję z powrotem ślad zrzutu pamięci poniżej dla "pthread_join" i "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 

Każda pomoc będzie mile widziana.

Odpowiedz

8

Wygląda na to, że kod po pętli while wewnątrz threadHandler powoduje błąd segfault. Jeśli w wątku zostanie wygenerowany sygnał (na przykład SIGSEGV), sam proces zostanie zabity.

Spróbuj użyć GDB i thread apply all bt, aby uzyskać wynik śledzenia wszystkich wątków.

+0

Dziękuję Milan. To było dokładnie to! Okazuje się, że w moim wątku rzutowałem wskaźnik NULL na typ klasy, a następnie rozbiłem się podczas uzyskiwania dostępu do elementów danych tej instancji. Nie tylko jest to naprawione, wiem trochę więcej o wątkach i gdb :) – lawrenceB

Powiązane problemy