Bug 4506 - The use of pthread_kill or pthread_join in "dead threads" causes Segmentation Fault
Summary: The use of pthread_kill or pthread_join in "dead threads" causes Segmentation...
Status: RESOLVED INVALID
Alias: None
Product: glibc
Classification: Unclassified
Component: nptl (show other bugs)
Version: unspecified
: P1 critical
Target Milestone: ---
Assignee: Ulrich Drepper
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2007-05-14 19:12 UTC by Elcio Friedrich
Modified: 2014-07-04 16:34 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Last reconfirmed:
fweimer: security-


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Elcio Friedrich 2007-05-14 19:12:29 UTC
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;
}
Comment 1 Ulrich Drepper 2007-05-14 19:39:53 UTC
This is deliberate.  Fix your code, it's broken.