Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 26 Jan 2005 01:11:41 GMT
From:      Serguei Leontiev <lse@CryptoPro.ru>
To:        freebsd-gnats-submit@FreeBSD.org
Subject:   threads/76694: fork cause hang in dup()/close() function in child (-lc_r)
Message-ID:  <200501260111.j0Q1Bf8G086739@www.freebsd.org>
Resent-Message-ID: <200501260120.j0Q1KJFb042014@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help

>Number:         76694
>Category:       threads
>Synopsis:       fork cause hang in dup()/close() function in child (-lc_r)
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    freebsd-threads
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Wed Jan 26 01:20:19 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@wv1u.btc.adaptec.com:/usr/obj/usr/src/sys/GENERIC  i386
      
>Description:
For multithreaded application dup()/close() in other thread cause hang dup()/close() in child process after fork. Child do not use thread related operations.

This bug first detected for accept() library function after daemon(). May be daemon() not thread-safe, but dup()/close() - MUST thread-safe by POSIX, and MUST compatible with fork() anywhere.

This bug affected "-lc_r" library. Library "-lthr" & "-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;
const int CHLD = 100;
#else                   // if SEMI_OK defined - 50% hang on my system
const int FRKL = 10;
const int CHLD = 10;
#endif

void *test_write(void *pvcnt)
{
    volatile sig_atomic_t *pscnt = (volatile sig_atomic_t *)pvcnt;
    int n = *pscnt;
    int i;
    int fd;

    for(i = 0; i < n; i++){
        if(0 > (fd = dup(STDIN_FILENO))){
            perror("dup:");
            continue;
        }
        *pscnt = i;
        if(0 > close(fd)){
            perror("close:");
        }
    }
    return NULL;
}

int main (void)
{
    pthread_attr_t attrs[NATR];
    pthread_t thread_id;
    volatile sig_atomic_t cnt[PTHR];
    int i;
    int cntr;
    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],
                        &test_write, (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 use thread related operations
                // Only dup() & close()
            cntr = CHLD;
            test_write(&cntr);
            _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:



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200501260111.j0Q1Bf8G086739>