Remove gMallocLeakZygoteChild.

Remove this global variable and change the setting of it to non-zero
to a call to android_mallopt.

In addition, change the initialize function to use pass a bool* instead of
int*.

Bug: 130028357

Test: Ran malloc_debug/malloc_hooks/perfetto tests.
Change-Id: I20d382bdeaaf38aac6b9dcabea5b3dfab3c945f6
Merged-In: I20d382bdeaaf38aac6b9dcabea5b3dfab3c945f6
(cherry picked from commit 5225b342f0810c027df3d09fbbcef4d324b19b93)
diff --git a/libc/bionic/malloc_common.cpp b/libc/bionic/malloc_common.cpp
index f817281..3f1bcc3 100644
--- a/libc/bionic/malloc_common.cpp
+++ b/libc/bionic/malloc_common.cpp
@@ -60,9 +60,6 @@
 void* (*volatile __realloc_hook)(void*, size_t, const void*);
 void (*volatile __free_hook)(void*, const void*);
 void* (*volatile __memalign_hook)(size_t, size_t, const void*);
-
-// In a VM process, this is set to 1 after fork()ing out of zygote.
-int gMallocLeakZygoteChild = 0;
 // =============================================================================
 
 // =============================================================================
diff --git a/libc/bionic/malloc_common.h b/libc/bionic/malloc_common.h
index 7f3b711..2176e63 100644
--- a/libc/bionic/malloc_common.h
+++ b/libc/bionic/malloc_common.h
@@ -69,7 +69,7 @@
 
 #endif
 
-extern int gMallocLeakZygoteChild;
+extern bool gZygoteChild;
 
 static inline const MallocDispatch* GetDispatchTable() {
   return atomic_load_explicit(&__libc_globals->current_dispatch_table, memory_order_acquire);
diff --git a/libc/bionic/malloc_common_dynamic.cpp b/libc/bionic/malloc_common_dynamic.cpp
index e7147a0..64f9f6f 100644
--- a/libc/bionic/malloc_common_dynamic.cpp
+++ b/libc/bionic/malloc_common_dynamic.cpp
@@ -46,6 +46,7 @@
 //   write_malloc_leak_info: Writes the leak info data to a file.
 
 #include <dlfcn.h>
+#include <errno.h>
 #include <fcntl.h>
 #include <pthread.h>
 #include <stdatomic.h>
@@ -73,6 +74,8 @@
 // =============================================================================
 pthread_mutex_t gGlobalsMutateLock = PTHREAD_MUTEX_INITIALIZER;
 
+bool gZygoteChild = false;
+
 _Atomic bool gGlobalsMutating = false;
 // =============================================================================
 
@@ -112,7 +115,7 @@
 static constexpr char kDebugEnvOptions[] = "LIBC_DEBUG_MALLOC_OPTIONS";
 
 typedef void (*finalize_func_t)();
-typedef bool (*init_func_t)(const MallocDispatch*, int*, const char*);
+typedef bool (*init_func_t)(const MallocDispatch*, bool*, const char*);
 typedef void (*get_malloc_leak_info_func_t)(uint8_t**, size_t*, size_t*, size_t*, size_t*);
 typedef void (*free_malloc_leak_info_func_t)(uint8_t*);
 typedef bool (*write_malloc_leak_info_func_t)(FILE*);
@@ -329,7 +332,7 @@
 
 bool FinishInstallHooks(libc_globals* globals, const char* options, const char* prefix) {
   init_func_t init_func = reinterpret_cast<init_func_t>(gFunctions[FUNC_INITIALIZE]);
-  if (!init_func(&__libc_malloc_default_dispatch, &gMallocLeakZygoteChild, options)) {
+  if (!init_func(&__libc_malloc_default_dispatch, &gZygoteChild, options)) {
     error_log("%s: failed to enable malloc %s", getprogname(), prefix);
     ClearGlobalFunctions();
     return false;
@@ -470,6 +473,14 @@
 // Platform-internal mallopt variant.
 // =============================================================================
 extern "C" bool android_mallopt(int opcode, void* arg, size_t arg_size) {
+  if (opcode == M_SET_ZYGOTE_CHILD) {
+    if (arg != nullptr || arg_size != 0) {
+      errno = EINVAL;
+      return false;
+    }
+    gZygoteChild = true;
+    return true;
+  }
   if (opcode == M_SET_ALLOCATION_LIMIT_BYTES) {
     return LimitEnable(arg, arg_size);
   }
diff --git a/libc/bionic/malloc_heapprofd.cpp b/libc/bionic/malloc_heapprofd.cpp
index eda54ce..2aeb9bf 100644
--- a/libc/bionic/malloc_heapprofd.cpp
+++ b/libc/bionic/malloc_heapprofd.cpp
@@ -81,10 +81,10 @@
 
 // In a Zygote child process, this is set to true if profiling of this process
 // is allowed. Note that this is set at a later time than the global
-// gMallocLeakZygoteChild. The latter is set during the fork (while still in
+// gZygoteChild. The latter is set during the fork (while still in
 // zygote's SELinux domain). While this bit is set after the child is
 // specialized (and has transferred SELinux domains if applicable).
-static _Atomic bool gMallocZygoteChildProfileable = false;
+static _Atomic bool gZygoteChildProfileable = false;
 
 extern "C" void* MallocInitHeapprofdHook(size_t);
 
@@ -114,8 +114,8 @@
 
 static void MaybeInstallInitHeapprofdHook(int) {
   // Zygote child processes must be marked profileable.
-  if (gMallocLeakZygoteChild &&
-      !atomic_load_explicit(&gMallocZygoteChildProfileable, memory_order_acquire)) {
+  if (gZygoteChild &&
+      !atomic_load_explicit(&gZygoteChildProfileable, memory_order_acquire)) {
     return;
   }
 
@@ -326,7 +326,7 @@
 
 // Marks this process as a profileable zygote child.
 static bool HandleInitZygoteChildProfiling() {
-  atomic_store_explicit(&gMallocZygoteChildProfileable, true, memory_order_release);
+  atomic_store_explicit(&gZygoteChildProfileable, true, memory_order_release);
 
   // Conditionally start "from startup" profiling.
   if (HeapprofdShouldLoad()) {
diff --git a/libc/libc.map.txt b/libc/libc.map.txt
index e094967..55ca9dc 100644
--- a/libc/libc.map.txt
+++ b/libc/libc.map.txt
@@ -1483,7 +1483,6 @@
 
     # Used by libandroid_runtime and libmedia
     android_mallopt; # apex
-    gMallocLeakZygoteChild; # apex
 } LIBC_P;
 
 LIBC_PRIVATE {
diff --git a/libc/malloc_debug/PointerData.h b/libc/malloc_debug/PointerData.h
index 24ca748..c7958f3 100644
--- a/libc/malloc_debug/PointerData.h
+++ b/libc/malloc_debug/PointerData.h
@@ -44,7 +44,7 @@
 #include "OptionData.h"
 #include "UnwindBacktrace.h"
 
-extern int* g_malloc_zygote_child;
+extern bool* g_zygote_child;
 
 // Forward declarations.
 class Config;
@@ -89,7 +89,9 @@
   size_t hash_index;
   size_t RealSize() const { return size & ~(1U << 31); }
   bool ZygoteChildAlloc() const { return size & (1U << 31); }
-  static size_t GetEncodedSize(size_t size) { return GetEncodedSize(*g_malloc_zygote_child, size); }
+  static size_t GetEncodedSize(size_t size) {
+    return GetEncodedSize(*g_zygote_child, size);
+  }
   static size_t GetEncodedSize(bool child_alloc, size_t size) {
     return size | ((child_alloc) ? (1U << 31) : 0);
   }
diff --git a/libc/malloc_debug/malloc_debug.cpp b/libc/malloc_debug/malloc_debug.cpp
index 1145796..91e1d26 100644
--- a/libc/malloc_debug/malloc_debug.cpp
+++ b/libc/malloc_debug/malloc_debug.cpp
@@ -58,7 +58,7 @@
 // ------------------------------------------------------------------------
 DebugData* g_debug;
 
-int* g_malloc_zygote_child;
+bool* g_zygote_child;
 
 const MallocDispatch* g_dispatch;
 // ------------------------------------------------------------------------
@@ -70,7 +70,7 @@
 // ------------------------------------------------------------------------
 __BEGIN_DECLS
 
-bool debug_initialize(const MallocDispatch* malloc_dispatch, int* malloc_zygote_child,
+bool debug_initialize(const MallocDispatch* malloc_dispatch, bool* malloc_zygote_child,
                       const char* options);
 void debug_finalize();
 void debug_dump_heap(const char* file_name);
@@ -225,15 +225,15 @@
   return g_debug->GetPointer(header);
 }
 
-bool debug_initialize(const MallocDispatch* malloc_dispatch, int* malloc_zygote_child,
+bool debug_initialize(const MallocDispatch* malloc_dispatch, bool* zygote_child,
                       const char* options) {
-  if (malloc_zygote_child == nullptr || options == nullptr) {
+  if (zygote_child == nullptr || options == nullptr) {
     return false;
   }
 
   InitAtfork();
 
-  g_malloc_zygote_child = malloc_zygote_child;
+  g_zygote_child = zygote_child;
 
   g_dispatch = malloc_dispatch;
 
diff --git a/libc/malloc_debug/tests/malloc_debug_unit_tests.cpp b/libc/malloc_debug/tests/malloc_debug_unit_tests.cpp
index f611f3d..0238d10 100644
--- a/libc/malloc_debug/tests/malloc_debug_unit_tests.cpp
+++ b/libc/malloc_debug/tests/malloc_debug_unit_tests.cpp
@@ -50,7 +50,7 @@
 
 __BEGIN_DECLS
 
-bool debug_initialize(const MallocDispatch*, int*, const char*);
+bool debug_initialize(const MallocDispatch*, bool*, const char*);
 void debug_finalize();
 
 void* debug_malloc(size_t);
@@ -103,8 +103,8 @@
   }
 
   void Init(const char* options) {
-    zygote = 0;
-    ASSERT_TRUE(debug_initialize(&dispatch, &zygote, options));
+    zygote_child = false;
+    ASSERT_TRUE(debug_initialize(&dispatch, &zygote_child, options));
     initialized = true;
   }
 
@@ -116,7 +116,7 @@
 
   bool initialized;
 
-  int zygote;
+  bool zygote_child;
 
   static MallocDispatch dispatch;
 };
@@ -1344,7 +1344,7 @@
   backtrace_fake_add(std::vector<uintptr_t> {0xa300, 0xb300});
 
   std::vector<void*> pointers;
-  zygote = 1;
+  zygote_child = true;
   pointers.push_back(debug_malloc(100));
   ASSERT_TRUE(pointers.back() != nullptr);
   pointers.push_back(debug_malloc(40));
@@ -1352,7 +1352,7 @@
   pointers.push_back(debug_malloc(200));
   ASSERT_TRUE(pointers.back() != nullptr);
 
-  zygote = 0;
+  zygote_child = false;
   pointers.push_back(debug_malloc(10));
   ASSERT_TRUE(pointers.back() != nullptr);
   pointers.push_back(debug_malloc(50));
@@ -1750,7 +1750,7 @@
   backtrace_fake_add(std::vector<uintptr_t> {0xbc000, 0xecd00, 0x12000});
   backtrace_fake_add(std::vector<uintptr_t> {0xbc000});
 
-  zygote = 1;
+  zygote_child = true;
 
   void* pointers[4];
   pointers[0] = debug_malloc(100);
@@ -1809,14 +1809,14 @@
   backtrace_fake_add(std::vector<uintptr_t> {0xbc000, 0xecd00, 0x12000});
   backtrace_fake_add(std::vector<uintptr_t> {0xbc000});
 
-  zygote = 1;
+  zygote_child = true;
   void* pointers[4];
   pointers[0] = debug_malloc(40);
   ASSERT_TRUE(pointers[0] != nullptr);
   pointers[1] = debug_malloc(40);
   ASSERT_TRUE(pointers[1] != nullptr);
 
-  zygote = 0;
+  zygote_child = false;
   pointers[2] = debug_malloc(40);
   ASSERT_TRUE(pointers[2] != nullptr);
   pointers[3] = debug_malloc(100);
@@ -1989,7 +1989,7 @@
   // Set all of the options.
   Init("guard fill backtrace leak_track free_track=2");
 
-  zygote = 1;
+  zygote_child = true;
 
   backtrace_fake_add(std::vector<uintptr_t> {0x1});
 
diff --git a/libc/malloc_hooks/malloc_hooks.cpp b/libc/malloc_hooks/malloc_hooks.cpp
index 07b668f..b1c1d50 100644
--- a/libc/malloc_hooks/malloc_hooks.cpp
+++ b/libc/malloc_hooks/malloc_hooks.cpp
@@ -48,7 +48,7 @@
 // ------------------------------------------------------------------------
 __BEGIN_DECLS
 
-bool hooks_initialize(const MallocDispatch* malloc_dispatch, int* malloc_zygote_child,
+bool hooks_initialize(const MallocDispatch* malloc_dispatch, bool* zygote_child,
     const char* options);
 void hooks_finalize();
 void hooks_get_malloc_leak_info(
@@ -97,7 +97,7 @@
 __END_DECLS
 // ------------------------------------------------------------------------
 
-bool hooks_initialize(const MallocDispatch* malloc_dispatch, int*, const char*) {
+bool hooks_initialize(const MallocDispatch* malloc_dispatch, bool*, const char*) {
   g_dispatch = malloc_dispatch;
   __malloc_hook = default_malloc_hook;
   __realloc_hook = default_realloc_hook;
diff --git a/libc/private/bionic_malloc.h b/libc/private/bionic_malloc.h
index a1744aa..e8a6f6e 100644
--- a/libc/private/bionic_malloc.h
+++ b/libc/private/bionic_malloc.h
@@ -45,6 +45,9 @@
   //   arg_size = sizeof(size_t)
   M_SET_ALLOCATION_LIMIT_BYTES = 3,
 #define M_SET_ALLOCATION_LIMIT_BYTES M_SET_ALLOCATION_LIMIT_BYTES
+  // Called after the zygote forks to indicate this is a child.
+  M_SET_ZYGOTE_CHILD = 4,
+#define M_SET_ZYGOTE_CHILD M_SET_ZYGOTE_CHILD
 };
 
 // Manipulates bionic-specific handling of memory allocation APIs such as
diff --git a/libc/symbol_ordering b/libc/symbol_ordering
index 10245db..c04692b 100644
--- a/libc/symbol_ordering
+++ b/libc/symbol_ordering
@@ -27,7 +27,7 @@
 restartloop
 _ZL24gHeapprofdInitInProgress
 _ZL27gHeapprofdInitHookInstalled
-_ZL29gMallocZygoteChildProfileable
+_ZL23gZygoteChildProfileable
 _ZZ17__find_icu_symbolPKcE9found_icu
 ru_a
 ru_b
@@ -55,7 +55,6 @@
 g_atexit_lock
 gGlobalsMutateLock
 global_hashtable
-gMallocLeakZygoteChild
 gmtptr
 handlers
 je_background_thread_info