[llvm] r233282 - Sometimes report_fatal_error is called when there is not a handler function used to fail gracefully. In that case, RunInterruptHandlers is called, which attempts to enter a critical section object. Ensure that the critical section is properly initialized so that this code functions properly, and tools like clang-tidy do not crash in Debug builds.

Aaron Ballman aaron at aaronballman.com
Thu Mar 26 09:24:38 PDT 2015


Author: aaronballman
Date: Thu Mar 26 11:24:38 2015
New Revision: 233282

URL: http://llvm.org/viewvc/llvm-project?rev=233282&view=rev
Log:
Sometimes report_fatal_error is called when there is not a handler function used to fail gracefully. In that case, RunInterruptHandlers is called, which attempts to enter a critical section object. Ensure that the critical section is properly initialized so that this code functions properly, and tools like clang-tidy do not crash in Debug builds.

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

Modified: llvm/trunk/lib/Support/Windows/Signals.inc
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/Windows/Signals.inc?rev=233282&r1=233281&r2=233282&view=diff
==============================================================================
--- llvm/trunk/lib/Support/Windows/Signals.inc (original)
+++ llvm/trunk/lib/Support/Windows/Signals.inc Thu Mar 26 11:24:38 2015
@@ -174,6 +174,7 @@ static PTOP_LEVEL_EXCEPTION_FILTER OldFi
 // (such as CTRL/C) occurs.  This causes concurrency issues with the above
 // globals which this critical section addresses.
 static CRITICAL_SECTION CriticalSection;
+static bool CriticalSectionInitialized = false;
 
 static void PrintStackTraceForThread(llvm::raw_ostream &OS, HANDLE hProcess,
                                      HANDLE hThread, STACKFRAME64 &StackFrame,
@@ -290,6 +291,16 @@ extern "C" void HandleAbort(int Sig) {
   }
 }
 
+static void InitializeThreading() {
+  if (CriticalSectionInitialized)
+    return;
+
+  // Now's the time to create the critical section. This is the first time
+  // through here, and there's only one thread.
+  InitializeCriticalSection(&CriticalSection);
+  CriticalSectionInitialized = true;
+}
+
 static void RegisterHandler() {
 #if __MINGW32__ && !defined(__MINGW64_VERSION_MAJOR)
   // On MinGW.org, we need to load up the symbols explicitly, because the
@@ -308,9 +319,7 @@ static void RegisterHandler() {
     return;
   }
 
-  // Now's the time to create the critical section.  This is the first time
-  // through here, and there's only one thread.
-  InitializeCriticalSection(&CriticalSection);
+  InitializeThreading();
 
   // Enter it immediately.  Now if someone hits CTRL/C, the console handler
   // can't proceed until the globals are updated.
@@ -456,6 +465,11 @@ static void Cleanup() {
 }
 
 void llvm::sys::RunInterruptHandlers() {
+  // The interrupt handler may be called from an interrupt, but it may also be
+  // called manually (such as the case of report_fatal_error with no registered
+  // error handler). We must ensure that the critical section is properly
+  // initialized.
+  InitializeThreading();
   Cleanup();
 }
 





More information about the llvm-commits mailing list