From 44b7f6b41bc428f56c93d61b9ce9f618fb29c982 Mon Sep 17 00:00:00 2001 From: kib Date: Fri, 6 Dec 2013 21:26:57 +0000 Subject: Do not force to run atexit handlers, which text comes from a dso owning the handle passed to __cxa_finalize() but which are registered by other dso, when the process is inside exit(3). Running them makes the destruction order wrong, and there is hope that such destructors would not call dlclose(3), since it is pointless at this stage of the process existence. The change effectively disables the r211706 after the exit(3) is called. Reported and tested by: Michael Gmelin Analyzed by: dim Sponsored by: The FreeBSD Foundation MFC after: 1 week --- lib/libc/stdlib/atexit.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) (limited to 'lib/libc/stdlib') diff --git a/lib/libc/stdlib/atexit.c b/lib/libc/stdlib/atexit.c index 18c31c3..01d09fe 100644 --- a/lib/libc/stdlib/atexit.c +++ b/lib/libc/stdlib/atexit.c @@ -151,6 +151,8 @@ __cxa_atexit(void (*func)(void *), void *arg, void *dso) #pragma weak __pthread_cxa_finalize void __pthread_cxa_finalize(const struct dl_phdr_info *); +static int global_exit; + /* * Call all handlers registered with __cxa_atexit for the shared * object owning 'dso'. Note: if 'dso' is NULL, then all remaining @@ -164,10 +166,12 @@ __cxa_finalize(void *dso) struct atexit_fn fn; int n, has_phdr; - if (dso != NULL) + if (dso != NULL) { has_phdr = _rtld_addr_phdr(dso, &phdr_info); - else + } else { has_phdr = 0; + global_exit = 1; + } _MUTEX_LOCK(&atexit_mutex); for (p = __atexit; p; p = p->next) { @@ -177,8 +181,9 @@ __cxa_finalize(void *dso) fn = p->fns[n]; if (dso != NULL && dso != 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 +205,6 @@ __cxa_finalize(void *dso) if (dso == NULL) _MUTEX_DESTROY(&atexit_mutex); - if (has_phdr && &__pthread_cxa_finalize != NULL) + if (has_phdr && !global_exit && &__pthread_cxa_finalize != NULL) __pthread_cxa_finalize(&phdr_info); } -- cgit v1.1