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()) {