Patch to correct the refrence count of fork handler in child process

suzuki suzuki@in.ibm.com
Sun Feb 25 21:44:00 GMT 2007


Hi,

While debugging a hang in one of our applications I came across the 
following bug in NPTL library.

The hang occurs in a child process spawn by a multi-threaded 
application. The application has been linked to a library which has 
registered "pthread_atfork()" handlers. The child processes hang 
indefinitely at __unregister_atfork() while exiting. These hanging 
processes have only one thread of execution, but they were waiting for 
the fork handler count to become 0, from a number which was greater than 2.

eg:

[root@c108bc2b01 ~]# strace -p 16603
Process 16603 attached - interrupt to quit
futex(0x800730, FUTEX_WAIT, 8, NULL <unfinished ...>
Process 16603 detached
[root@c108bc2b01 ~]# strace -p 16605
Process 16605 attached - interrupt to quit
futex(0x800730, FUTEX_WAIT, 7, NULL <unfinished ...>


This happens with the following scenario :

When mulitple threads in a process call fork () (simultaneously), they 
might end up in bumping up the fork handler ref. counts to a value > 2 
(depending on the number of threads and the timings). The child process 
forked thus would have an abnormal fork handler refcount which would 
never drop back to 0 and thus wait indefinitely while doing an 
__unregister_atfork().

We have verified the attached patch, where we reset the fork-handler 
refcounts to 1 for the child process. It is safe to do that, since we 
are the only thread in the process.


--- libc.orig/nptl/sysdeps/unix/sysv/linux/fork.c       2003-12-20 
15:37:13.000000000 -0800
+++ libc/nptl/sysdeps/unix/sysv/linux/fork.c    2007-02-23 
12:24:02.000000000 -0800
@@ -167,8 +167,12 @@
             allp->handler->child_handler ();

           /* Note that we do not have to wake any possible waiter.
-            This is the only thread in the new process.  */
-         --allp->handler->refcntr;
+            This is the only thread in the new process.
+            The count may have been bumped up by other threads doing
+            a fork. We reset it to 1, to avoid waiting for non-existing
+            thread(s) to release the count.
+          */
+         allp->handler->refcntr = 1;



Comments are more than welcome !

If it looks correct, could you please push this upstream ?


Thanks,

Suzuki K P
Linux Technology Center,
IBM

-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: fix-fork-handler-refcount-in-child.patch
URL: <http://sourceware.org/pipermail/libc-alpha/attachments/20070225/75153fec/attachment.ksh>


More information about the Libc-alpha mailing list