Call __cxa_thread_finalize for the main thread.

Bug: http://b/20231984
Bug: http://b/16696563
Change-Id: I71cfddd0d404d1d4a593ec8d3bca9741de8cb90f
diff --git a/libc/Android.mk b/libc/Android.mk
index e632ee7..0dc3db7 100644
--- a/libc/Android.mk
+++ b/libc/Android.mk
@@ -63,6 +63,7 @@
     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 @@
     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 83fe3d2..10ce674 100644
--- a/libc/upstream-openbsd/lib/libc/stdlib/exit.c
+++ b/libc/stdlib/exit.c
@@ -32,8 +32,6 @@
 #include <sys/mman.h>
 #include <stdlib.h>
 #include <unistd.h>
-#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 fea60b7..59d2efd 100644
--- a/tests/__cxa_thread_atexit_test.cpp
+++ b/tests/__cxa_thread_atexit_test.cpp
@@ -50,6 +50,29 @@
   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) {