[llvm] r270273 - Create a sigaltstack when we register our signal handlers. Otherwise we'd very

Richard Smith via llvm-commits llvm-commits at lists.llvm.org
Fri May 20 14:07:42 PDT 2016


Author: rsmith
Date: Fri May 20 16:07:41 2016
New Revision: 270273

URL: http://llvm.org/viewvc/llvm-project?rev=270273&view=rev
Log:
Create a sigaltstack when we register our signal handlers. Otherwise we'd very
likely fail to produce a backtrace if we crash due to stack overflow.

Modified:
    llvm/trunk/lib/Support/Unix/Signals.inc

Modified: llvm/trunk/lib/Support/Unix/Signals.inc
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/Unix/Signals.inc?rev=270273&r1=270272&r2=270273&view=diff
==============================================================================
--- llvm/trunk/lib/Support/Unix/Signals.inc (original)
+++ llvm/trunk/lib/Support/Unix/Signals.inc Fri May 20 16:07:41 2016
@@ -28,6 +28,8 @@
 # include <execinfo.h>         // For backtrace().
 #endif
 #if HAVE_SIGNAL_H
+// FIXME: We unconditionally use symbols from this header below. Do we really
+// need a configure-time check for a POSIX-mandated header in lib/Support/Unix?
 #include <signal.h>
 #endif
 #if HAVE_SYS_STAT_H
@@ -106,6 +108,31 @@ static void RegisterHandler(int Signal)
   ++NumRegisteredSignals;
 }
 
+// Hold onto the old alternate signal stack so that it's not reported as a leak.
+// We don't make any attempt to remove our alt signal stack if we remove our
+// signal handlers; that can't be done reliably if someone else is also trying
+// to do the same thing.
+static struct sigaltstack OldAltStack;
+
+static void CreateSigAltStack() {
+  const size_t AltStackSize = MINSIGSTKSZ + 8192;
+
+  // If we're executing on the alternate stack, or we already have an alternate
+  // signal stack that we're happy with, there's nothing for us to do. Don't
+  // reduce the size, some other part of the process might need a larger stack
+  // than we do.
+  if (sigaltstack(nullptr, &OldAltStack) != 0 ||
+      OldAltStack.ss_flags & SS_ONSTACK ||
+      (OldAltStack.ss_sp && OldAltStack.ss_size >= AltStackSize))
+    return;
+
+  struct sigaltstack AltStack = {};
+  AltStack.ss_sp = malloc(AltStackSize);
+  AltStack.ss_size = AltStackSize;
+  if (sigaltstack(&AltStack, &OldAltStack) != 0)
+    free(AltStack.ss_sp);
+}
+
 static void RegisterHandlers() {
   // We need to dereference the signals mutex during handler registration so
   // that we force its construction. This is to prevent the first use being
@@ -116,6 +143,10 @@ static void RegisterHandlers() {
   // If the handlers are already registered, we're done.
   if (NumRegisteredSignals != 0) return;
 
+  // Create an alternate stack for signal handling. This is necessary for us to
+  // be able to reliably handle signals due to stack overflow.
+  CreateSigAltStack();
+
   for (auto S : IntSigs) RegisterHandler(S);
   for (auto S : KillSigs) RegisterHandler(S);
 }




More information about the llvm-commits mailing list