2011-10-07 21 views
5

Tengo un error de segmentación al unirme a un subproceso secundario y he agotado todas las opciones que podía pensar en depuración, buscando en el desbordamiento de pila y en el resto de Internet. :) Seré tan completo como pueda. El código está escrito en C++ y compilado con GNU GCC en OSX 10.6.8. Me he vinculado en la biblioteca 'pthread' usando el parámetro '-pthread'. También probé '-lphtread'. Ninguna diferencia.pthread_join se bloquea intermitentemente con falla de segmentación en OSX

estoy usando las siguientes variables globales:

pthread_t gTid; 

pthread_attr_t gAttr; 

int gExitThread = 0; 

Estoy creando un hilo hijo de mi hilo conductor de ejecución:

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

Inside 'threadHandler', Tengo el siguiente ejecutar bucle utilizando la base API API:

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

Se utiliza la variable global gExitThread para indicar que el hilo debe matar correctamente . La macro RUN_LOOP_TIMEOUT se establece en 2 segundos (aunque los valores más grandes y más pequeños no hacen diferencia).

El hilo se señaliza a ser matado por el siguiente fragmento de código en el hilo principal:

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

La llamada a 'pthread_join' se bloquea con un fallo de segmentación después de un breve retraso. También he notado que reemplazar la llamada de 'pthread_join' con un reposo normal de, digamos, dos segundos, causa la misma falla de segmentación cuando se ejecuta 'usleep (2000000)'. Copiaré la traza posterior del volcado del núcleo a continuación tanto para 'pthread_join' como para '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 

será muy apreciada Cualquier ayuda.

Respuesta

8

Parece que el código después de su ciclo while dentro de threadHandler está causando una segfault. Si se genera una señal (por ejemplo, SIGSEGV) dentro de un hilo, el proceso en sí mismo será eliminado.

Intente utilizar GDB y thread apply all bt para obtener el seguimiento de todos los hilos.

+0

Gracias Milan. ¡Eso fue exactamente! Resulta que en mi hilo estuve lanzando un puntero NULL a un tipo de clase y luego se bloqueó al acceder a los miembros de datos de esa instancia. No solo es fijo, sé un poco más sobre hilos y gdb :) – lawrenceB

Cuestiones relacionadas