From owner-freebsd-hackers@FreeBSD.ORG Wed Mar 22 19:07:53 2006 Return-Path: X-Original-To: hackers@freebsd.org Delivered-To: freebsd-hackers@FreeBSD.ORG Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 3F1C716A425; Wed, 22 Mar 2006 19:07:53 +0000 (UTC) (envelope-from kostikbel@gmail.com) Received: from fw.zoral.com.ua (ll-227.216.82.212.sovam.net.ua [212.82.216.227]) by mx1.FreeBSD.org (Postfix) with ESMTP id 7161E43D7F; Wed, 22 Mar 2006 19:07:34 +0000 (GMT) (envelope-from kostikbel@gmail.com) Received: from deviant.kiev.zoral.com.ua (root@deviant.kiev.zoral.com.ua [10.1.1.148]) by fw.zoral.com.ua (8.13.3/8.13.3) with ESMTP id k2MJ7SJd011203 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Wed, 22 Mar 2006 21:07:28 +0200 (EET) (envelope-from kostikbel@gmail.com) Received: from deviant.kiev.zoral.com.ua (kostik@localhost [127.0.0.1]) by deviant.kiev.zoral.com.ua (8.13.4/8.13.4) with ESMTP id k2MJ7RHo001107; Wed, 22 Mar 2006 21:07:27 +0200 (EET) (envelope-from kostikbel@gmail.com) Received: (from kostik@localhost) by deviant.kiev.zoral.com.ua (8.13.4/8.13.4/Submit) id k2MJ7PSx001106; Wed, 22 Mar 2006 21:07:25 +0200 (EET) (envelope-from kostikbel@gmail.com) X-Authentication-Warning: deviant.kiev.zoral.com.ua: kostik set sender to kostikbel@gmail.com using -f Date: Wed, 22 Mar 2006 21:07:25 +0200 From: Kostik Belousov To: Kostik Belousov Message-ID: <20060322190725.GC27116@deviant.kiev.zoral.com.ua> References: <44215FE9.2070602@highway.ne.jp> <20060322174312.GB27116@deviant.kiev.zoral.com.ua> Mime-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha1; protocol="application/pgp-signature"; boundary="bCsyhTFzCvuiizWE" Content-Disposition: inline In-Reply-To: <20060322174312.GB27116@deviant.kiev.zoral.com.ua> User-Agent: Mutt/1.4.2.1i X-Virus-Scanned: ClamAV version 0.88, clamav-milter version 0.87 on fw.zoral.com.ua X-Virus-Status: Clean X-Spam-Status: No, score=-1.4 required=5.0 tests=ALL_TRUSTED autolearn=failed version=3.1.0 X-Spam-Checker-Version: SpamAssassin 3.1.0 (2005-09-13) on fw.zoral.com.ua Cc: hackers@freebsd.org, kan@freebsd.org, Kazuaki Oda Subject: Re: dlopen() and dlclose() are not MT-safe? X-BeenThere: freebsd-hackers@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Technical Discussions relating to FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 22 Mar 2006 19:07:53 -0000 --bCsyhTFzCvuiizWE Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-Transfer-Encoding: quoted-printable On Wed, Mar 22, 2006 at 07:43:12PM +0200, Kostik Belousov wrote: > 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 > > #include > > #include > > #include > > #include > > #include > >=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 >=20 > The following patch put some relief for the problem: >=20 > 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); >=20 > /* Finish cleaning up the newly-unreferenced objects. */ >=20 >=20 > But it still allows for the mess of _init/_fini simultaneous calls > from different threads. SUSv3 does not mention constructors/destructors. Oops. Completely reversed condition in the if. :(. Also, I don't think it shall returns the error in this situation. New take: 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 19:03:12 -0000 @@ -1688,6 +1688,11 @@ wlock_release(rtld_bind_lock, lockstate); objlist_call_fini(&list_fini); lockstate =3D wlock_acquire(rtld_bind_lock); + if (root->refcount !=3D 0) { + wlock_release(rtld_bind_lock, lockstate); + return 0; + } + objlist_remove_unref(&list_fini); /* Finish cleaning up the newly-unreferenced objects. */ --bCsyhTFzCvuiizWE Content-Type: application/pgp-signature Content-Disposition: inline -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.2.2 (FreeBSD) iD8DBQFEIaBsC3+MBN1Mb4gRAr1rAJoDR1ZQ3n0+XBy06Xa9jUHVVVueEwCfdj7a jRmZF2qC7Tj88xUXv1Y4II4= =WfEu -----END PGP SIGNATURE----- --bCsyhTFzCvuiizWE--