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>
next in thread | previous in thread | raw e-mail | index | archive | help
--liOOAslEiF7prFVr Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-Transfer-Encoding: quoted-printable On Wed, Mar 22, 2006 at 11:32:09PM +0900, Kazuaki Oda wrote: > Hello, >=20 > I compiled the following code on 6.1-PRERELEASE and ran: >=20 > dltest.c > ---------------------------------------------------------------------- > #include <err.h> > #include <dlfcn.h> > #include <pthread.h> > #include <stdio.h> > #include <stdlib.h> > #include <unistd.h> >=20 > #define NTHREADS 10 >=20 > void *func(void *dummy); >=20 > int main(void) > { > pthread_t tids[NTHREADS]; > int error; > int i; >=20 > for (i =3D 0; i < NTHREADS; i++) { > error =3D pthread_create(&tids[i], NULL, func, NULL); > if (error) > errc(1, error, "pthread_create"); > } >=20 > for (;;) > sleep(1); >=20 > /* NOTREACHED */ >=20 > exit(0); > } >=20 > void *func(void *dummy) > { > void *h; >=20 > for (;;) { > if ((h =3D dlopen("/usr/lib/libm.so", RTLD_NOW)) =3D=3D NULL) > errx(1, "dlopen: %s", dlerror()); > if (dlclose(h) =3D=3D -1) > errx(1, "dlclose: %s", dlerror()); > } >=20 > /* NOTREACHED */ >=20 > return (NULL); > } > ---------------------------------------------------------------------- >=20 > % 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) >=20 > % 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) >=20 > Hmm, it seems dlopen() and dlclose() are not MT-safe. Is this a known > issue? >=20 > -- > Kazuaki Oda The following patch put some relief for the problem: Index: libexec/rtld-elf/rtld.c = =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D 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 =3D wlock_acquire(rtld_bind_lock); + if (root->refcount =3D=3D 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. --liOOAslEiF7prFVr Content-Type: application/pgp-signature Content-Disposition: inline -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.2.2 (FreeBSD) iD8DBQFEIYyvC3+MBN1Mb4gRAqNnAJ99oSXZJu2GX6ffvlah05dtDTGqOQCg0cBw V7O5wKkm4D4gjW2NIY/R1ag= =rlPa -----END PGP SIGNATURE----- --liOOAslEiF7prFVr--
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20060322174312.GB27116>