Date: Wed, 22 Mar 2006 19:43:12 +0200 From: Kostik Belousov <kostikbel@gmail.com> To: Kazuaki Oda <kaakun@highway.ne.jp> Cc: kan@freebsd.org, hackers@freebsd.org Subject: Re: dlopen() and dlclose() are not MT-safe? Message-ID: <20060322174312.GB27116@deviant.kiev.zoral.com.ua> In-Reply-To: <44215FE9.2070602@highway.ne.jp> References: <44215FE9.2070602@highway.ne.jp>
index | next in thread | previous in thread | raw e-mail
[-- Attachment #1 --]
On Wed, Mar 22, 2006 at 11:32:09PM +0900, Kazuaki Oda wrote:
> Hello,
>
> I compiled the following code on 6.1-PRERELEASE and ran:
>
> dltest.c
> ----------------------------------------------------------------------
> #include <err.h>
> #include <dlfcn.h>
> #include <pthread.h>
> #include <stdio.h>
> #include <stdlib.h>
> #include <unistd.h>
>
> #define NTHREADS 10
>
> void *func(void *dummy);
>
> int main(void)
> {
> pthread_t tids[NTHREADS];
> int error;
> int i;
>
> for (i = 0; i < NTHREADS; i++) {
> error = pthread_create(&tids[i], NULL, func, NULL);
> if (error)
> errc(1, error, "pthread_create");
> }
>
> for (;;)
> sleep(1);
>
> /* NOTREACHED */
>
> exit(0);
> }
>
> void *func(void *dummy)
> {
> void *h;
>
> for (;;) {
> if ((h = dlopen("/usr/lib/libm.so", RTLD_NOW)) == NULL)
> errx(1, "dlopen: %s", dlerror());
> if (dlclose(h) == -1)
> errx(1, "dlclose: %s", dlerror());
> }
>
> /* NOTREACHED */
>
> return (NULL);
> }
> ----------------------------------------------------------------------
>
> % cc -Wall -o dltest dltest.c -lpthread
> % ./dltest
> ld-elf.so.1: assert failed: /usr/src/libexec/rtld-elf/rtld.c:2445
> Segmentation fault (core dumped)
>
> % cc -Wall -o dltest dltest.c -lthr
> % ./dltest
> % ld-elf.so.1: assert failed: /usr/src/libexec/rtld-elf/rtld.c:1723
> Abort (core dumped)
>
> Hmm, it seems dlopen() and dlclose() are not MT-safe. Is this a known
> issue?
>
> --
> Kazuaki Oda
The following patch put some relief for the problem:
Index: libexec/rtld-elf/rtld.c ===================================================================
RCS file: /usr/local/arch/ncvs/src/libexec/rtld-elf/rtld.c,v
retrieving revision 1.112
diff -u -r1.112 rtld.c
--- libexec/rtld-elf/rtld.c 24 Dec 2005 15:37:30 -0000 1.112
+++ libexec/rtld-elf/rtld.c 22 Mar 2006 17:33:06 -0000
@@ -1688,6 +1688,12 @@
wlock_release(rtld_bind_lock, lockstate);
objlist_call_fini(&list_fini);
lockstate = wlock_acquire(rtld_bind_lock);
+ if (root->refcount == 0) {
+ _rtld_error("%s: object busy", root->path);
+ wlock_release(rtld_bind_lock, lockstate);
+ return -1;
+ }
+
objlist_remove_unref(&list_fini);
/* Finish cleaning up the newly-unreferenced objects. */
But it still allows for the mess of _init/_fini simultaneous calls
from different threads. SUSv3 does not mention constructors/destructors.
[-- Attachment #2 --]
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.2.2 (FreeBSD)
iD8DBQFEIYyvC3+MBN1Mb4gRAqNnAJ99oSXZJu2GX6ffvlah05dtDTGqOQCg0cBw
V7O5wKkm4D4gjW2NIY/R1ag=
=rlPa
-----END PGP SIGNATURE-----
help
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20060322174312.GB27116>
