From b153720d577dd9a32f4bf614dd7dcb337f3c3bdc Mon Sep 17 00:00:00 2001 From: Vy Nguyen Date: Mon, 19 Oct 2026 20:52:41 -0400 Subject: [PATCH 1/2] Guard mallopt calls when targeting API < 26 Details: `mallopt()` was introduced in Android Bionic in API 26. When targeting `minSdkVersion < 26`: - Without `-D__ANDROID_UNAVAILABLE_SYMBOLS_ARE_WEAK__`, `` hides the `mallopt` declaration entirely, failing to compile. - With `-D__ANDROID_UNAVAILABLE_SYMBOLS_ARE_WEAK__`, `mallopt` is emitted as a weak symbol that resolves to `nullptr` on devices/emulators running API < 26. In user-mode QEMU/chroot environments where `/dev/__properties__` is unavailable, compiler-rt's `__builtin_available` falls back to `__ANDROID_API_FUTURE__` (`10000`) and returns `true`, causing a null function pointer call at startup. Declare `mallopt` as a weak symbol and check `&mallopt != nullptr` before calling it. --- src/benchmark.cc | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/benchmark.cc b/src/benchmark.cc index 4a6789f99b..c0b195aa20 100644 --- a/src/benchmark.cc +++ b/src/benchmark.cc @@ -32,6 +32,7 @@ #ifdef __ANDROID_NDK__ #include +extern "C" __attribute__((weak)) int mallopt(int, int); #endif #ifdef BENCHMARK_OS_LINUX @@ -972,7 +973,9 @@ void Initialize(int* argc, char** argv, void (*HelperPrintf)()) { if (__builtin_available(android 31, *)) { // Not asserting on the return value, as sanitizers interpose the allocator // and always return 0 - (void)mallopt(M_BIONIC_ZERO_INIT, 0); + if (&mallopt != nullptr) { + (void)mallopt(M_BIONIC_ZERO_INIT, 0); + } } // The default configuration of bionic is to return pages to the OS as soon @@ -980,7 +983,9 @@ void Initialize(int* argc, char** argv, void (*HelperPrintf)()) { // delay before returning memory to avoid excessive faulting on repeated // allocation and deallocation, which is common in repeated benchmark runs. if (__builtin_available(android 27, *)) { - (void)mallopt(M_DECAY_TIME, 1); + if (&mallopt != nullptr) { + (void)mallopt(M_DECAY_TIME, 1); + } } #endif internal::HelperPrintf = HelperPrintf; From a154bc22f70e258c9756c008ec8556fb33e51a7a Mon Sep 17 00:00:00 2001 From: Vy Nguyen Date: Wed, 21 Oct 2026 08:53:53 -0400 Subject: [PATCH 2/2] remove nullptr check - gate on api 26 instead --- src/benchmark.cc | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/benchmark.cc b/src/benchmark.cc index c0b195aa20..e49cbdc4e0 100644 --- a/src/benchmark.cc +++ b/src/benchmark.cc @@ -32,8 +32,10 @@ #ifdef __ANDROID_NDK__ #include +#if __ANDROID_API__ < 26 extern "C" __attribute__((weak)) int mallopt(int, int); #endif +#endif #ifdef BENCHMARK_OS_LINUX #include @@ -973,9 +975,7 @@ void Initialize(int* argc, char** argv, void (*HelperPrintf)()) { if (__builtin_available(android 31, *)) { // Not asserting on the return value, as sanitizers interpose the allocator // and always return 0 - if (&mallopt != nullptr) { - (void)mallopt(M_BIONIC_ZERO_INIT, 0); - } + (void)mallopt(M_BIONIC_ZERO_INIT, 0); } // The default configuration of bionic is to return pages to the OS as soon @@ -983,9 +983,7 @@ void Initialize(int* argc, char** argv, void (*HelperPrintf)()) { // delay before returning memory to avoid excessive faulting on repeated // allocation and deallocation, which is common in repeated benchmark runs. if (__builtin_available(android 27, *)) { - if (&mallopt != nullptr) { - (void)mallopt(M_DECAY_TIME, 1); - } + (void)mallopt(M_DECAY_TIME, 1); } #endif internal::HelperPrintf = HelperPrintf;