Description
Symptoms
MSan fails to init with
MemorySanitizer: CHECK failed: sanitizer_allocator_primary64.h:133 "((kSpaceBeg)) == ((address_range.Init(TotalSpaceSize, PrimaryAllocatorName, kSpaceBeg)))" (0xe00000000000, 0xfffffffffffffff4) (tid=23879)
Environment
This is when running an MSan-instrumented aarch64 binary via qemu-aarch64
. I'm using a clang snapshot:
Debian clang version 18.0.0 (++20230829112257+96e83d3705c7-1~exp1~20230829112313.180)
People report similar issues on Raspberry Pi 4, with ASan, and with Clang 16 and Clang 17, while Clang 15 works:
- Sanitizer CHECK failed: sanitizer_allocator_primary64.h:133 google/sanitizers#1674
- Sanitizer CHECK failed: ../../.././libsanitizer/sanitizer_common/sanitizer_allocator_primary64.h:73 ((kSpaceBeg)) == ((address_range.Init(TotalSpaceSize, PrimaryAllocatorName, kSpaceBeg))) (105553116266496, -12) google/sanitizers#1329
- https://raspberrypi.stackexchange.com/questions/144012/clang-sanitizers-fail
- https://gitlab.alpinelinux.org/alpine/aports/-/issues/15025
- https://groups.google.com/g/thread-sanitizer/c/ML3IEO8Yby8 (but this one lacks details...)
So this seems to be a regression between 15 and 16.
Possible causes and fix
I have a strong suspicion that the reason for this is the commit a588cfe, but I haven't tested recompiling with -DSANITIZER_CAN_USE_ALLOCATOR64=0
.
When I use qemu's strace functionality, I get this just before the crash:
mmap(0x0000e00000000000,8192,PROT_NONE,MAP_PRIVATE|MAP_ANONYMOUS|MAP_FIXED|MAP_NORESERVE,-1,0) = -1 errno=12 (Cannot allocate memory)
And note that the value 0xfffffffffffffff4
from the assertion is equal to -12
. Here, 0x0000e00000000000
is a 48-bit address, but perhaps QEMU's emulation supports only smaller (39 bits)? [1] I suspect that the Raspberry Pi 4 also has a virtual address space smaller than 48 bits. When I try this with Clang 14, I see only mmap calls up to address 0x0000006000000000
(which is a 39-bit address).
The AArch64 memory layout on Linux can vary a lot (https://www.kernel.org/doc/html/v5.8/arm64/memory.html). Possible virtual address sizes are 39 bits, 42 bits, 48 bits, and 52 bits. Perhaps it's a good idea to detect this at runtime in the 64-bit allocator?
(note: Not sure if this is the right place to report. It seems to me that this is a compiler-rt issue, which seems to be tracked here? But please close if the existing google/sanitizers#1674 is a better place to track this.)
edit:
[1] After some more experimentation, I am not convinced that's true. I see QEMU placing the code 47-bit addresses. So I don't know why it doesn't like 0x0000e00000000000
. Its emulation of the Linux memory layout may not be perfect. I might reach out to them. But this does not change much about the validity of this bug, which still seems to occur on Raspberry Pi (without any emulation layer).