tech-userlevel archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
fork() and ld.elf_so
Hi all,
attached patch introduces the necessary hooks around fork() to prevent
lock starvation in multi-thread programs. Basic issue:
Thread 1 calls dlopen()
Thread 2 calls fork()
Child tries to bind a weak symbol
-> Bomb
Joerg
Index: include/dlfcn.h
===================================================================
RCS file: /home/joerg/repo/netbsd/src/include/dlfcn.h,v
retrieving revision 1.22
diff -u -p -r1.22 dlfcn.h
--- include/dlfcn.h 24 Dec 2010 12:41:42 -0000 1.22
+++ include/dlfcn.h 28 Mar 2011 18:59:57 -0000
@@ -110,4 +110,15 @@ __END_DECLS
#endif
#endif /* _NETBSD_SOURCE */
+#if defined(_LIBC) || defined(_RTLD_SOURCE)
+#define RTLD_LOCK_PRE_FORK 1
+#define RTLD_LOCK_POST_FORK 2
+#endif
+
+#if defined(_LIBC)
+__weakref_visible void _rtld_lock_handler(int) __weak_reference(_rtld_lock);
+#elif defined(_RTLD_SOURCE)
+__dso_public void _rtld_lock(int);
+#endif
+
#endif /* !defined(_DLFCN_H_) */
Index: lib/libc/gen/pthread_atfork.c
===================================================================
RCS file: /home/joerg/repo/netbsd/src/lib/libc/gen/pthread_atfork.c,v
retrieving revision 1.8
diff -u -p -r1.8 pthread_atfork.c
--- lib/libc/gen/pthread_atfork.c 28 Apr 2008 20:22:59 -0000 1.8
+++ lib/libc/gen/pthread_atfork.c 28 Mar 2011 18:56:29 -0000
@@ -36,6 +36,7 @@ __RCSID("$NetBSD: pthread_atfork.c,v 1.8
#include "namespace.h"
+#include <dlfcn.h>
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
@@ -155,7 +156,11 @@ fork(void)
SIMPLEQ_FOREACH(iter, &prepareq, next)
(*iter->fn)();
+ if (_rtld_lock_handler)
+ (*_rtld_lock_handler)(RTLD_LOCK_PRE_FORK);
ret = __fork();
+ if (_rtld_lock_handler)
+ (*_rtld_lock_handler)(RTLD_LOCK_POST_FORK);
if (ret != 0) {
/*
Index: libexec/ld.elf_so/rtld.c
===================================================================
RCS file: /home/joerg/repo/netbsd/src/libexec/ld.elf_so/rtld.c,v
retrieving revision 1.147
diff -u -p -r1.147 rtld.c
--- libexec/ld.elf_so/rtld.c 28 Mar 2011 00:37:40 -0000 1.147
+++ libexec/ld.elf_so/rtld.c 28 Mar 2011 18:50:15 -0000
@@ -1397,6 +1397,24 @@ _rtld_objlist_remove(Objlist *list, Obj_
}
}
+void
+_rtld_lock(int arg)
+{
+ switch (arg) {
+ default:
+ dbg(("%s: invalid argument: %d", __func__, arg));
+ break;
+ case RTLD_LOCK_PRE_FORK:
+ _rtld_exclusive_enter();
+ _rtld_mutex_may_recurse = true;
+ break;
+ case RTLD_LOCK_POST_FORK:
+ _rtld_mutex_may_recurse = false;
+ _rtld_exclusive_exit();
+ break;
+ }
+}
+
#define RTLD_EXCLUSIVE_MASK 0x80000000U
static volatile unsigned int _rtld_mutex;
static volatile unsigned int _rtld_waiter_exclusive;
Index: libexec/ld.elf_so/symbol.c
===================================================================
RCS file: /home/joerg/repo/netbsd/src/libexec/ld.elf_so/symbol.c,v
retrieving revision 1.56
diff -u -p -r1.56 symbol.c
--- libexec/ld.elf_so/symbol.c 12 Mar 2011 22:54:36 -0000 1.56
+++ libexec/ld.elf_so/symbol.c 28 Mar 2011 18:50:47 -0000
@@ -93,6 +93,7 @@ _rtld_is_exported(const Elf_Sym *def)
(fptr_t)dladdr,
(fptr_t)dlinfo,
(fptr_t)dl_iterate_phdr,
+ (fptr_t)_rtld_lock,
#if defined(__HAVE_TLS_VARIANT_I) || defined(__HAVE_TLS_VARIANT_II)
(fptr_t)_rtld_tls_allocate,
(fptr_t)_rtld_tls_free,
Home |
Main Index |
Thread Index |
Old Index