After digging into Apple's libmalloc source code, I found the offending function nano_malloc
. You can view the code at Apple's open source site here.
As you can see from the code, nano_malloc
call nano_preallocate_band_vm
to pre-allocate a certain amount of heap memory (for optimization purpose, I guess). If the kernel does not return an address at exactly NANOZONE_SIGNATURE
(0x6 << 44), nano_preallocate_band_vm
report failure ==> nano_init
print out the message.
Unlike Linux community, Apple does not comment on their internal implementations, so I do not have any authoritative answer. But here is my hypothesis:
- Libmalloc preallocate memory for optimization purpose only ==> Failed to do so does not affect the result of any program.
- Address/Thread sanitizers allocate their data structures before libmalloc does ==> libmalloc can not acquire a memory chunk at the exact address as it expect ==> failed to pre-allocate.
Regardless, as the source code shows, Apple give you 2 ways to turn off this warnings:
- Undef
NANO_PREALLOCATE_BAND_VM
(only viable if you compile libmalloc from source)
- Set the environment variable
MallocNanoZone
to 0.
I did try the 2nd option and success.
FYI, It's not Xcode or Swift's specific problem. I compiled C/C++ code with Address Sanitizer clang -fsanitize=address -o main main.c
, the program emit exactly the same warning and the same solution worked.
My tools' version for future reference:
$ clang --version
Apple clang version 13.0.0 (clang-1300.0.29.3)
Target: x86_64-apple-darwin21.1.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
$ sw_vers
ProductName: macOS
ProductVersion: 12.0.1
BuildVersion: 21A559