[compiler-rt] [sanitizer_common][tsan] Improve message for unsupported vm config on Apple platforms (PR #158665)
Andrew Haberlandt via llvm-commits
llvm-commits at lists.llvm.org
Tue Sep 16 17:09:57 PDT 2025
https://github.com/ndrewh updated https://github.com/llvm/llvm-project/pull/158665
>From 92ac79c6dc0c44016b4cb79246eec194248f785e Mon Sep 17 00:00:00 2001
From: Andrew Haberlandt <ahaberlandt at apple.com>
Date: Fri, 12 Sep 2025 16:40:20 -0700
Subject: [PATCH 1/2] [sanitizer_common][tsan] Improve message for unsupported
vm config
An existing log message is triggered in InitializePlatformEarly if
the address space max is not as sufficient for TSAN.
Some platforms expand the address space limit, but reserve much
of the space TSAN needs. Therefore, we now check that the kernel
has not mapped over the address space that we intend to use.
IsAddressInMappedRegion is added to sanitizer_common. This introduces
a new dependency on mach_vm_region_recurse during TSAN startup, so this
intentionally fails softly (to avoid breaking current users who
may be in a sandbox that doesn't allow this).
rdar://135265279
---
.../lib/sanitizer_common/sanitizer_mac.cpp | 23 +++++++++++++++++++
.../lib/sanitizer_common/sanitizer_mac.h | 2 ++
.../lib/tsan/rtl/tsan_platform_mac.cpp | 16 ++++++++++---
3 files changed, 38 insertions(+), 3 deletions(-)
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_mac.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_mac.cpp
index d4811ff4ed217..bf861063ca1f5 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_mac.cpp
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_mac.cpp
@@ -1298,6 +1298,29 @@ uptr FindAvailableMemoryRange(uptr size, uptr alignment, uptr left_padding,
return 0;
}
+// Returns true if the address is definitely mapped, and false if it is not
+// mapped or could not be determined.
+bool IsAddressInMappedRegion(uptr addr) {
+ mach_vm_size_t vmsize = 0;
+ natural_t depth = 0;
+ vm_region_submap_short_info_data_64_t vminfo;
+ mach_msg_type_number_t count = VM_REGION_SUBMAP_SHORT_INFO_COUNT_64;
+ mach_vm_address_t address = addr;
+
+ kern_return_t kr =
+ mach_vm_region_recurse(mach_task_self(), &address, &vmsize, &depth,
+ (vm_region_info_t)&vminfo, &count);
+
+ if (kr == KERN_DENIED) {
+ Report(
+ "WARN: mach_vm_region_recurse returned KERN_DENIED when checking "
+ "whether an address is mapped.\n");
+ Report("HINT: Is mach_vm_region_recurse allowed by sandbox?\n");
+ }
+
+ return (kr == KERN_SUCCESS && addr >= address && addr < address + vmsize);
+}
+
// FIXME implement on this platform.
void GetMemoryProfile(fill_profile_f cb, uptr *stats) {}
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_mac.h b/compiler-rt/lib/sanitizer_common/sanitizer_mac.h
index b0e4ac7f40745..789dd8e4d8e9c 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_mac.h
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_mac.h
@@ -76,6 +76,8 @@ struct ThreadEventCallbacks {
void InstallPthreadIntrospectionHook(const ThreadEventCallbacks &callbacks);
+bool IsAddressInMappedRegion(uptr addr);
+
} // namespace __sanitizer
#endif // SANITIZER_APPLE
diff --git a/compiler-rt/lib/tsan/rtl/tsan_platform_mac.cpp b/compiler-rt/lib/tsan/rtl/tsan_platform_mac.cpp
index eb344df168ab9..84dfe999045f9 100644
--- a/compiler-rt/lib/tsan/rtl/tsan_platform_mac.cpp
+++ b/compiler-rt/lib/tsan/rtl/tsan_platform_mac.cpp
@@ -226,9 +226,19 @@ static void ThreadTerminateCallback(uptr thread) {
void InitializePlatformEarly() {
# if !SANITIZER_GO && SANITIZER_IOS
uptr max_vm = GetMaxUserVirtualAddress() + 1;
- if (max_vm != HiAppMemEnd()) {
- Printf("ThreadSanitizer: unsupported vm address limit %p, expected %p.\n",
- (void *)max_vm, (void *)HiAppMemEnd());
+ if (max_vm < HiAppMemEnd()) {
+ Printf(
+ "ThreadSanitizer: Unsupported virtual memory layout:\n\tVM address "
+ "limit = %p\n\tExpected %p.\n",
+ (void*)max_vm, (void*)HiAppMemEnd());
+ Die();
+ }
+ // In some configurations, the max_vm is expanded, but much of this space is
+ // already mapped. TSAN will not work in this configuration.
+ else if (IsAddressInMappedRegion(HiAppMemEnd() - 1)) {
+ Printf(
+ "ThreadSanitizer: Unsupported virtual memory layout: Address %p is "
+ "already mapped.\n");
Die();
}
#endif
>From 1311d989d17c4c7e47363ee2569bfed53bcc548c Mon Sep 17 00:00:00 2001
From: Andrew Haberlandt <ahaberlandt at apple.com>
Date: Tue, 16 Sep 2025 17:08:56 -0700
Subject: [PATCH 2/2] nits
---
compiler-rt/lib/tsan/rtl/tsan_platform_mac.cpp | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/compiler-rt/lib/tsan/rtl/tsan_platform_mac.cpp b/compiler-rt/lib/tsan/rtl/tsan_platform_mac.cpp
index 84dfe999045f9..5cc81bab5b911 100644
--- a/compiler-rt/lib/tsan/rtl/tsan_platform_mac.cpp
+++ b/compiler-rt/lib/tsan/rtl/tsan_platform_mac.cpp
@@ -227,7 +227,7 @@ void InitializePlatformEarly() {
# if !SANITIZER_GO && SANITIZER_IOS
uptr max_vm = GetMaxUserVirtualAddress() + 1;
if (max_vm < HiAppMemEnd()) {
- Printf(
+ Report(
"ThreadSanitizer: Unsupported virtual memory layout:\n\tVM address "
"limit = %p\n\tExpected %p.\n",
(void*)max_vm, (void*)HiAppMemEnd());
@@ -235,8 +235,8 @@ void InitializePlatformEarly() {
}
// In some configurations, the max_vm is expanded, but much of this space is
// already mapped. TSAN will not work in this configuration.
- else if (IsAddressInMappedRegion(HiAppMemEnd() - 1)) {
- Printf(
+ if (IsAddressInMappedRegion(HiAppMemEnd() - 1)) {
+ Report(
"ThreadSanitizer: Unsupported virtual memory layout: Address %p is "
"already mapped.\n");
Die();
More information about the llvm-commits
mailing list