From 163ab8ba86deb991c73152e6828f270cc71dc4c5 Mon Sep 17 00:00:00 2001 From: Dmitriy Ivanov Date: Wed, 15 Apr 2015 15:31:51 -0700 Subject: [PATCH] Call __cxa_thread_finalize for the main thread. Bug: http://b/20231984 Bug: http://b/16696563 Change-Id: I71cfddd0d404d1d4a593ec8d3bca9741de8cb90f --- libc/Android.mk | 2 +- .../lib/libc => }/stdlib/exit.c | 11 +++++++-- tests/__cxa_thread_atexit_test.cpp | 23 +++++++++++++++++++ 3 files changed, 33 insertions(+), 3 deletions(-) rename libc/{upstream-openbsd/lib/libc => }/stdlib/exit.c (88%) diff --git a/libc/Android.mk b/libc/Android.mk index e632ee72f..0dc3db770 100644 --- a/libc/Android.mk +++ b/libc/Android.mk @@ -63,6 +63,7 @@ libc_common_src_files := \ stdio/sprintf.c \ stdio/stdio.c \ stdio/stdio_ext.cpp \ + stdlib/exit.c \ # Fortify implementations of libc functions. libc_common_src_files += \ @@ -480,7 +481,6 @@ libc_upstream_openbsd_ndk_src_files := \ upstream-openbsd/lib/libc/stdlib/atoi.c \ upstream-openbsd/lib/libc/stdlib/atol.c \ upstream-openbsd/lib/libc/stdlib/atoll.c \ - upstream-openbsd/lib/libc/stdlib/exit.c \ upstream-openbsd/lib/libc/stdlib/getenv.c \ upstream-openbsd/lib/libc/stdlib/insque.c \ upstream-openbsd/lib/libc/stdlib/lsearch.c \ diff --git a/libc/upstream-openbsd/lib/libc/stdlib/exit.c b/libc/stdlib/exit.c similarity index 88% rename from libc/upstream-openbsd/lib/libc/stdlib/exit.c rename to libc/stdlib/exit.c index 83fe3d2de..10ce674ab 100644 --- a/libc/upstream-openbsd/lib/libc/stdlib/exit.c +++ b/libc/stdlib/exit.c @@ -32,8 +32,6 @@ #include #include #include -#include "atexit.h" -#include "thread_private.h" /* * This variable is zero until a process has created a thread. @@ -44,12 +42,21 @@ */ int __isthreaded = 0; +/* BEGIN android-added: using __cxa_finalize and __cxa_thread_finalize */ +extern void __cxa_finalize(void* dso_handle); +extern void __cxa_thread_finalize(); +/* END android-added */ + /* * Exit, flushing stdio buffers if necessary. */ void exit(int status) { + /* BEGIN android-added: call thread_local d-tors */ + __cxa_thread_finalize(); + /* END android-added */ + /* * Call functions registered by atexit() or _cxa_atexit() * (including the stdio cleanup routine) and then _exit(). diff --git a/tests/__cxa_thread_atexit_test.cpp b/tests/__cxa_thread_atexit_test.cpp index fea60b719..59d2efd50 100644 --- a/tests/__cxa_thread_atexit_test.cpp +++ b/tests/__cxa_thread_atexit_test.cpp @@ -50,6 +50,29 @@ TEST(thread_local, smoke) { ASSERT_EQ("dtor called.", class_with_dtor_output); } +class ClassWithDtorForMainThread { + public: + void set_message(const std::string& msg) { + message = msg; + } + + ~ClassWithDtorForMainThread() { + fprintf(stderr, "%s", message.c_str()); + } + private: + std::string message; +}; + +static void thread_atexit_main() { + static thread_local ClassWithDtorForMainThread class_with_dtor_for_main_thread; + class_with_dtor_for_main_thread.set_message("d-tor for main thread called."); + exit(0); +} + +TEST(thread_local, dtor_for_main_thread) { + ASSERT_EXIT(thread_atexit_main(), testing::ExitedWithCode(0), "d-tor for main thread called."); +} + extern "C" int __cxa_thread_atexit_impl(void (*fn)(void*), void* arg, void* dso_handle); static void thread_atexit_fn1(void* arg) {