Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 5 Dec 2013 19:07:28 +0200
From:      Konstantin Belousov <kostikbel@gmail.com>
To:        Michael Gmelin <freebsd@grem.de>
Cc:        David Chisnall <theraven@freebsd.org>, Brooks Davis <brooks@FreeBSD.org>, Dimitry Andric <dim@FreeBSD.org>, Matthias Andree <mandree@FreeBSD.org>, "freebsd-ports@freebsd.org Ports" <freebsd-ports@freebsd.org>
Subject:   Re: Position independent code and global destructor order (devel/ice)
Message-ID:  <20131205170728.GF59496@kib.kiev.ua>
In-Reply-To: <20131130223427.3d95ae7c@bsd64.grem.de>
References:  <6900C006-2A57-4EAF-B19A-629A85CBA001@FreeBSD.org> <20130626210534.GY91021@kib.kiev.ua> <A60BFADA-E358-4363-8BED-E154AB327C6B@FreeBSD.org> <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>

next in thread | previous in thread | raw e-mail | index | archive | help

--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 <dlfcn.h>
 #include <link.h>
 #include <stddef.h>
 #include <stdlib.h>
@@ -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--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20131205170728.GF59496>