[compiler-rt] Formatted approved PR #179000 (PR #196674)

via llvm-commits llvm-commits at lists.llvm.org
Fri May 8 18:05:37 PDT 2026


https://github.com/accauble created https://github.com/llvm/llvm-project/pull/196674

PR #179000 was approved by @DanBlackwell and @vitalybuka a few weeks ago but cannot be merged because of formatting issues. The only changes this makes to @ilovepi's code is the formatting.


>From 82343bb08ce4ebb365fae2ea1a4b3bd6a328db19 Mon Sep 17 00:00:00 2001
From: Paul Kirth <paulkirth at google.com>
Date: Fri, 30 Jan 2026 16:01:44 -0800
Subject: [PATCH 1/4] [compiler-rt][common] Don't unmap stacks not mapped by
 the runtime

When the sanitizer hasn't mapped the alternate signal stack, but the
host program has (like LLVM), the runtime still tries to unilaterally
unmap the alternate stack. Instead, the runtime should just check if
it's actually mmaped the alternate stack, and only unmap it if it has.
---
 .../lib/sanitizer_common/sanitizer_posix_libcdep.cpp     | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_posix_libcdep.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_posix_libcdep.cpp
index 35b596de30fff..c29ae55267273 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_posix_libcdep.cpp
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_posix_libcdep.cpp
@@ -49,6 +49,8 @@ namespace __sanitizer {
 
 [[maybe_unused]] static atomic_uint8_t signal_handler_is_from_sanitizer[64];
 
+static THREADLOCAL void* allocated_alt_stack_base = nullptr;
+
 u32 GetUid() {
   return getuid();
 }
@@ -201,6 +203,7 @@ void SetAlternateSignalStack() {
   altstack.ss_sp = (char *)MmapOrDie(altstack.ss_size, __func__);
   altstack.ss_flags = 0;
   CHECK_EQ(0, sigaltstack(&altstack, nullptr));
+  allocated_alt_stack_base = altstack.ss_sp;
 }
 
 void UnsetAlternateSignalStack() {
@@ -209,7 +212,11 @@ void UnsetAlternateSignalStack() {
   altstack.ss_flags = SS_DISABLE;
   altstack.ss_size = GetAltStackSize();  // Some sane value required on Darwin.
   CHECK_EQ(0, sigaltstack(&altstack, &oldstack));
-  UnmapOrDie(oldstack.ss_sp, oldstack.ss_size);
+  if (allocated_alt_stack_base != 0 &&
+      allocated_alt_stack_base == oldstack.ss_sp) {
+    UnmapOrDie(oldstack.ss_sp, oldstack.ss_size);
+    allocated_alt_stack_base = nullptr;
+  }
 }
 
 bool IsSignalHandlerFromSanitizer(int signum) {

>From 3f46415b6577c20273a23896ac894eea3d162fae Mon Sep 17 00:00:00 2001
From: Paul Kirth <paulkirth at google.com>
Date: Fri, 20 Feb 2026 16:00:36 -0800
Subject: [PATCH 2/4] Use AsanThread to store pointer

---
 compiler-rt/lib/asan/asan_thread.cpp               |  4 ++--
 compiler-rt/lib/asan/asan_thread.h                 |  1 +
 .../lib/sanitizer_common/sanitizer_common.h        |  4 ++--
 .../lib/sanitizer_common/sanitizer_fuchsia.cpp     |  4 ++--
 .../sanitizer_common/sanitizer_posix_libcdep.cpp   | 14 +++++---------
 compiler-rt/lib/sanitizer_common/sanitizer_win.cpp |  5 +++--
 6 files changed, 15 insertions(+), 17 deletions(-)

diff --git a/compiler-rt/lib/asan/asan_thread.cpp b/compiler-rt/lib/asan/asan_thread.cpp
index 32ab723e89001..ec96ec9b8082b 100644
--- a/compiler-rt/lib/asan/asan_thread.cpp
+++ b/compiler-rt/lib/asan/asan_thread.cpp
@@ -132,7 +132,7 @@ void AsanThread::Destroy() {
       CHECK_EQ(this, thread);
     malloc_storage().CommitBack();
     if (common_flags()->use_sigaltstack)
-      UnsetAlternateSignalStack();
+      UnsetAlternateSignalStack(altstack_base_);
     FlushToDeadThreadStats(&stats_);
     // We also clear the shadow on thread destruction because
     // some code may still be executing in later TSD destructors
@@ -288,7 +288,7 @@ void AsanThread::ThreadStart(ThreadID os_id) {
   asanThreadRegistry().StartThread(tid(), os_id, ThreadType::Regular, nullptr);
 
   if (common_flags()->use_sigaltstack)
-    SetAlternateSignalStack();
+    altstack_base_ = SetAlternateSignalStack();
 }
 
 AsanThread *CreateMainThread() {
diff --git a/compiler-rt/lib/asan/asan_thread.h b/compiler-rt/lib/asan/asan_thread.h
index e9ca6b6a59016..b356998459d9d 100644
--- a/compiler-rt/lib/asan/asan_thread.h
+++ b/compiler-rt/lib/asan/asan_thread.h
@@ -190,6 +190,7 @@ class AsanThread {
   AsanStats stats_;
   bool unwinding_;
   uptr extra_spill_area_;
+  void *altstack_base_ = nullptr;
 
   char start_data_[];
 };
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common.h b/compiler-rt/lib/sanitizer_common/sanitizer_common.h
index 4dd2187df2272..195c98870397c 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_common.h
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_common.h
@@ -387,8 +387,8 @@ void ReportDeadlySignal(const SignalContext &sig, u32 tid,
                         const void *unwind_context);
 
 // Alternative signal stack (POSIX-only).
-void SetAlternateSignalStack();
-void UnsetAlternateSignalStack();
+void *SetAlternateSignalStack();
+void UnsetAlternateSignalStack(void *altstack_base);
 
 bool IsSignalHandlerFromSanitizer(int signum);
 bool SetSignalHandlerFromSanitizer(int signum, bool new_state);
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_fuchsia.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_fuchsia.cpp
index 3c61b60802996..4dc31f4e51efa 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_fuchsia.cpp
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_fuchsia.cpp
@@ -93,8 +93,8 @@ void CheckMPROTECT() {}
 void PlatformPrepareForSandboxing(void *args) {}
 void DisableCoreDumperIfNecessary() {}
 void InstallDeadlySignalHandlers(SignalHandlerType handler) {}
-void SetAlternateSignalStack() {}
-void UnsetAlternateSignalStack() {}
+void* SetAlternateSignalStack() { return nullptr; }
+void UnsetAlternateSignalStack(void* altstack_base) {}
 
 bool SignalContext::IsStackOverflow() const { return false; }
 void SignalContext::DumpAllRegisters(void *context) { UNIMPLEMENTED(); }
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_posix_libcdep.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_posix_libcdep.cpp
index c29ae55267273..a397672fa8166 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_posix_libcdep.cpp
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_posix_libcdep.cpp
@@ -49,8 +49,6 @@ namespace __sanitizer {
 
 [[maybe_unused]] static atomic_uint8_t signal_handler_is_from_sanitizer[64];
 
-static THREADLOCAL void* allocated_alt_stack_base = nullptr;
-
 u32 GetUid() {
   return getuid();
 }
@@ -190,12 +188,12 @@ static uptr GetAltStackSize() {
   return SIGSTKSZ * 4;
 }
 
-void SetAlternateSignalStack() {
+void* SetAlternateSignalStack() {
   stack_t altstack, oldstack;
   CHECK_EQ(0, sigaltstack(nullptr, &oldstack));
   // If the alternate stack is already in place, do nothing.
   // Android always sets an alternate stack, but it's too small for us.
-  if (!SANITIZER_ANDROID && !(oldstack.ss_flags & SS_DISABLE)) return;
+  if (!SANITIZER_ANDROID && !(oldstack.ss_flags & SS_DISABLE)) return nullptr;
   // TODO(glider): the mapped stack should have the MAP_STACK flag in the
   // future. It is not required by man 2 sigaltstack now (they're using
   // malloc()).
@@ -203,19 +201,17 @@ void SetAlternateSignalStack() {
   altstack.ss_sp = (char *)MmapOrDie(altstack.ss_size, __func__);
   altstack.ss_flags = 0;
   CHECK_EQ(0, sigaltstack(&altstack, nullptr));
-  allocated_alt_stack_base = altstack.ss_sp;
+  return altstack.ss_sp;
 }
 
-void UnsetAlternateSignalStack() {
+void UnsetAlternateSignalStack(void* altstack_base) {
   stack_t altstack, oldstack;
   altstack.ss_sp = nullptr;
   altstack.ss_flags = SS_DISABLE;
   altstack.ss_size = GetAltStackSize();  // Some sane value required on Darwin.
   CHECK_EQ(0, sigaltstack(&altstack, &oldstack));
-  if (allocated_alt_stack_base != 0 &&
-      allocated_alt_stack_base == oldstack.ss_sp) {
+  if (altstack_base && altstack_base == oldstack.ss_sp) {
     UnmapOrDie(oldstack.ss_sp, oldstack.ss_size);
-    allocated_alt_stack_base = nullptr;
   }
 }
 
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_win.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_win.cpp
index ed4f60deeffc8..70f4a936c1329 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_win.cpp
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_win.cpp
@@ -913,11 +913,12 @@ void ReportFile::Write(const char *buffer, uptr length) {
   }
 }
 
-void SetAlternateSignalStack() {
+void* SetAlternateSignalStack() {
   // FIXME: Decide what to do on Windows.
+  return nullptr;
 }
 
-void UnsetAlternateSignalStack() {
+void UnsetAlternateSignalStack(void* altstack_base) {
   // FIXME: Decide what to do on Windows.
 }
 

>From a426d515a1f2d488b9a5a158d11ec403b1d83e0c Mon Sep 17 00:00:00 2001
From: Paul Kirth <paulkirth at google.com>
Date: Mon, 23 Feb 2026 13:47:36 -0800
Subject: [PATCH 3/4] Add test case

---
 .../TestCases/Posix/multiple_sigaltstack.cpp  | 24 +++++++++++++++++++
 1 file changed, 24 insertions(+)
 create mode 100644 compiler-rt/test/asan/TestCases/Posix/multiple_sigaltstack.cpp

diff --git a/compiler-rt/test/asan/TestCases/Posix/multiple_sigaltstack.cpp b/compiler-rt/test/asan/TestCases/Posix/multiple_sigaltstack.cpp
new file mode 100644
index 0000000000000..b70e6ff485a98
--- /dev/null
+++ b/compiler-rt/test/asan/TestCases/Posix/multiple_sigaltstack.cpp
@@ -0,0 +1,24 @@
+// RUN: %clangxx_asan %s -o %t && %env_asan_opts=use_sigaltstack=1 %run %t
+
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <pthread.h>
+
+char global_alt_stack[4096 * 4];
+
+int main() {
+  stack_t altstack;
+  altstack.ss_sp = global_alt_stack;
+  altstack.ss_size = sizeof(global_alt_stack);
+  altstack.ss_flags = 0;
+  if (sigaltstack(&altstack, nullptr) != 0) {
+    perror("sigaltstack");
+    exit(1);
+  }
+
+  // UnsetAlternateSignalStack will get called when the thread exists. If we
+  // don't *only* unmap a signal stack the runtime owns, we'll get a fault on
+  // the munmap operation, since that memory isn't mmaped.
+  return 0;
+}

>From 3b5a0f1bc763ac8f51048054ef8df9f6c7427221 Mon Sep 17 00:00:00 2001
From: Allyson Cauble-Chantrenne <acaublec at amd.com>
Date: Fri, 8 May 2026 19:56:09 -0500
Subject: [PATCH 4/4] Formatted files for approved PR #179000

---
 compiler-rt/lib/asan/asan_thread.h                            | 2 +-
 compiler-rt/lib/sanitizer_common/sanitizer_common.h           | 4 ++--
 compiler-rt/lib/sanitizer_common/sanitizer_posix_libcdep.cpp  | 3 ++-
 .../test/asan/TestCases/Posix/multiple_sigaltstack.cpp        | 2 +-
 4 files changed, 6 insertions(+), 5 deletions(-)

diff --git a/compiler-rt/lib/asan/asan_thread.h b/compiler-rt/lib/asan/asan_thread.h
index b356998459d9d..6dbac7f3d8162 100644
--- a/compiler-rt/lib/asan/asan_thread.h
+++ b/compiler-rt/lib/asan/asan_thread.h
@@ -190,7 +190,7 @@ class AsanThread {
   AsanStats stats_;
   bool unwinding_;
   uptr extra_spill_area_;
-  void *altstack_base_ = nullptr;
+  void* altstack_base_ = nullptr;
 
   char start_data_[];
 };
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common.h b/compiler-rt/lib/sanitizer_common/sanitizer_common.h
index 195c98870397c..2aacec1cd8994 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_common.h
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_common.h
@@ -387,8 +387,8 @@ void ReportDeadlySignal(const SignalContext &sig, u32 tid,
                         const void *unwind_context);
 
 // Alternative signal stack (POSIX-only).
-void *SetAlternateSignalStack();
-void UnsetAlternateSignalStack(void *altstack_base);
+void* SetAlternateSignalStack();
+void UnsetAlternateSignalStack(void* altstack_base);
 
 bool IsSignalHandlerFromSanitizer(int signum);
 bool SetSignalHandlerFromSanitizer(int signum, bool new_state);
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_posix_libcdep.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_posix_libcdep.cpp
index a397672fa8166..056eb677f0441 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_posix_libcdep.cpp
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_posix_libcdep.cpp
@@ -193,7 +193,8 @@ void* SetAlternateSignalStack() {
   CHECK_EQ(0, sigaltstack(nullptr, &oldstack));
   // If the alternate stack is already in place, do nothing.
   // Android always sets an alternate stack, but it's too small for us.
-  if (!SANITIZER_ANDROID && !(oldstack.ss_flags & SS_DISABLE)) return nullptr;
+  if (!SANITIZER_ANDROID && !(oldstack.ss_flags & SS_DISABLE))
+    return nullptr;
   // TODO(glider): the mapped stack should have the MAP_STACK flag in the
   // future. It is not required by man 2 sigaltstack now (they're using
   // malloc()).
diff --git a/compiler-rt/test/asan/TestCases/Posix/multiple_sigaltstack.cpp b/compiler-rt/test/asan/TestCases/Posix/multiple_sigaltstack.cpp
index b70e6ff485a98..a7cf4b3a43b91 100644
--- a/compiler-rt/test/asan/TestCases/Posix/multiple_sigaltstack.cpp
+++ b/compiler-rt/test/asan/TestCases/Posix/multiple_sigaltstack.cpp
@@ -1,9 +1,9 @@
 // RUN: %clangxx_asan %s -o %t && %env_asan_opts=use_sigaltstack=1 %run %t
 
+#include <pthread.h>
 #include <signal.h>
 #include <stdio.h>
 #include <stdlib.h>
-#include <pthread.h>
 
 char global_alt_stack[4096 * 4];
 



More information about the llvm-commits mailing list