]> granicus.if.org Git - llvm/commitdiff
[Support] Avoid concurrency hazard in signal handler registration
authorBruno Cardoso Lopes <bruno.cardoso@gmail.com>
Mon, 27 Mar 2017 18:21:31 +0000 (18:21 +0000)
committerBruno Cardoso Lopes <bruno.cardoso@gmail.com>
Mon, 27 Mar 2017 18:21:31 +0000 (18:21 +0000)
Several static functions from the signal API can be invoked
simultaneously; RemoveFileOnSignal for instance can be called indirectly
by multiple parallel loadModule() invocations, which might lead to
the assertion:

Assertion failed: (NumRegisteredSignals < array_lengthof(RegisteredSignalInfo) && "Out of space for signal handlers!"),
  function RegisterHandler, file /llvm/lib/Support/Unix/Signals.inc, line 105.

RemoveFileOnSignal calls RegisterHandlers(), which isn't currently
mutex protected, leading to the behavior above. This potentially affect
a few other users of RegisterHandlers() too.

rdar://problem/30381224

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@298871 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Support/Unix/Signals.inc

index 081b2fe33a6ebd44c83a42a8bf2f4be50196ea0b..68be010ff5c2e7afcbb712a2af9ffa0827c228fa 100644 (file)
@@ -149,11 +149,7 @@ static void CreateSigAltStack() {}
 #endif
 
 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
-  // during handling an actual signal because you can't safely call new in a
-  // signal handler.
-  *SignalsMutex;
+  sys::SmartScopedLock<true> Guard(*SignalsMutex);
 
   // If the handlers are already registered, we're done.
   if (NumRegisteredSignals != 0) return;