diff options
author | kib <kib@FreeBSD.org> | 2013-12-13 05:54:30 +0000 |
---|---|---|
committer | kib <kib@FreeBSD.org> | 2013-12-13 05:54:30 +0000 |
commit | a455348768c94edff360c66f151bddaab070fb1b (patch) | |
tree | 617d08d77318daf0474b38732b94558edf0cdfde /lib/libc | |
parent | 82cc6046d52f9eac81e6aeec4898f750592c307c (diff) | |
download | FreeBSD-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/libc')
-rw-r--r-- | lib/libc/stdlib/atexit.c | 15 |
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); } |