The use of pthread_kill(iThreadId, SIGCONT) or pthread_join(iThreadId, NULL) in "dead threads" causes Segmentation Fault. When a thread finish the execution and I send a signal SIGCONT with pthread_kill or wait for a thread execution or return using pthread_join, the application crashed. It occurs with the manipulations of 5 threads. On the example below try THREAD_MAX = 5 (it is going to crash) and THREAD_MAX = 3 (ok). I tested on OpenSuse 10.2 (NPTL 2.5) and Debian, both Kernel 2.6 and NPTL and both have the problem. I tested on Conectiva 9 (Kernel 2.4), using LinuxThreads and I didn't have any problem. Best, ManDraKe Example: ============================================= #include <pthread.h> #include <stdio.h> #include <stdlib.h> #include <signal.h> #include <sys/types.h> #include <sys/wait.h> #include <errno.h> #define THREAD_MAX 5 void HandlerManipulator(int iSignalNr) { } void* doWork (void* pArg) { int i; printf("\nWorker thread [%u] doing the job %d!\n", pthread_self()); sleep(1); printf("\n____+ Worker thread [%u] is DEAD !!!!\n", pthread_self()); return; } int main (int argc, char* const argv []) { int i, iRet, iBUG; pthread_attr_t attr; pthread_t hThread[THREAD_MAX]; pthread_t t1; struct sigaction stSigAction; memset (&stSigAction, 0, sizeof (stSigAction)); stSigAction.sa_handler = &HandlerManipulator; sigaction (SIGUSR1, &stSigAction, 0); sigaction (SIGCONT, &stSigAction, 0); pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); for (i = 0; i<THREAD_MAX; i++) { pthread_create (&hThread[i], &attr, &doWork, 0); printf("Create Thread[%d] = [%u]\n", i, hThread[i]); } iBUG = 0; while (1) { for (i = 0; i<THREAD_MAX; i++) { printf("hThread[%d] = [%u] Before Wait/Resume\n", i, hThread[i]); /* This point crashed after 2 interations with 5 threads */ // iRet = pthread_kill (hThread[i], SIGCONT); iRet = pthread_join (hThread[i], NULL); switch (iRet) { case 0: { printf("hThread[%d] = [%u] NO ERROS - iRet = %d\n", i, hThread[i], iRet); break; } case ESRCH: { printf("hThread[%d] = [%u] TID PROBLEM - iRet = %d\n", i, hThread[i], iRet); break; } case EINVAL: { printf("hThread[%d] = [%u] SIGNAL PROBLEM - iRet = %d\n", i, hThread[i], iRet); break; } default: { printf("hThread[%d] = [%u] UNKNOWN PROBLEM - iRet = %d\n", i, hThread[i], iRet); } } } sleep(1); iBUG++; printf("iBUG = %d\n", iBUG); } return 0; }
This is deliberate. Fix your code, it's broken.