threads/76694: fork cause hang in dup()/close() function inchild
(-lc_r)
Julian Elischer
julian at elischer.org
Wed Jan 26 16:40:25 PST 2005
The following reply was made to PR threads/76694; it has been noted by GNATS.
From: Julian Elischer <julian at elischer.org>
To: Serguei Leontiev <lse at CryptoPro.ru>
Cc: freebsd-gnats-submit at freebsd.org
Subject: Re: threads/76694: fork cause hang in dup()/close() function in child
(-lc_r)
Date: Wed, 26 Jan 2005 16:30:29 -0800
this may seem harsh, but 5.2.1 was still an experimental branch..
you should upgrade to 5.3 where lkse is the defualt (called libpthread).
libc_r will not be "actively" maintained after we settle on a kernel
supported threading package.
Serguei Leontiev wrote:
>>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 at 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:
>>
>>
>_______________________________________________
>freebsd-threads at freebsd.org mailing list
>http://lists.freebsd.org/mailman/listinfo/freebsd-threads
>To unsubscribe, send any mail to "freebsd-threads-unsubscribe at freebsd.org"
>
>
More information about the freebsd-threads
mailing list