threads/76690: fork hang in child for (-lc_r & -lthr)

Serguei Leontiev lse at CryptoPro.ru
Tue Jan 25 16:50:08 PST 2005


>Number:         76690
>Category:       threads
>Synopsis:       fork hang in child for (-lc_r & -lthr)
>Confidential:   no
>Severity:       critical
>Priority:       medium
>Responsible:    freebsd-threads
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Wed Jan 26 00:50:07 GMT 2005
>Closed-Date:
>Last-Modified:
>Originator:     Serguei Leontiev
>Release:        5.2.1
>Organization:
Crypto-Pro
>Environment:
FreeBSD build-fbsd 5.2.1-RELEASE FreeBSD 5.2.1-RELEASE #0: Mon Feb 23 20:45:55 GMT 2004     root at wv1u.btc.adaptec.com:/usr/obj/usr/src/sys/GENERIC  i386

>Description:
For multithreaded application malloc/free in other thread cause fork() hang in child process. Child process does not anything to work or threading operations.

This bug first detected for system() library function in multithreaded application.

This bug affected "-lc_r" and "-lthr" library. Library "-lkse" seems OK.

Sorry for my bests English.
>How-To-Repeat:
#include <errno.h>
#include <pthread.h>
#include <signal.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/wait.h>
#include <unistd.h>

const int INFL = 1000000000;
const int PTHR = 4;
const int NATR = 2;

#ifndef SEMI_OK         // if SEMI_OK not defined - >95% hang on my system
const int FRKL = 100;
#else                   // if SEMI_OK defined - 50% hang on my system
const int FRKL = 3;
#endif

void *malloc_free(void *pvcnt)
{
    volatile sig_atomic_t *pscnt = (volatile sig_atomic_t *)pvcnt;
    int n = *pscnt;
    int i;
    void *m;

    for(i = 0; i < n; i++){
        m = malloc(10);
        *pscnt = i;
        free(m);
    }
    return NULL;
}

int main (void)
{
    pthread_attr_t attrs[NATR];
    pthread_t thread_id;
    volatile sig_atomic_t cnt[PTHR];
    int i;
    pid_t pid, savedpid;
    int pstat;

    pthread_attr_init(&attrs[0]);
    pthread_attr_setdetachstate(&attrs[0], PTHREAD_CREATE_DETACHED);
    pthread_attr_setscope(&attrs[0], PTHREAD_SCOPE_PROCESS);
    pthread_attr_init(&attrs[1]);
    pthread_attr_setdetachstate(&attrs[1], PTHREAD_CREATE_DETACHED);
    pthread_attr_setscope(&attrs[1], PTHREAD_SCOPE_SYSTEM);
    for(i = 0; i < PTHR; i++) {
        cnt[i] = INFL;
        if(pthread_create(&thread_id, &attrs[i%NATR],
                        &malloc_free, (void *)&cnt[i])){
            perror("pthread_create:");
            return 1;
        }
    }
    fprintf(stderr, "Threads created.\n");

    for (i = 0; i < FRKL; i++) {
        fprintf(stderr, "forking\n");
        switch(pid = fork()) {
        case -1:                        /* error */
            perror("fork fail:");
            return 2;
        case 0:                         /* child */
            // Child don't anything to work - simple exit
            // When child hang, this hang in fork code
            _exit(0);
        default:                        /* parent */
            savedpid = pid;
            do{
                pid = waitpid(savedpid, &pstat, 0);
            }while(pid == -1 && errno == EINTR);
            break;
        }
    }
    fprintf(stderr, "Threads OK:");
    for(i = 0; i < PTHR; i++){
        fprintf(stderr, " %d", (int)cnt[i]);
    }
    fprintf(stderr, "\n");
    _exit(0);
    return 0;
}

>Fix:
      
>Release-Note:
>Audit-Trail:
>Unformatted:


More information about the freebsd-threads mailing list