Repository navigation
Guard mallopt calls when targeting API < 26 - #2343
Conversation
Details: `mallopt()` was introduced in Android Bionic in API 26. When targeting `minSdkVersion < 26`: - Without `-D__ANDROID_UNAVAILABLE_SYMBOLS_ARE_WEAK__`, `<malloc.h>` 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.
|
|
||
| #ifdef __ANDROID_NDK__ | ||
| #include <malloc.h> | ||
| extern "C" __attribute__((weak)) int mallopt(int, int); |
There was a problem hiding this comment.
Is this kind of symbol re-declaration even allowed in C++?
There was a problem hiding this comment.
this is not a definition - it's just a weak declaration
There was a problem hiding this comment.
That is what i'm asking, yes.
There was a problem hiding this comment.
it is. the attribute is an extension so not covered by the standard but this sort of redclaration is fine. it must match the original declaration exactly (does mallopt have noexcept for eg?).
| // 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) { |
There was a problem hiding this comment.
this might always evaluate true which could trigger compiler warnings/errors. we don't build android on CI so maybe confirm this?
There was a problem hiding this comment.
Why do you think this would trigger a warning? 🤔
This pattern of checking if a weak-symbol is defined is very common everywhere.
There was a problem hiding this comment.
well in the case that mallopt is defined, this is trivially always true. in the case that it's not defined it's trivially always false. we have a warning in clang on conditionals that are always trivially true or false.
There was a problem hiding this comment.
Gotcha! I've removed the nullptr checks and added the condition on the weak-decl instead.
Details:
mallopt()was introduced in Android Bionic in API 26.When targeting
minSdkVersion < 26:-D__ANDROID_UNAVAILABLE_SYMBOLS_ARE_WEAK__,<malloc.h>hides themalloptdeclaration entirely, failing to compile.-D__ANDROID_UNAVAILABLE_SYMBOLS_ARE_WEAK__,malloptis emitted as a weak symbol that resolves tonullptron devices/emulators running API < 26. In user-mode QEMU/chroot environments where/dev/__properties__is unavailable, compiler-rt's__builtin_availablefalls back to__ANDROID_API_FUTURE__(10000) and returnstrue, causing a null function pointer call at startup.Declare
malloptas a weak symbol and check&mallopt != nullptrbefore calling it.