LeakSanitizer does not seem to work correctly on macOS 13.5 on Apple Silicon, and I’m wondering what changed, since I’ve been using this feature successfully on earlier macOS / Intel.
I am using open-source Clang from MacPorts, and I see the following behaviour. There are leaks reported even for a barebones C program int main(void) { return 0; }
, compiled using clang -fsanitize=address -g -fno-omit-frame-pointer
, and run with ASAN_OPTIONS=detect_leaks=1
.
With clang version 16.0.6
, I get 4 leaks reported. With clang version 15.0.7
, I see 138 leak reports. With clang version 14.0.6
, the program hangs indefinitely with 100% CPU usage when leak detection is enabled.
Leak reports look similar to the following, but I was not able to deal with them using a suppressions file in a real project, since they don’t always come from an identifiable place (libobjc.A.dylib
is mentioned here, but sometimes it’s only <unknown module>
)
Indirect leak of 16 byte(s) in 1 object(s) allocated from:
#0 0x104759ec4 in wrap_calloc+0x90 (libclang_rt.asan_osx_dynamic.dylib:arm64+0x3dec4) (BuildId: b100a6c8bcc13b048edb87902f84fa7832000000200000000100000000000b00)
#1 0x1a8592f90 in _fetchInitializingClassList(bool)+0x64 (libobjc.A.dylib:arm64+0xaf90) (BuildId: ac12887cd6983627b9d1d2e5055a5da432000000200000000100000000050d00)
#2 0x110f0001a8592e2c (<unknown module>)
#3 0x5c3d8001a8592b34 (<unknown module>)
#4 0xe4670001a859299c (<unknown module>)
#5 0x400f0001a859299c (<unknown module>)
#6 0x795a8001a859299c (<unknown module>)
#7 0x59288001a85ad0e4 (<unknown module>)
#8 0x6b790001a85925c0 (<unknown module>)
#9 0x55d0001a8591f60 (<unknown module>)
#10 0x297c8001a86641f8 (<unknown module>)
#11 0xab0b0001a86635c0 (<unknown module>)
#12 0xe4028001b42bf678 (<unknown module>)
#13 0x410a0001a85f01d4 (<unknown module>)
#14 0xe1440001a8631e90 (<unknown module>)
#15 0x98578001a86251a0 (<unknown module>)
#16 0xbc658001a85d02d4 (<unknown module>)
#17 0x18038001a86241c8 (<unknown module>)
#18 0x5c3c0001a8631954 (<unknown module>)
#19 0x5a140001a85ec858 (<unknown module>)
#20 0xe7c8001a85f5f68 (<unknown module>)
#21 0x40338001a86107f8 (<unknown module>)
#22 0xa720001a85d52cc (<unknown module>)
#23 0xfd1d8001a85d3e14 (<unknown module>)
#24 0x5320fffffffffffc (<unknown module>)
All these Clang versions worked fine on macOS 10.14.6 with an Intel processor.
As I recall, they also worked fine on macOS 13 / Intel, but I am not certain.
Questions:
Is LeakSanitizer expected to work on this platform? Is the problem I see specific to Apple Silicon? Could something be wrong with MacPorts’s Clang builds (issue report )?
Most importantly, is there a practical workaround?
I assumed that this platform may not be supported, but it is in fact stated as a supported platform for LLVM 16.0 in the documentation:
https://releases.llvm.org/16.0.0/tools/clang/docs/LeakSanitizer.html#supported-platforms
I notice that there was already a similar report on GitHub, but it did not receive much attention:
opened 02:49AM - 22 Mar 22 UTC
I am running on `Mac M1` with `clang version 13.0.1`.
When I run the leak san… itizer for example code shown in the [Clang 13 documentation](https://releases.llvm.org/13.0.0/tools/clang/docs/index.html),
```c
$ cat memory-leak.c
#include <stdlib.h>
void *p;
int main() {
p = malloc(7);
p = 0; // The memory is leaked here.
return 0;
}
$ clang -fsanitize=address -g memory-leak.c ; ASAN_OPTIONS=detect_leaks=1 ./a.out
```
the output shows that "4071 byte(s) leaked in 128 allocation(s)", with many of the leaked bytes coming from objects in the `<unknown module>`.
I also tested it against the code shown below:
```c
$ cat memory-leak.c
int main()
{
return 0;
}
$ clang -fsanitize=address -g memory-leak.c ; ASAN_OPTIONS=detect_leaks=1 ./a.out
```
It shows that "4064 byte(s) leaked in 127 allocation(s)".
It appears that by default, there are 4064 bytes leaked. The complete output of the second program is shown below.
```
==72058==ERROR: LeakSanitizer: detected memory leaks
Direct leak of 1856 byte(s) in 58 object(s) allocated from:
#0 0x1030c7a2c in wrap_calloc+0x94 (libclang_rt.asan_osx_dynamic.dylib:arm64+0x3fa2c)
#1 0x19a4be484 in realizeClassWithoutSwift(objc_class*, objc_class*)+0x8c (libobjc.A.dylib:arm64+0x5484)
#2 0x315b00019a4be608 (<unknown module>)
#3 0x7c1280019a4bc61c (<unknown module>)
#4 0x7a3000019a4baf40 (<unknown module>)
#5 0xf74c000102ce7948 (<unknown module>)
#6 0x311e800102ce2988 (<unknown module>)
#7 0x749800102ce780c (<unknown module>)
#8 0xb511000102cfc800 (<unknown module>)
#9 0x3c5580019a4bae04 (<unknown module>)
#10 0x301b00019a4754e0 (<unknown module>)
#11 0xe4880019a484cbc (<unknown module>)
#12 0x6e148001a51806a4 (<unknown module>)
#13 0xa842800102cedd8c (<unknown module>)
#14 0x732800102d1717c (<unknown module>)
#15 0x194c800102d0dbc8 (<unknown module>)
#16 0x9221800102cd9f94 (<unknown module>)
#17 0x2d1d000102d0d970 (<unknown module>)
#18 0x307a000102d16bcc (<unknown module>)
#19 0x957f800102cedccc (<unknown module>)
#20 0x5f22000102cf47c8 (<unknown module>)
#21 0x1325800102d02fe8 (<unknown module>)
#22 0x431b800102cdddb4 (<unknown module>)
#23 0xfc30000102cdd064 (<unknown module>)
#24 0x4737ffffffffffc (<unknown module>)
Direct leak of 1856 byte(s) in 58 object(s) allocated from:
#0 0x1030c7a2c in wrap_calloc+0x94 (libclang_rt.asan_osx_dynamic.dylib:arm64+0x3fa2c)
#1 0x19a4be484 in realizeClassWithoutSwift(objc_class*, objc_class*)+0x8c (libobjc.A.dylib:arm64+0x5484)
#2 0x7c1280019a4bc61c (<unknown module>)
#3 0x7a3000019a4baf40 (<unknown module>)
#4 0xf74c000102ce7948 (<unknown module>)
#5 0x311e800102ce2988 (<unknown module>)
#6 0x749800102ce780c (<unknown module>)
#7 0xb511000102cfc800 (<unknown module>)
#8 0x3c5580019a4bae04 (<unknown module>)
#9 0x301b00019a4754e0 (<unknown module>)
#10 0xe4880019a484cbc (<unknown module>)
#11 0x6e148001a51806a4 (<unknown module>)
#12 0xa842800102cedd8c (<unknown module>)
#13 0x732800102d1717c (<unknown module>)
#14 0x194c800102d0dbc8 (<unknown module>)
#15 0x9221800102cd9f94 (<unknown module>)
#16 0x2d1d000102d0d970 (<unknown module>)
#17 0x307a000102d16bcc (<unknown module>)
#18 0x957f800102cedccc (<unknown module>)
#19 0x5f22000102cf47c8 (<unknown module>)
#20 0x1325800102d02fe8 (<unknown module>)
#21 0x431b800102cdddb4 (<unknown module>)
#22 0xfc30000102cdd064 (<unknown module>)
#23 0x4737ffffffffffc (<unknown module>)
Direct leak of 160 byte(s) in 5 object(s) allocated from:
#0 0x1030c7a2c in wrap_calloc+0x94 (libclang_rt.asan_osx_dynamic.dylib:arm64+0x3fa2c)
#1 0x19a4be484 in realizeClassWithoutSwift(objc_class*, objc_class*)+0x8c (libobjc.A.dylib:arm64+0x5484)
#2 0xa15f80019a4be5f0 (<unknown module>)
#3 0x7c1280019a4bc61c (<unknown module>)
#4 0x7a3000019a4baf40 (<unknown module>)
#5 0xf74c000102ce7948 (<unknown module>)
#6 0x311e800102ce2988 (<unknown module>)
#7 0x749800102ce780c (<unknown module>)
#8 0xb511000102cfc800 (<unknown module>)
#9 0x3c5580019a4bae04 (<unknown module>)
#10 0x301b00019a4754e0 (<unknown module>)
#11 0xe4880019a484cbc (<unknown module>)
#12 0x6e148001a51806a4 (<unknown module>)
#13 0xa842800102cedd8c (<unknown module>)
#14 0x732800102d1717c (<unknown module>)
#15 0x194c800102d0dbc8 (<unknown module>)
#16 0x9221800102cd9f94 (<unknown module>)
#17 0x2d1d000102d0d970 (<unknown module>)
#18 0x307a000102d16bcc (<unknown module>)
#19 0x957f800102cedccc (<unknown module>)
#20 0x5f22000102cf47c8 (<unknown module>)
#21 0x1325800102d02fe8 (<unknown module>)
#22 0x431b800102cdddb4 (<unknown module>)
#23 0xfc30000102cdd064 (<unknown module>)
#24 0x4737ffffffffffc (<unknown module>)
Direct leak of 128 byte(s) in 4 object(s) allocated from:
#0 0x1030c7a2c in wrap_calloc+0x94 (libclang_rt.asan_osx_dynamic.dylib:arm64+0x3fa2c)
#1 0x19a4be484 in realizeClassWithoutSwift(objc_class*, objc_class*)+0x8c (libobjc.A.dylib:arm64+0x5484)
#2 0x566380019a4be608 (<unknown module>)
#3 0xa15f80019a4be5f0 (<unknown module>)
#4 0x7c1280019a4bc61c (<unknown module>)
#5 0x7a3000019a4baf40 (<unknown module>)
#6 0xf74c000102ce7948 (<unknown module>)
#7 0x311e800102ce2988 (<unknown module>)
#8 0x749800102ce780c (<unknown module>)
#9 0xb511000102cfc800 (<unknown module>)
#10 0x3c5580019a4bae04 (<unknown module>)
#11 0x301b00019a4754e0 (<unknown module>)
#12 0xe4880019a484cbc (<unknown module>)
#13 0x6e148001a51806a4 (<unknown module>)
#14 0xa842800102cedd8c (<unknown module>)
#15 0x732800102d1717c (<unknown module>)
#16 0x194c800102d0dbc8 (<unknown module>)
#17 0x9221800102cd9f94 (<unknown module>)
#18 0x2d1d000102d0d970 (<unknown module>)
#19 0x307a000102d16bcc (<unknown module>)
#20 0x957f800102cedccc (<unknown module>)
#21 0x5f22000102cf47c8 (<unknown module>)
#22 0x1325800102d02fe8 (<unknown module>)
#23 0x431b800102cdddb4 (<unknown module>)
#24 0xfc30000102cdd064 (<unknown module>)
#25 0x4737ffffffffffc (<unknown module>)
Direct leak of 32 byte(s) in 1 object(s) allocated from:
#0 0x1030c7a2c in wrap_calloc+0x94 (libclang_rt.asan_osx_dynamic.dylib:arm64+0x3fa2c)
#1 0x19a4be484 in realizeClassWithoutSwift(objc_class*, objc_class*)+0x8c (libobjc.A.dylib:arm64+0x5484)
#2 0xaa7f80019a4be5f0 (<unknown module>)
#3 0xa15f80019a4be5f0 (<unknown module>)
#4 0x7c1280019a4bc61c (<unknown module>)
#5 0x7a3000019a4baf40 (<unknown module>)
#6 0xf74c000102ce7948 (<unknown module>)
#7 0x311e800102ce2988 (<unknown module>)
#8 0x749800102ce780c (<unknown module>)
#9 0xb511000102cfc800 (<unknown module>)
#10 0x3c5580019a4bae04 (<unknown module>)
#11 0x301b00019a4754e0 (<unknown module>)
#12 0xe4880019a484cbc (<unknown module>)
#13 0x6e148001a51806a4 (<unknown module>)
#14 0xa842800102cedd8c (<unknown module>)
#15 0x732800102d1717c (<unknown module>)
#16 0x194c800102d0dbc8 (<unknown module>)
#17 0x9221800102cd9f94 (<unknown module>)
#18 0x2d1d000102d0d970 (<unknown module>)
#19 0x307a000102d16bcc (<unknown module>)
#20 0x957f800102cedccc (<unknown module>)
#21 0x5f22000102cf47c8 (<unknown module>)
#22 0x1325800102d02fe8 (<unknown module>)
#23 0x431b800102cdddb4 (<unknown module>)
#24 0xfc30000102cdd064 (<unknown module>)
#25 0x4737ffffffffffc (<unknown module>)
Direct leak of 32 byte(s) in 1 object(s) allocated from:
#0 0x1030c7a2c in wrap_calloc+0x94 (libclang_rt.asan_osx_dynamic.dylib:arm64+0x3fa2c)
#1 0x19a4be484 in realizeClassWithoutSwift(objc_class*, objc_class*)+0x8c (libobjc.A.dylib:arm64+0x5484)
#2 0xfa5b00019a4be608 (<unknown module>)
#3 0xaa7f80019a4be5f0 (<unknown module>)
#4 0xa15f80019a4be5f0 (<unknown module>)
#5 0x7c1280019a4bc61c (<unknown module>)
#6 0x7a3000019a4baf40 (<unknown module>)
#7 0xf74c000102ce7948 (<unknown module>)
#8 0x311e800102ce2988 (<unknown module>)
#9 0x749800102ce780c (<unknown module>)
#10 0xb511000102cfc800 (<unknown module>)
#11 0x3c5580019a4bae04 (<unknown module>)
#12 0x301b00019a4754e0 (<unknown module>)
#13 0xe4880019a484cbc (<unknown module>)
#14 0x6e148001a51806a4 (<unknown module>)
#15 0xa842800102cedd8c (<unknown module>)
#16 0x732800102d1717c (<unknown module>)
#17 0x194c800102d0dbc8 (<unknown module>)
#18 0x9221800102cd9f94 (<unknown module>)
#19 0x2d1d000102d0d970 (<unknown module>)
#20 0x307a000102d16bcc (<unknown module>)
#21 0x957f800102cedccc (<unknown module>)
#22 0x5f22000102cf47c8 (<unknown module>)
#23 0x1325800102d02fe8 (<unknown module>)
#24 0x431b800102cdddb4 (<unknown module>)
#25 0xfc30000102cdd064 (<unknown module>)
#26 0x4737ffffffffffc (<unknown module>)
SUMMARY: AddressSanitizer: 4064 byte(s) leaked in 127 allocation(s).
```
Let me also include an example which demonstrates that this issue can’t be worked around with suppression files:
Direct leak of 6964 byte(s) in 1 object(s) allocated from:
#0 0x102fc019c in wrap_malloc+0x88 (libclang_rt.asan_osx_dynamic.dylib:arm64+0x5019c) (BuildId: 7f28487348363def83d523cf4a8af7ae32000000200000000100000000000b00)
#1 0x1a85e1fe0 (<unknown module>)
#2 0x211d8001a8933ec8 (<unknown module>)
#3 0x677600010400b3a8 (<unknown module>)
#4 0x102b3fd54 in main dqueue.c:112
#5 0x1a85d3f24 (<unknown module>)
#6 0x49447ffffffffffc (<unknown module>)
-----------------------------------------------------
Suppressions used:
count bytes template
4 152 libobjc.A.dylib
3 148 libsystem_c.dylib
-----------------------------------------------------
SUMMARY: AddressSanitizer: 6964 byte(s) leaked in 1 allocation(s).
This comes from one of the simpler tests in the igraph library, when the library is compiled without any external dependencies.
Same result with LLVM / Clang 17.0.1.