[llvm-commits] [compiler-rt] r154092 - in /compiler-rt/trunk/lib/asan: asan_internal.h asan_posix.cc asan_rtl.cc asan_thread.cc asan_win.cc

Alexander Potapenko glider at google.com
Thu Apr 5 03:54:53 PDT 2012


Author: glider
Date: Thu Apr  5 05:54:52 2012
New Revision: 154092

URL: http://llvm.org/viewvc/llvm-project?rev=154092&view=rev
Log:
Introduce the use_sigaltstack flag (off by default), which enables using alternate
per-thread stacks for signal handling. This allows to print more verbose error reports
for stack overflows.


Modified:
    compiler-rt/trunk/lib/asan/asan_internal.h
    compiler-rt/trunk/lib/asan/asan_posix.cc
    compiler-rt/trunk/lib/asan/asan_rtl.cc
    compiler-rt/trunk/lib/asan/asan_thread.cc
    compiler-rt/trunk/lib/asan/asan_win.cc

Modified: compiler-rt/trunk/lib/asan/asan_internal.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_internal.h?rev=154092&r1=154091&r2=154092&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_internal.h (original)
+++ compiler-rt/trunk/lib/asan/asan_internal.h Thu Apr  5 05:54:52 2012
@@ -181,6 +181,8 @@
 int AsanClose(int fd);
 
 bool AsanInterceptsSignal(int signum);
+void SetAlternateSignalStack();
+void UnsetAlternateSignalStack();
 void InstallSignalHandlers();
 int GetPid();
 uintptr_t GetThreadSelf();
@@ -249,6 +251,7 @@
 extern bool   FLAG_allow_user_poisoning;
 extern int    FLAG_sleep_before_dying;
 extern bool   FLAG_handle_segv;
+extern bool   FLAG_use_sigaltstack;
 
 extern int asan_inited;
 // Used to avoid infinite recursion in __asan_init().

Modified: compiler-rt/trunk/lib/asan/asan_posix.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_posix.cc?rev=154092&r1=154091&r2=154092&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_posix.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_posix.cc Thu Apr  5 05:54:52 2012
@@ -34,6 +34,8 @@
 // since most of the stuff here is inlinable.
 #include <algorithm>
 
+static const size_t kAltStackSize = SIGSTKSZ * 4;  // SIGSTKSZ is not enough.
+
 namespace __asan {
 
 static void MaybeInstallSigaction(int signum,
@@ -44,6 +46,7 @@
   REAL(memset)(&sigact, 0, sizeof(sigact));
   sigact.sa_sigaction = handler;
   sigact.sa_flags = SA_SIGINFO;
+  if (FLAG_use_sigaltstack) sigact.sa_flags |= SA_ONSTACK;
   CHECK(0 == REAL(sigaction)(signum, &sigact, 0));
 }
 
@@ -63,7 +66,40 @@
   ShowStatsAndAbort();
 }
 
+void SetAlternateSignalStack() {
+  stack_t altstack, oldstack;
+  CHECK(0 == sigaltstack(NULL, &oldstack));
+  // If the alternate stack is already in place, do nothing.
+  if ((oldstack.ss_flags & SS_DISABLE) == 0) return;
+  // 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()).
+  void* base = AsanMmapSomewhereOrDie(kAltStackSize, __FUNCTION__);
+  altstack.ss_sp = base;
+  altstack.ss_flags = 0;
+  altstack.ss_size = kAltStackSize;
+  CHECK(0 == sigaltstack(&altstack, NULL));
+  if (FLAG_v > 0) {
+    Report("Alternative stack for T%d set: [%p,%p)\n",
+           asanThreadRegistry().GetCurrentTidOrMinusOne(),
+           altstack.ss_sp, (char*)altstack.ss_sp + altstack.ss_size);
+  }
+}
+
+void UnsetAlternateSignalStack() {
+  stack_t altstack, oldstack;
+  altstack.ss_sp = NULL;
+  altstack.ss_flags = SS_DISABLE;
+  altstack.ss_size = 0;
+  CHECK(0 == sigaltstack(&altstack, &oldstack));
+  AsanUnmapOrDie(oldstack.ss_sp, oldstack.ss_size);
+}
+
 void InstallSignalHandlers() {
+  // Set the alternate signal stack for the main thread.
+  // This will cause SetAlternateSignalStack to be called twice, but the stack
+  // will be actually set only once.
+  if (FLAG_use_sigaltstack) SetAlternateSignalStack();
   MaybeInstallSigaction(SIGSEGV, ASAN_OnSIGSEGV);
   MaybeInstallSigaction(SIGBUS, ASAN_OnSIGSEGV);
 }

Modified: compiler-rt/trunk/lib/asan/asan_rtl.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_rtl.cc?rev=154092&r1=154091&r2=154092&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_rtl.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_rtl.cc Thu Apr  5 05:54:52 2012
@@ -39,6 +39,7 @@
 size_t FLAG_malloc_context_size = kMallocContextSize;
 uintptr_t FLAG_large_malloc;
 bool   FLAG_handle_segv;
+bool   FLAG_use_sigaltstack;
 bool   FLAG_replace_str;
 bool   FLAG_replace_intrin;
 bool   FLAG_replace_cfallocator;  // Used on Mac only.
@@ -442,6 +443,7 @@
   FLAG_poison_shadow = IntFlagValue(options, "poison_shadow=", 1);
   FLAG_report_globals = IntFlagValue(options, "report_globals=", 1);
   FLAG_handle_segv = IntFlagValue(options, "handle_segv=", ASAN_NEEDS_SEGV);
+  FLAG_use_sigaltstack = IntFlagValue(options, "use_sigaltstack=", 0);
   FLAG_symbolize = IntFlagValue(options, "symbolize=", 1);
   FLAG_demangle = IntFlagValue(options, "demangle=", 1);
   FLAG_debug = IntFlagValue(options, "debug=", 0);
@@ -470,7 +472,6 @@
   InitializeAsanInterceptors();
 
   ReplaceSystemMalloc();
-  InstallSignalHandlers();
 
   if (FLAG_v) {
     Printf("|| `[%p, %p]` || HighMem    ||\n", kHighMemBeg, kHighMemEnd);
@@ -517,6 +518,8 @@
     AsanDie();
   }
 
+  InstallSignalHandlers();
+
   // On Linux AsanThread::ThreadStart() calls malloc() that's why asan_inited
   // should be set to 1 prior to initializing the threads.
   asan_inited = 1;

Modified: compiler-rt/trunk/lib/asan/asan_thread.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_thread.cc?rev=154092&r1=154091&r2=154092&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_thread.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_thread.cc Thu Apr  5 05:54:52 2012
@@ -82,6 +82,7 @@
 
 thread_return_t AsanThread::ThreadStart() {
   Init();
+  if (FLAG_use_sigaltstack) SetAlternateSignalStack();
 
   if (!start_routine_) {
     // start_routine_ == NULL if we're on the main thread or on one of the
@@ -93,6 +94,7 @@
 
   thread_return_t res = start_routine_(arg_);
   malloc_storage().CommitBack();
+  if (FLAG_use_sigaltstack) UnsetAlternateSignalStack();
 
   this->Destroy();
 

Modified: compiler-rt/trunk/lib/asan/asan_win.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_win.cc?rev=154092&r1=154091&r2=154092&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_win.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_win.cc Thu Apr  5 05:54:52 2012
@@ -262,6 +262,14 @@
   return GetCurrentThreadId();
 }
 
+void SetAlternateSignalStack() {
+  // FIXME: Decide what to do on Windows.
+}
+
+void UnsetAlternateSignalStack() {
+  // FIXME: Decide what to do on Windows.
+}
+
 void InstallSignalHandlers() {
   // FIXME: Decide what to do on Windows.
 }





More information about the llvm-commits mailing list