diff --git a/libc/Android.mk b/libc/Android.mk index 78b847584..e06a86056 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 83aab53cc..e388f3b62 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) {