Dear Sir,

I am writing to thank you for your letter and say,

'trouble trouble trouble, nothing but trouble'.

FreeBSD bug bin/17437 (see 
http://www.FreeBSD.org/cgi/query-pr.cgi?pr=17437) acknowledges this bug 
as high priority and serious in 2000 !

from the PR

'
(Following up on myself, after further investigations):

Nope, the above patch is insufficient, it just serves to uncover
more bugs...

The problem is that libc_r does not do complete cleanup of the other
threads after the fork.  All deleted threads must be quietly removed
from any queues they happen to be waiting in, or they may later be
subject to "revival" after they have been freed.

Scenario (typical use of pthread_atfork()):
         - forking thread aquires a number of mutexes.
         - another thread waits on one of the mutexes
         - after forking, the mutexes are released,
           which will make any waiting threads
           runnable -- but they have been deallocated!
         - Bad Things(tm) happen...

All mutexes where this may happen can be conveniently located via the
"mutexq" field of the running thread, so this particular scenario is
easily fixed.

There is no similar way to handle threads queued on, for example,
condition variables, as there is no way to find the head of the "qe"
and "pqe" queue entries.  The "join_queue" should be emptied too.

Basically, right now libc_r does not work at all after a fork().

        Regards,
        /Mikko
'

More comment below



On Sun, Jul 13, 2003 at 07:49:55PM -0700, Burton Strauss wrote:
> Interesting S... if it doesn't implement pthread_atfork(), then there's actually no 
> safe way to run on FreeBSD...  I'll dump the text from the man page at the bottom - 
> it makes for interesting reading!
> 
> It's easy enough to #ifdef that stuff out - it's all self contained.  I can fix it 
> in the cvs easily too.  You won't be any worse off than you were previously...
> 
> But - can you check a couple of things for me re FreeBSD?
> 
> 1. If you fork() does it copy memory or is it shared?
>

I think the former (copy memory _not_ shared) since

1

2 sample fork program has common values of the common variables and 
changing the value of a var in the parent does not change that in the 
child.

pc09011> cat z.c
#include <stdlib.h>

 int
main(int argc, char *argv[]) {

  int p1, p_x, p_y ;

  p_x = 1 ; p_y = 2 ;

  printf("before fork().\n") ;
  printf("process [%d] x: %d\n", (int) getpid(), p_x) ;
  printf("process [%d] y: %d\n", (int) getpid(), p_y) ;

  if ( (p1 = fork())  == -1 ) {
     printf("fork() failed.\n") ;
     exit(1) ;
  }

  printf("after fork().\n") ;

  if ( p1 ) {
    p_y = 4 ;
    printf("setting y in parent [%d] .. y: %d\n", (int) getpid(), p_y) ;
  } else {
    printf("process [%d] x: %d\n", (int) getpid(), p_x) ;
    printf("process [%d] y: %d\n", (int) getpid(), p_y) ;
  }

}

pc09011> ./z
before fork().
process [15371] x: 1
process [15371] y: 2
after fork().
after fork().
setting y in parent [15371] .. y: 4
process [15372] x: 1
pc09011> process [15372] y: 2

pc09011> 





> 2. What level of POSIX threads does FreeBSD support? (pthreads_atfork() is part of 
> POSIX Threads Extension (1003.1c-1995) - it's even available in Solaris for ghu's 
> sake...)
>


>From man prthread

STANDARDS
     The functions in libc_r with the pthread_ prefix and not _np suffix 
or pthread_rwlock prefix conform to ISO/IEC 9945-1:1996 (``POSIX.1'').

So this looks like a bug.
 
> 
> -----Burton
> 
> 
> 
> DESCRIPTION
>        pthread_atfork registers handler functions to be called just before and
>        just  after a new process is created with fork(2).  The prepare handler
>        will be called from the parent process, just before the new process  is
>        created.  The  parent  handler  will be called from the parent process,
>        just before fork(2) returns. The child handler will be called from  the
>        child process, just before fork(2) returns.
> 
>        One  or  several of the three handlers prepare, parent and child can be
>        given as NULL, meaning that no handler needs to be called at the corre-
>        sponding point.
> 
>        pthread_atfork  can  be called several times to install several sets of
>        handlers. At fork(2) time, the prepare  handlers  are  called  in  LIFO
>        order (last added with pthread_atfork, first called before fork), while
>        the parent and child handlers are called in FIFO  order  (first  added,
>        first called).
> 
>        To understand the purpose of pthread_atfork, recall that fork(2) dupli-
>        cates the whole memory space, including mutexes in their current  lock-
>        ing  state,  but only the calling thread: other threads are not running
>        in the child process.  The mutexes are not usable after  the  fork  and
>        must be initialized with pthread_mutex_init in the child process.  This
>        is a limitation of the current implementation and might or might not be
>        present in future versions.
> 
> 
> 

Yours sincerely.

-- 
------------------------------------------------------------------------
Stanley Hopcroft
------------------------------------------------------------------------

'...No man is an island, entire of itself; every man is a piece of the
continent, a part of the main. If a clod be washed away by the sea,
Europe is the less, as well as if a promontory were, as well as if a
manor of thy friend's or of thine own were. Any man's death diminishes
me, because I am involved in mankind; and therefore never send to know
for whom the bell tolls; it tolls for thee...'

from Meditation 17, J Donne.
_______________________________________________
Ntop mailing list
[EMAIL PROTECTED]
http://listgateway.unipi.it/mailman/listinfo/ntop

Reply via email to