Skip to content

[LSAN] LeakSanitizer false positive on macOS Aarch64 #115992

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
madsmtm opened this issue Nov 13, 2024 · 3 comments · May be fixed by #117478
Open

[LSAN] LeakSanitizer false positive on macOS Aarch64 #115992

madsmtm opened this issue Nov 13, 2024 · 3 comments · May be fixed by #117478
Labels
compiler-rt:lsan Leak sanitizer false-positive Warning fires when it should not platform:macos

Comments

@madsmtm
Copy link
Contributor

madsmtm commented Nov 13, 2024

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:

@madsmtm madsmtm changed the title [LSAN] LeakSanitizer false positive on macOS [LSAN] LeakSanitizer false positive on macOS Aarch64 Nov 13, 2024
@EugeneZelenko EugeneZelenko added platform:macos compiler-rt:lsan Leak sanitizer false-positive Warning fires when it should not and removed new issue labels Nov 13, 2024
@madsmtm
Copy link
Contributor Author

madsmtm commented Nov 16, 2024

Not sure if this is the right way to do it, but CC @vitalybuka in case you know something?

It would be nice to get this fixed so that we can release LeakSanitizer on aarch64-apple-darwin as well in rust-lang/rust#123617.

@vitalybuka vitalybuka assigned vitalybuka and unassigned vitalybuka Nov 24, 2024
@vitalybuka
Copy link
Collaborator

There is https://github.com/google/sanitizers/wiki/AddressSanitizerLeakSanitizer#suppressions
and also https://github.com/llvm/llvm-project/blob/4d4a353b8eddb0728d5b278befdccda4de484319/compiler-rt/include/sanitizer/lsan_interface.h#L76C29-L76C56

For permanent solution maybe

However I don't work on OSX, and I am not sure if permanent suppression is appropriate solution.

CC @wrotki @yln If you know who is interested in lsan at Apple.

@madsmtm madsmtm linked a pull request Nov 24, 2024 that will close this issue
@madsmtm
Copy link
Contributor Author

madsmtm commented Nov 24, 2024

Thanks for the pointers. I've opened #117478 to fix it that way, but still interested to hear from the others if there's a better way!

whalbawi added a commit to whalbawi/axle that referenced this issue Jan 24, 2025
This is done by passing special options to ASAN. However; a suppression
file is required for this platform as there is what seems to be a false
positive coming from an OS library:
llvm/llvm-project#115992
whalbawi added a commit to whalbawi/axle that referenced this issue Jan 24, 2025
This is done by passing special options to ASAN. However; a suppression
file is required for this platform as there is what seems to be a false
positive coming from an OS library:
llvm/llvm-project#115992
whalbawi added a commit to whalbawi/axle that referenced this issue Jan 24, 2025
This is done by passing special options to ASAN. However; a suppression
file is required for this platform as there is what seems to be a false
positive coming from an OS library:
llvm/llvm-project#115992

PR: #17
whalbawi added a commit to whalbawi/axle that referenced this issue Jan 24, 2025
This is done by passing special options to ASAN. However; a suppression
file is required for this platform as there is what seems to be a false
positive coming from an OS library:
llvm/llvm-project#115992

PR: #17
whalbawi added a commit to whalbawi/axle that referenced this issue Jan 24, 2025
This is done by passing special options to ASAN. However; a suppression
file is required for this platform as there is what seems to be a false
positive coming from an OS library:
llvm/llvm-project#115992

PR: #17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
compiler-rt:lsan Leak sanitizer false-positive Warning fires when it should not platform:macos
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants