From 54b6c4c7095e1d73e3d746564163617fcc6b7fd2 Mon Sep 17 00:00:00 2001 From: Aaron Ballman Date: Thu, 26 Mar 2015 16:24:38 +0000 Subject: [PATCH] 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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@233282 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Support/Windows/Signals.inc | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/lib/Support/Windows/Signals.inc b/lib/Support/Windows/Signals.inc index c786850c997..de6bf1c9583 100644 --- a/lib/Support/Windows/Signals.inc +++ b/lib/Support/Windows/Signals.inc @@ -174,6 +174,7 @@ static PTOP_LEVEL_EXCEPTION_FILTER OldFilter = NULL; // (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(); } -- 2.34.1