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