diff options
author | Alexandre Ganea <alexandre.ganea@ubisoft.com> | 2020-02-11 10:17:15 -0500 |
---|---|---|
committer | Hans Wennborg <hans@chromium.org> | 2020-02-12 10:22:21 +0100 |
commit | fd04cb43e1d83c6f18c932de94c1e341272ed160 (patch) | |
tree | 0eccf00d27a17e3b8ece0a0a4d7eecd328b5d524 /llvm/lib/Support/CrashRecoveryContext.cpp | |
parent | aeba7ba9f3dada09e196d174e7f13b82f01300db (diff) | |
download | bcm5719-llvm-fd04cb43e1d83c6f18c932de94c1e341272ed160.tar.gz bcm5719-llvm-fd04cb43e1d83c6f18c932de94c1e341272ed160.zip |
[Clang][Driver] After default -fintegrated-cc1, make llvm::report_fatal_error() generate preprocessed source + reproducer.sh again.
Added a test for #pragma clang __debug llvm_fatal_error to test for the original issue.
Added llvm::sys::Process::Exit() and replaced ::exit() in places where it was appropriate. This new function would call the current CrashRecoveryContext if one is running on the same thread; or call ::exit() otherwise.
Fixes PR44705.
Differential Revision: https://reviews.llvm.org/D73742
(cherry picked from commit faace365088a2a3a4cb1050a9facfc34a7a56577)
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__ |