diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2021-02-16 20:13:02 +0000 |
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2021-02-16 20:13:02 +0000 |
| commit | b60736ec1405bb0a8dd40989f67ef4c93da068ab (patch) | |
| tree | 5c43fbb7c9fc45f0f87e0e6795a86267dbd12f9d /llvm/lib/Support/CrashRecoveryContext.cpp | |
| parent | cfca06d7963fa0909f90483b42a6d7d194d01e08 (diff) | |
Diffstat (limited to 'llvm/lib/Support/CrashRecoveryContext.cpp')
| -rw-r--r-- | llvm/lib/Support/CrashRecoveryContext.cpp | 39 |
1 files changed, 33 insertions, 6 deletions
diff --git a/llvm/lib/Support/CrashRecoveryContext.cpp b/llvm/lib/Support/CrashRecoveryContext.cpp index ec7d7d641dce..3d3ca7f567c7 100644 --- a/llvm/lib/Support/CrashRecoveryContext.cpp +++ b/llvm/lib/Support/CrashRecoveryContext.cpp @@ -9,14 +9,12 @@ #include "llvm/Support/CrashRecoveryContext.h" #include "llvm/Config/llvm-config.h" #include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/ExitCodes.h" #include "llvm/Support/ManagedStatic.h" #include "llvm/Support/Signals.h" #include "llvm/Support/ThreadLocal.h" #include <mutex> #include <setjmp.h> -#if LLVM_ON_UNIX -#include <sysexits.h> // EX_IOERR -#endif using namespace llvm; @@ -97,6 +95,13 @@ static void uninstallExceptionOrSignalHandlers(); CrashRecoveryContextCleanup::~CrashRecoveryContextCleanup() {} +CrashRecoveryContext::CrashRecoveryContext() { + // On Windows, if abort() was previously triggered (and caught by a previous + // CrashRecoveryContext) the Windows CRT removes our installed signal handler, + // so we need to install it again. + sys::DisableSystemDialogsOnCrash(); +} + CrashRecoveryContext::~CrashRecoveryContext() { // Reclaim registered resources. CrashRecoveryContextCleanup *i = head; @@ -370,9 +375,10 @@ static void CrashRecoverySignalHandler(int Signal) { sigaddset(&SigMask, Signal); sigprocmask(SIG_UNBLOCK, &SigMask, nullptr); - // As per convention, -2 indicates a crash or timeout as opposed to failure to - // execute (see llvm/include/llvm/Support/Program.h) - int RetCode = -2; + // Return the same error code as if the program crashed, as mentioned in the + // section "Exit Status for Commands": + // https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_xcu_chap02.html + int RetCode = 128 + Signal; // Don't consider a broken pipe as a crash (see clang/lib/Driver/Driver.cpp) if (Signal == SIGPIPE) @@ -436,6 +442,27 @@ void CrashRecoveryContext::HandleExit(int RetCode) { llvm_unreachable("Most likely setjmp wasn't called!"); } +bool CrashRecoveryContext::throwIfCrash(int RetCode) { +#if defined(_WIN32) + // On Windows, the high bits are reserved for kernel return codes. Values + // starting with 0x80000000 are reserved for "warnings"; values of 0xC0000000 + // and up are for "errors". In practice, both are interpreted as a + // non-continuable signal. + unsigned Code = ((unsigned)RetCode & 0xF0000000) >> 28; + if (Code != 0xC && Code != 8) + return false; + ::RaiseException(RetCode, 0, 0, NULL); +#else + // On Unix, signals are represented by return codes of 128 or higher. + // Exit code 128 is a reserved value and should not be raised as a signal. + if (RetCode <= 128) + return false; + llvm::sys::unregisterHandlers(); + raise(RetCode - 128); +#endif + return true; +} + // FIXME: Portability. static void setThreadBackgroundPriority() { #ifdef __APPLE__ |
