malloc_debug: reset TrackData mutex after fork

Add a pthread_atfork handler to malloc_debug to lock the TrackData mutex
during fork and reset it in the child.  Ensures that the TrackData is
consistent when forking from a multi-threaded process, and that the
mutex is in a defined state in the child.

Bug: 27208635
(cherry picked from commit 7a28a3cf1f8df36e30724e8b4021cddde0596118)

Change-Id: I84bc67be09b8b767e1cf2f14141e2ae8dc4fb462
diff --git a/libc/malloc_debug/malloc_debug.cpp b/libc/malloc_debug/malloc_debug.cpp
index 0c0907d..dcc6048 100644
--- a/libc/malloc_debug/malloc_debug.cpp
+++ b/libc/malloc_debug/malloc_debug.cpp
@@ -85,6 +85,28 @@
 __END_DECLS
 // ------------------------------------------------------------------------
 
+static void InitAtfork() {
+  static pthread_once_t atfork_init = PTHREAD_ONCE_INIT;
+  pthread_once(&atfork_init, [](){
+    pthread_atfork(
+        [](){
+          if (g_debug != nullptr) {
+            g_debug->PrepareFork();
+          }
+        },
+        [](){
+          if (g_debug != nullptr) {
+            g_debug->PostForkParent();
+          }
+        },
+        [](){
+          if (g_debug != nullptr) {
+            g_debug->PostForkChild();
+          }
+        }
+    );
+  });
+}
 static void LogTagError(const Header* header, const void* pointer, const char* name) {
   ScopedDisableDebugCalls disable;
 
@@ -156,6 +178,9 @@
   if (malloc_zygote_child == nullptr) {
     return false;
   }
+
+  InitAtfork();
+
   g_malloc_zygote_child = malloc_zygote_child;
 
   g_dispatch = malloc_dispatch;