Description
Building and running any program with LeakSanitizer or with AddressSanitizer's detect_leaks=1
shows a leak in the system library libobjc.A.dylib
on Aarch64.
I tested this in a virtual machine as well, this problem is present in at least macOS 13.5, macOS 14.7 and macOS 15.1.
It may be an actual issue in the OS (though I doubt it), but ideally LeakSanitizer should filter it out anyhow, since it's not actionable for the user.
Full backtrace on macOS 15.1 (build 24B2083)
$ echo "int main() { return 0; }" > foo.c
$ /opt/homebrew/opt/llvm/bin/clang -fsanitize=leak foo.c
$ ./a.out
a.out(5340,0x1f228bac0) malloc: nano zone abandoned due to inability to reserve vm space.
=================================================================
==5340==ERROR: LeakSanitizer: detected memory leaks
Direct leak of 72 byte(s) in 1 object(s) allocated from:
#0 0x0001030180f8 in malloc+0x60 (libclang_rt.lsan_osx_dynamic.dylib:arm64+0x340f8)
#1 0x00018cf6fa8c in _malloc_type_malloc_outlined+0x60 (libsystem_malloc.dylib:arm64+0x1ca8c)
#2 0x00018cd7aaf4 in _fetchInitializingClassList(bool)+0x34 (libobjc.A.dylib:arm64+0xaaf4)
#3 0x00018cd7a9b8 in _setThisThreadIsInitializingClass(objc_class*)+0x1c (libobjc.A.dylib:arm64+0xa9b8)
#4 0x00018cd7a7d4 in initializeNonMetaClass+0x234 (libobjc.A.dylib:arm64+0xa7d4)
#5 0x00018cd7a638 in initializeNonMetaClass+0x98 (libobjc.A.dylib:arm64+0xa638)
#6 0x00018cd7a638 in initializeNonMetaClass+0x98 (libobjc.A.dylib:arm64+0xa638)
#7 0x00018cd7a638 in initializeNonMetaClass+0x98 (libobjc.A.dylib:arm64+0xa638)
#8 0x00018cd98a38 in initializeAndMaybeRelock(objc_class*, objc_object*, locker_mixin<lockdebug::lock_mixin<objc_lock_base_t>>&, bool)+0xa0 (libobjc.A.dylib:arm64+0x28a38)
#9 0x00018cd79f94 in lookUpImpOrForward+0x12c (libobjc.A.dylib:arm64+0x9f94)
#10 0x00018cd79b80 in _objc_msgSend_uncached+0x40 (libobjc.A.dylib:arm64+0x9b80)
#11 0x00018ce4bd54 in _xpc_collect_images+0xc0 (libxpc.dylib:arm64+0x2d54)
#12 0x00018ce4b1b0 in _libxpc_initializer+0x424 (libxpc.dylib:arm64+0x21b0)
#13 0x00019ac0d634 in libSystem_initializer+0xfc (libSystem.B.dylib:arm64+0x1634)
#14 0x00018cddfd50 in invocation function for block in dyld4::Loader::findAndRunAllInitializers(dyld4::RuntimeState&) const+0x110 (dyld:arm64+0xfffffffffff57d50)
#15 0x00018ce1e4cc in invocation function for block in dyld3::MachOAnalyzer::forEachInitializer(Diagnostics&, dyld3::MachOAnalyzer::VMAddrConverter const&, void (unsigned int) block_pointer, void const*) const+0x150 (dyld:arm64+0xfffffffffff964cc)
#16 0x00018ce11c34 in invocation function for block in dyld3::MachOFile::forEachSection(void (dyld3::MachOFile::SectionInfo const&, bool, bool&) block_pointer) const+0x1ec (dyld:arm64+0xfffffffffff89c34)
#17 0x00018cdc42d8 (<unknown module>)
#18 0x00018ce10bc8 in dyld3::MachOFile::forEachSection(void (dyld3::MachOFile::SectionInfo const&, bool, bool&) block_pointer) const+0xbc (dyld:arm64+0xfffffffffff88bc8)
#19 0x00018ce1dfe0 in dyld3::MachOAnalyzer::forEachInitializer(Diagnostics&, dyld3::MachOAnalyzer::VMAddrConverter const&, void (unsigned int) block_pointer, void const*) const+0x200 (dyld:arm64+0xfffffffffff95fe0)
#20 0x00018cddfbb0 in dyld4::Loader::findAndRunAllInitializers(dyld4::RuntimeState&) const+0xac (dyld:arm64+0xfffffffffff57bb0)
#21 0x00018cdeabe4 in dyld4::PrebuiltLoader::runInitializers(dyld4::RuntimeState&) const+0x28 (dyld:arm64+0xfffffffffff62be4)
#22 0x00018cdff8b4 in dyld4::APIs::runAllInitializersForMain()+0x50 (dyld:arm64+0xfffffffffff778b4)
#23 0x00018cdc98c4 (<unknown module>)
#24 0x00018cdc8bbc (<unknown module>)
#25 0x00018cdc8058 (<unknown module>)
Indirect leak of 32 byte(s) in 1 object(s) allocated from:
#0 0x000103018354 in calloc+0x64 (libclang_rt.lsan_osx_dynamic.dylib:arm64+0x34354)
#1 0x00018cf6fb04 in _malloc_type_calloc_outlined+0x64 (libsystem_malloc.dylib:arm64+0x1cb04)
#2 0x00018cd7ab70 in _fetchInitializingClassList(bool)+0xb0 (libobjc.A.dylib:arm64+0xab70)
#3 0x00018cd7a9b8 in _setThisThreadIsInitializingClass(objc_class*)+0x1c (libobjc.A.dylib:arm64+0xa9b8)
#4 0x00018cd7a7d4 in initializeNonMetaClass+0x234 (libobjc.A.dylib:arm64+0xa7d4)
#5 0x00018cd7a638 in initializeNonMetaClass+0x98 (libobjc.A.dylib:arm64+0xa638)
#6 0x00018cd7a638 in initializeNonMetaClass+0x98 (libobjc.A.dylib:arm64+0xa638)
#7 0x00018cd7a638 in initializeNonMetaClass+0x98 (libobjc.A.dylib:arm64+0xa638)
#8 0x00018cd98a38 in initializeAndMaybeRelock(objc_class*, objc_object*, locker_mixin<lockdebug::lock_mixin<objc_lock_base_t>>&, bool)+0xa0 (libobjc.A.dylib:arm64+0x28a38)
#9 0x00018cd79f94 in lookUpImpOrForward+0x12c (libobjc.A.dylib:arm64+0x9f94)
#10 0x00018cd79b80 in _objc_msgSend_uncached+0x40 (libobjc.A.dylib:arm64+0x9b80)
#11 0x00018ce4bd54 in _xpc_collect_images+0xc0 (libxpc.dylib:arm64+0x2d54)
#12 0x00018ce4b1b0 in _libxpc_initializer+0x424 (libxpc.dylib:arm64+0x21b0)
#13 0x00019ac0d634 in libSystem_initializer+0xfc (libSystem.B.dylib:arm64+0x1634)
#14 0x00018cddfd50 in invocation function for block in dyld4::Loader::findAndRunAllInitializers(dyld4::RuntimeState&) const+0x110 (dyld:arm64+0xfffffffffff57d50)
#15 0x00018ce1e4cc in invocation function for block in dyld3::MachOAnalyzer::forEachInitializer(Diagnostics&, dyld3::MachOAnalyzer::VMAddrConverter const&, void (unsigned int) block_pointer, void const*) const+0x150 (dyld:arm64+0xfffffffffff964cc)
#16 0x00018ce11c34 in invocation function for block in dyld3::MachOFile::forEachSection(void (dyld3::MachOFile::SectionInfo const&, bool, bool&) block_pointer) const+0x1ec (dyld:arm64+0xfffffffffff89c34)
#17 0x00018cdc42d8 (<unknown module>)
#18 0x00018ce10bc8 in dyld3::MachOFile::forEachSection(void (dyld3::MachOFile::SectionInfo const&, bool, bool&) block_pointer) const+0xbc (dyld:arm64+0xfffffffffff88bc8)
#19 0x00018ce1dfe0 in dyld3::MachOAnalyzer::forEachInitializer(Diagnostics&, dyld3::MachOAnalyzer::VMAddrConverter const&, void (unsigned int) block_pointer, void const*) const+0x200 (dyld:arm64+0xfffffffffff95fe0)
#20 0x00018cddfbb0 in dyld4::Loader::findAndRunAllInitializers(dyld4::RuntimeState&) const+0xac (dyld:arm64+0xfffffffffff57bb0)
#21 0x00018cdeabe4 in dyld4::PrebuiltLoader::runInitializers(dyld4::RuntimeState&) const+0x28 (dyld:arm64+0xfffffffffff62be4)
#22 0x00018cdff8b4 in dyld4::APIs::runAllInitializersForMain()+0x50 (dyld:arm64+0xfffffffffff778b4)
#23 0x00018cdc98c4 (<unknown module>)
#24 0x00018cdc8bbc (<unknown module>)
#25 0x00018cdc8058 (<unknown module>)
Indirect leak of 16 byte(s) in 1 object(s) allocated from:
#0 0x000103018354 in calloc+0x64 (libclang_rt.lsan_osx_dynamic.dylib:arm64+0x34354)
#1 0x00018cf6fb04 in _malloc_type_calloc_outlined+0x64 (libsystem_malloc.dylib:arm64+0x1cb04)
#2 0x00018cd7ab3c in _fetchInitializingClassList(bool)+0x7c (libobjc.A.dylib:arm64+0xab3c)
#3 0x00018cd7a9b8 in _setThisThreadIsInitializingClass(objc_class*)+0x1c (libobjc.A.dylib:arm64+0xa9b8)
#4 0x00018cd7a7d4 in initializeNonMetaClass+0x234 (libobjc.A.dylib:arm64+0xa7d4)
#5 0x00018cd7a638 in initializeNonMetaClass+0x98 (libobjc.A.dylib:arm64+0xa638)
#6 0x00018cd7a638 in initializeNonMetaClass+0x98 (libobjc.A.dylib:arm64+0xa638)
#7 0x00018cd7a638 in initializeNonMetaClass+0x98 (libobjc.A.dylib:arm64+0xa638)
#8 0x00018cd98a38 in initializeAndMaybeRelock(objc_class*, objc_object*, locker_mixin<lockdebug::lock_mixin<objc_lock_base_t>>&, bool)+0xa0 (libobjc.A.dylib:arm64+0x28a38)
#9 0x00018cd79f94 in lookUpImpOrForward+0x12c (libobjc.A.dylib:arm64+0x9f94)
#10 0x00018cd79b80 in _objc_msgSend_uncached+0x40 (libobjc.A.dylib:arm64+0x9b80)
#11 0x00018ce4bd54 in _xpc_collect_images+0xc0 (libxpc.dylib:arm64+0x2d54)
#12 0x00018ce4b1b0 in _libxpc_initializer+0x424 (libxpc.dylib:arm64+0x21b0)
#13 0x00019ac0d634 in libSystem_initializer+0xfc (libSystem.B.dylib:arm64+0x1634)
#14 0x00018cddfd50 in invocation function for block in dyld4::Loader::findAndRunAllInitializers(dyld4::RuntimeState&) const+0x110 (dyld:arm64+0xfffffffffff57d50)
#15 0x00018ce1e4cc in invocation function for block in dyld3::MachOAnalyzer::forEachInitializer(Diagnostics&, dyld3::MachOAnalyzer::VMAddrConverter const&, void (unsigned int) block_pointer, void const*) const+0x150 (dyld:arm64+0xfffffffffff964cc)
#16 0x00018ce11c34 in invocation function for block in dyld3::MachOFile::forEachSection(void (dyld3::MachOFile::SectionInfo const&, bool, bool&) block_pointer) const+0x1ec (dyld:arm64+0xfffffffffff89c34)
#17 0x00018cdc42d8 (<unknown module>)
#18 0x00018ce10bc8 in dyld3::MachOFile::forEachSection(void (dyld3::MachOFile::SectionInfo const&, bool, bool&) block_pointer) const+0xbc (dyld:arm64+0xfffffffffff88bc8)
#19 0x00018ce1dfe0 in dyld3::MachOAnalyzer::forEachInitializer(Diagnostics&, dyld3::MachOAnalyzer::VMAddrConverter const&, void (unsigned int) block_pointer, void const*) const+0x200 (dyld:arm64+0xfffffffffff95fe0)
#20 0x00018cddfbb0 in dyld4::Loader::findAndRunAllInitializers(dyld4::RuntimeState&) const+0xac (dyld:arm64+0xfffffffffff57bb0)
#21 0x00018cdeabe4 in dyld4::PrebuiltLoader::runInitializers(dyld4::RuntimeState&) const+0x28 (dyld:arm64+0xfffffffffff62be4)
#22 0x00018cdff8b4 in dyld4::APIs::runAllInitializersForMain()+0x50 (dyld:arm64+0xfffffffffff778b4)
#23 0x00018cdc98c4 (<unknown module>)
#24 0x00018cdc8bbc (<unknown module>)
#25 0x00018cdc8058 (<unknown module>)
SUMMARY: LeakSanitizer: 120 byte(s) leaked in 3 allocation(s).
Same for clang -fsanitize=address foo.c && ASAN_OPTIONS=detect_leaks=1 ./a.out
.
Clang version:
Homebrew clang version 19.1.3
Target: arm64-apple-darwin24.1.0
Thread model: posix
InstalledDir: /opt/homebrew/Cellar/llvm/19.1.3/bin
Configuration file: /opt/homebrew/etc/clang/arm64-apple-darwin24.cfg
I'm using the Clang from Homebrew here, because Apple's bundled Clang does not have LeakSanitizer enabled. The problem also reproduces with the Clang from Nixpkgs, and with rustc
.
Do tell me if there's something else I can do to help resolve this!
Originally reported in rust-lang/rust#121624.
See also: