From owner-freebsd-ports@FreeBSD.ORG Thu Dec 5 17:07:44 2013 Return-Path: Delivered-To: freebsd-ports@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 1537FA9C; Thu, 5 Dec 2013 17:07:44 +0000 (UTC) Received: from kib.kiev.ua (kib.kiev.ua [IPv6:2001:470:d5e7:1::1]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.freebsd.org (Postfix) with ESMTPS id 66BED1B2F; Thu, 5 Dec 2013 17:07:43 +0000 (UTC) Received: from tom.home (kostik@localhost [127.0.0.1]) by kib.kiev.ua (8.14.7/8.14.7) with ESMTP id rB5H7ShX074741; Thu, 5 Dec 2013 19:07:28 +0200 (EET) (envelope-from kostikbel@gmail.com) DKIM-Filter: OpenDKIM Filter v2.8.3 kib.kiev.ua rB5H7ShX074741 Received: (from kostik@localhost) by tom.home (8.14.7/8.14.7/Submit) id rB5H7S9K074740; Thu, 5 Dec 2013 19:07:28 +0200 (EET) (envelope-from kostikbel@gmail.com) X-Authentication-Warning: tom.home: kostik set sender to kostikbel@gmail.com using -f Date: Thu, 5 Dec 2013 19:07:28 +0200 From: Konstantin Belousov To: Michael Gmelin Subject: Re: Position independent code and global destructor order (devel/ice) Message-ID: <20131205170728.GF59496@kib.kiev.ua> References: <6900C006-2A57-4EAF-B19A-629A85CBA001@FreeBSD.org> <20130626210534.GY91021@kib.kiev.ua> <20130626231741.497f7a9b@bsd64.grem.de> <20130626212833.GB91021@kib.kiev.ua> <20130627015602.7a437aad@bsd64.grem.de> <51CC411C.4060105@FreeBSD.org> <20130627140428.GI91021@kib.kiev.ua> <20130827144507.385a552c@bsd64.grem.de> <20131130223427.3d95ae7c@bsd64.grem.de> MIME-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha1; protocol="application/pgp-signature"; boundary="gFv5QsKiEhTTe390" Content-Disposition: inline In-Reply-To: <20131130223427.3d95ae7c@bsd64.grem.de> User-Agent: Mutt/1.5.22 (2013-10-16) X-Spam-Status: No, score=-2.0 required=5.0 tests=ALL_TRUSTED,BAYES_00, DKIM_ADSP_CUSTOM_MED,FREEMAIL_FROM,NML_ADSP_CUSTOM_MED autolearn=no version=3.3.2 X-Spam-Checker-Version: SpamAssassin 3.3.2 (2011-06-06) on tom.home Cc: David Chisnall , Brooks Davis , Dimitry Andric , Matthias Andree , "freebsd-ports@freebsd.org Ports" X-BeenThere: freebsd-ports@freebsd.org X-Mailman-Version: 2.1.17 Precedence: list List-Id: Porting software to FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 05 Dec 2013 17:07:44 -0000 --gFv5QsKiEhTTe390 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-Transfer-Encoding: quoted-printable On Sat, Nov 30, 2013 at 10:34:27PM +0100, Michael Gmelin wrote: > We discussed this topic about half a year ago, but came to no > conclusion. I CCed everyone who participated in the discussion back > then. >=20 > Since 10-RELEASE is around the corner and I'm trying to get devel/ice > working on it, one more attempt: >=20 > When -fPIC is used on objects that are linked into an executable (and > not a shared library), the static destruction order guaranteed by the > C++ standard is not followed. There is also no warning or error while > building/linking. The end-result of this problem is subtle and will > only surface on exit (at the end of runtime). When porting bigger > projects (like Ice in my case), finding all those problems is really > hard, since they're not reported at build time. It's not uncommon to > set global CFLAGS in a build, and not every projects distinguishes > between objects which will end up in shared libraries and those which > will be linked to executables directly. >=20 > In case of Ice this leads to crashes (bus error etc.) on exit, > depending on the projects the results of this could be quite severe. > The fix is to go through every Makefile of the project, basically > creating a big patch that touches everything to work around this > issue, hoping not to forget a single object file. Every user of the libra= ry > and the generated code will have to do the same in their > Makefiles/Cmakefiles/Jamfiles etc. It makes porting and using C++ code > on FreeBSD hard and software that runs fine on other platforms will > break for reasons people won't understand/will take them forever to > debug. >=20 > So is there anything that could be done to: >=20 > a) Make -fPIC just work like it did before r211706? > or if this is not an option. > b) Report an error when linking the executable, so that objects built > with -fPIC can't be used in that case/barf at compile time. >=20 > I would appreciate any kind of constructive response at this point, the > last I got was back in June: "I think that we could revert the > termination calls to the functions from the dso being unloaded, but > this is quite unfortunate, since it will restore the endless series of > 'segfault at the process termination' reports." If you provided link to the original discussion, it would take much less energy and time to refresh the memory. I looked over this, and I think that r211706 can be refined, by only calling atexit hooks for 'wrong' dso when the call to __cxa_finalize() is from the real dlclose(), as opposed to the process exit. For me, with the world where the patch is applied, your 'major tom' test passes. Of course, when dso1 registers __cxa_atexit hook located in dso2, and dso2 is unloaded before dso1, the hooks are called in the wrong order still, but the only alternatives there are either crash or do not call such hooks at all. diff --git a/include/dlfcn.h b/include/dlfcn.h index c508843..38957e2 100644 --- a/include/dlfcn.h +++ b/include/dlfcn.h @@ -53,7 +53,8 @@ #define RTLD_DI_SERINFO 4 /* Obtain search path info. */ #define RTLD_DI_SERINFOSIZE 5 /* ... query for required space. */ #define RTLD_DI_ORIGIN 6 /* Obtain object origin */ -#define RTLD_DI_MAX RTLD_DI_ORIGIN +#define RTLD_DI_GLOBALEXIT 7 +#define RTLD_DI_MAX RTLD_DI_GLOBALEXIT =20 /* * Special handle arguments for dlsym()/dlinfo(). diff --git a/lib/libc/stdlib/atexit.c b/lib/libc/stdlib/atexit.c index 18c31c3..b08d1de 100644 --- a/lib/libc/stdlib/atexit.c +++ b/lib/libc/stdlib/atexit.c @@ -37,6 +37,7 @@ static char sccsid[] =3D "@(#)atexit.c 8.2 (Berkeley) 7/3= /94"; __FBSDID("$FreeBSD$"); =20 #include "namespace.h" +#include #include #include #include @@ -162,8 +163,10 @@ __cxa_finalize(void *dso) struct dl_phdr_info phdr_info; struct atexit *p; struct atexit_fn fn; - int n, has_phdr; + int n, has_phdr, global_exit; =20 + global_exit =3D 0; + dlinfo(dso, RTLD_DI_GLOBALEXIT, &global_exit); if (dso !=3D NULL) has_phdr =3D _rtld_addr_phdr(dso, &phdr_info); else @@ -177,8 +180,9 @@ __cxa_finalize(void *dso) fn =3D p->fns[n]; if (dso !=3D NULL && dso !=3D fn.fn_dso) { /* wrong DSO ? */ - if (!has_phdr || !__elf_phdr_match_addr( - &phdr_info, fn.fn_ptr.cxa_func)) + if (!has_phdr || global_exit || + !__elf_phdr_match_addr(&phdr_info, + fn.fn_ptr.cxa_func)) continue; } /* @@ -200,6 +204,6 @@ __cxa_finalize(void *dso) if (dso =3D=3D NULL) _MUTEX_DESTROY(&atexit_mutex); =20 - if (has_phdr && &__pthread_cxa_finalize !=3D NULL) + if (has_phdr && !global_exit && &__pthread_cxa_finalize !=3D NULL) __pthread_cxa_finalize(&phdr_info); } diff --git a/libexec/rtld-elf/rtld.c b/libexec/rtld-elf/rtld.c index b55effa..7cfc95b 100644 --- a/libexec/rtld-elf/rtld.c +++ b/libexec/rtld-elf/rtld.c @@ -173,6 +173,7 @@ static char *libmap_override; /* Maps to use in additio= n to libmap.conf */ static bool trust; /* False for setuid and setgid programs */ static bool dangerous_ld_env; /* True if environment variables have been used to affect the libraries loaded */ +static bool global_exit; static char *ld_bind_now; /* Environment variable for immediate binding */ static char *ld_debug; /* Environment variable for debugging */ static char *ld_library_path; /* Environment variable for search path */ @@ -2600,6 +2601,7 @@ rtld_exit(void) =20 wlock_acquire(rtld_bind_lock, &lockstate); dbg("rtld_exit()"); + global_exit =3D true; objlist_call_fini(&list_fini, NULL, &lockstate); /* No need to remove the items from the list, since we are exiting. */ if (!libmap_disable) @@ -3197,6 +3199,12 @@ dlinfo(void *handle, int request, void *p) =20 rlock_acquire(rtld_bind_lock, &lockstate); =20 + if (request =3D=3D RTLD_DI_GLOBALEXIT) { + *(int *)p =3D global_exit; + error =3D 0; + goto out; + } + if (handle =3D=3D NULL || handle =3D=3D RTLD_SELF) { void *retaddr; =20 @@ -3207,8 +3215,8 @@ dlinfo(void *handle, int request, void *p) obj =3D dlcheck(handle); =20 if (obj =3D=3D NULL) { - lock_release(rtld_bind_lock, &lockstate); - return (-1); + error =3D -1; + goto out; } =20 error =3D 0; @@ -3230,8 +3238,8 @@ dlinfo(void *handle, int request, void *p) error =3D -1; } =20 +out: lock_release(rtld_bind_lock, &lockstate); - return (error); } =20 --gFv5QsKiEhTTe390 Content-Type: application/pgp-signature -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.22 (FreeBSD) iQIcBAEBAgAGBQJSoLLPAAoJEJDCuSvBvK1BoMIP+wWc5OpeG/SKV1Wu4AYL5S3X oKygnaOqhcU8KO+bgvDiUbPeCa/mY2CzqVEgTdnk+dwQohA7AyucuwxIhVSyWbVX UusQHA4p0BsfA3zT8mGTedsnN41sxe/mizxwtBfyDThlRnFCkd52eGukroNMpc// 31GbR0qsqZTyvlw5uhTmnOHut7heVFF+jlChp+GQpiIdmd/5vx3diwuJUj9Le3kD 0Mz62V722be/3lCtmzcvqySkY/Xc4tIqgJpC4cqHbj8ztYFT66tda2MZvJt7iEcr 9Y1gUwk38eDaxgsP1D26bSTB0r0+ge2BOiJgMECRZQ9V1/Y5On3npLjBpNMttyPS WVaVj9cc4kNyWt+//PRJiSDFG0sJsdnjyPPeDGy3mLfuclPj5qQ+/5vtX92i2Lzs Zh40fHHo9rymmakcBYzi1kTZJzfzje1A82im5stEoPZ7QvmWd5jg6D0JwljkwuhN pVscn9VqafqqtTPF6jmiD9lofFCn/tQAXi8g+Jef5HbLtvyPYFQcxV1t1MJWOMKG 78nvLB9IXaqIvOa/nibgabz5zuqVtqaJ9KsXccsIzPLn28laybFOtViqE/Z75EeY bgz6oNLvkwV3dRaIAR/bdqUiQ8ZG8zze9kpX2I0GcndxDytkr5KovISzNjjC21DD S6izEtEX38taxAlnr35r =5n3q -----END PGP SIGNATURE----- --gFv5QsKiEhTTe390--