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>