This is the mail archive of the
mailing list for the glibc project.
[RFC][BZ #1874] Fix assertion triggered by thread/fork interaction
- From: OndÅej BÃlka <neleai at seznam dot cz>
- To: libc-alpha at sourceware dot org, libc-ports at sourceware dot org
- Date: Wed, 9 Oct 2013 22:05:34 +0200
- Subject: [RFC][BZ #1874] Fix assertion triggered by thread/fork interaction
- Authentication-results: sourceware.org; auth=none
This bug had a simple patch for five years without reply.
Could someone comment this?
It was detected on custom chip, could this be replicated on other
An analysis from bugzilla and patch are below
If a thread happens to hold dl_load_lock and have r_state set to RT_ADD
or RT_DELETE at the time another thread calls fork(), then the child exit
code from fork (in nptl/sysdeps/unix/sysv/linux/fork.c in our case)
re-initializes dl_load_lock but does not restore r_state to RT_CONSISTENT.
If the child subsequently requires ld.so functionality before calling exec(),
then the assertion will fire.
The patch acquires dl_load_lock on entry to fork() and releases it on exit
from the parent path. The child path is initialized as currently done.
This is essentially pthreads_atfork, but forced to be first because the
acquisition of dl_load_lock must happen before malloc_atfork is active
to avoid a deadlock.
2007-05-29 23:44:33.000000000 -0400
2007-05-31 15:07:18.712221827 -0400
@@ -27,6 +27,7 @@
@@ -59,6 +60,8 @@
struct used_handler *next;
} *allp = NULL;
+ /* grab ld.so lock BEFORE switching to malloc_atfork */
+ __rtld_lock_lock_recursive (GL(dl_load_lock));
/* Run all the registered preparation handlers. In reverse order.
While doing this we build up a list of all the entries. */
struct fork_handler *runp;
@@ -208,6 +211,8 @@
allp = allp->next;
+ /* unlock ld.so last, because we locked it first */
+ __rtld_lock_unlock_recursive (GL(dl_load_lock));