[Support][Windows] Unify dialog box suppression and print stack traces on abort.

llvm-svn: 227470
This commit is contained in:
Michael J. Spencer 2015-01-29 17:20:29 +00:00
parent 9bf5328f97
commit 89b0ad2647
3 changed files with 33 additions and 20 deletions

View File

@ -39,6 +39,9 @@ namespace sys {
/// @brief Print a stack trace if a fatal signal occurs.
void PrintStackTraceOnErrorSignal();
/// Disable all system dialog boxes that appear when the process crashes.
void DisableSystemDialogsOnCrash();
/// \brief Print the stack trace using the given \c FILE object.
void PrintStackTrace(FILE *);

View File

@ -480,6 +480,8 @@ static void PrintStackTraceSignalHandler(void *) {
PrintStackTrace(stderr);
}
void llvm::sys::DisableSystemDialogsOnCrash() {}
/// PrintStackTraceOnErrorSignal - When an error signal (such as SIGABRT or
/// SIGSEGV) is delivered to the process, print a stack trace and then exit.
void llvm::sys::PrintStackTraceOnErrorSignal() {

View File

@ -13,6 +13,7 @@
#include "llvm/Support/FileSystem.h"
#include <algorithm>
#include <signal.h>
#include <stdio.h>
#include <vector>
@ -165,7 +166,6 @@ static std::vector<std::string> *FilesToRemove = NULL;
static std::vector<std::pair<void(*)(void*), void*> > *CallBacksToRun = 0;
static bool RegisteredUnhandledExceptionFilter = false;
static bool CleanupExecuted = false;
static bool ExitOnUnhandledExceptions = false;
static PTOP_LEVEL_EXCEPTION_FILTER OldFilter = NULL;
// Windows creates a new thread to execute the console handler when an event
@ -196,6 +196,12 @@ static int AvoidMessageBoxHook(int ReportType, char *Message, int *Return) {
#endif
static void HandleAbort(int Sig) {
if (Sig == SIGABRT) {
LLVM_BUILTIN_TRAP;
}
}
static void RegisterHandler() {
#if __MINGW32__ && !defined(__MINGW64_VERSION_MAJOR)
// On MinGW.org, we need to load up the symbols explicitly, because the
@ -226,17 +232,6 @@ static void RegisterHandler() {
OldFilter = SetUnhandledExceptionFilter(LLVMUnhandledExceptionFilter);
SetConsoleCtrlHandler(LLVMConsoleCtrlHandler, TRUE);
// Environment variable to disable any kind of crash dialog.
if (getenv("LLVM_DISABLE_CRASH_REPORT")) {
#ifdef _MSC_VER
_CrtSetReportHook(AvoidMessageBoxHook);
#endif
SetErrorMode(SEM_FAILCRITICALERRORS |
SEM_NOGPFAULTERRORBOX |
SEM_NOOPENFILEERRORBOX);
ExitOnUnhandledExceptions = true;
}
// IMPORTANT NOTE: Caller must call LeaveCriticalSection(&CriticalSection) or
// else multi-threading problems will ensue.
}
@ -276,9 +271,29 @@ void sys::DontRemoveFileOnSignal(StringRef Filename) {
LeaveCriticalSection(&CriticalSection);
}
void sys::DisableSystemDialogsOnCrash() {
// Crash to stack trace handler on abort.
signal(SIGABRT, HandleAbort);
// The following functions are not reliably accessible on MinGW.
#ifdef _MSC_VER
// We're already handling writing a "something went wrong" message.
_set_abort_behavior(0, _WRITE_ABORT_MSG);
// Disable Dr. Watson.
_set_abort_behavior(0, _CALL_REPORTFAULT);
_CrtSetReportHook(AvoidMessageBoxHook);
#endif
// Disable standard error dialog box.
SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX |
SEM_NOOPENFILEERRORBOX);
_set_error_mode(_OUT_TO_STDERR);
}
/// PrintStackTraceOnErrorSignal - When an error signal (such as SIBABRT or
/// SIGSEGV) is delivered to the process, print a stack trace and then exit.
void sys::PrintStackTraceOnErrorSignal() {
DisableSystemDialogsOnCrash();
RegisterHandler();
LeaveCriticalSection(&CriticalSection);
}
@ -437,14 +452,7 @@ static LONG WINAPI LLVMUnhandledExceptionFilter(LPEXCEPTION_POINTERS ep) {
fputc('\n', stderr);
}
if (ExitOnUnhandledExceptions)
_exit(ep->ExceptionRecord->ExceptionCode);
// Allow dialog box to pop up allowing choice to start debugger.
if (OldFilter)
return (*OldFilter)(ep);
else
return EXCEPTION_CONTINUE_SEARCH;
}
static BOOL WINAPI LLVMConsoleCtrlHandler(DWORD dwCtrlType) {