diff options
Diffstat (limited to 'llvm/lib/Support/CrashRecoveryContext.cpp')
-rw-r--r-- | llvm/lib/Support/CrashRecoveryContext.cpp | 30 |
1 files changed, 25 insertions, 5 deletions
diff --git a/llvm/lib/Support/CrashRecoveryContext.cpp b/llvm/lib/Support/CrashRecoveryContext.cpp index 0cc2d4059fe..f708da773f4 100644 --- a/llvm/lib/Support/CrashRecoveryContext.cpp +++ b/llvm/lib/Support/CrashRecoveryContext.cpp @@ -14,9 +14,6 @@ #include "llvm/Support/ThreadLocal.h" #include <mutex> #include <setjmp.h> -#ifdef _WIN32 -#include <windows.h> // for GetExceptionInformation -#endif #if LLVM_ON_UNIX #include <sysexits.h> // EX_IOERR #endif @@ -178,6 +175,9 @@ CrashRecoveryContext::unregisterCleanup(CrashRecoveryContextCleanup *cleanup) { } #if defined(_MSC_VER) + +#include <windows.h> // for GetExceptionInformation + // If _MSC_VER is defined, we must have SEH. Use it if it's available. It's way // better than VEH. Vectored exception handling catches all exceptions happening // on the thread with installed exception handlers, so it can interfere with @@ -203,6 +203,8 @@ static int ExceptionFilter(_EXCEPTION_POINTERS *Except) { } int RetCode = (int)Except->ExceptionRecord->ExceptionCode; + if ((RetCode & 0xF0000000) == 0xE0000000) + RetCode &= ~0xF0000000; // this crash was generated by sys::Process::Exit // Handle the crash const_cast<CrashRecoveryContextImpl *>(CRCI)->HandleCrash( @@ -280,10 +282,13 @@ static LONG CALLBACK ExceptionHandler(PEXCEPTION_POINTERS ExceptionInfo) // TODO: We can capture the stack backtrace here and store it on the // implementation if we so choose. + int RetCode = (int)ExceptionInfo->ExceptionRecord->ExceptionCode; + if ((RetCode & 0xF0000000) == 0xE0000000) + RetCode &= ~0xF0000000; // this crash was generated by sys::Process::Exit + // Handle the crash const_cast<CrashRecoveryContextImpl *>(CRCI)->HandleCrash( - (int)ExceptionInfo->ExceptionRecord->ExceptionCode, - reinterpret_cast<uintptr_t>(ExceptionInfo)); + RetCode, reinterpret_cast<uintptr_t>(ExceptionInfo)); // Note that we don't actually get here because HandleCrash calls // longjmp, which means the HandleCrash function never returns. @@ -416,6 +421,21 @@ bool CrashRecoveryContext::RunSafely(function_ref<void()> Fn) { #endif // !_MSC_VER +LLVM_ATTRIBUTE_NORETURN +void CrashRecoveryContext::HandleExit(int RetCode) { +#if defined(_WIN32) + // SEH and VEH + ::RaiseException(0xE0000000 | RetCode, 0, 0, NULL); +#else + // On Unix we don't need to raise an exception, we go directly to + // HandleCrash(), then longjmp will unwind the stack for us. + CrashRecoveryContextImpl *CRCI = (CrashRecoveryContextImpl *)Impl; + assert(CRCI && "Crash recovery context never initialized!"); + CRCI->HandleCrash(RetCode, 0 /*no sig num*/); +#endif + llvm_unreachable("Most likely setjmp wasn't called!"); +} + // FIXME: Portability. static void setThreadBackgroundPriority() { #ifdef __APPLE__ |