summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorkib <kib@FreeBSD.org>2013-12-13 05:54:30 +0000
committerkib <kib@FreeBSD.org>2013-12-13 05:54:30 +0000
commita455348768c94edff360c66f151bddaab070fb1b (patch)
tree617d08d77318daf0474b38732b94558edf0cdfde /lib
parent82cc6046d52f9eac81e6aeec4898f750592c307c (diff)
downloadFreeBSD-src-a455348768c94edff360c66f151bddaab070fb1b.zip
FreeBSD-src-a455348768c94edff360c66f151bddaab070fb1b.tar.gz
MFC r259042:
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).
Diffstat (limited to 'lib')
-rw-r--r--lib/libc/stdlib/atexit.c15
1 files changed, 10 insertions, 5 deletions
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);
}
OpenPOWER on IntegriCloud