diff options
Diffstat (limited to 'lib/System/Win32/Signals.cpp')
-rw-r--r-- | lib/System/Win32/Signals.cpp | 239 |
1 files changed, 0 insertions, 239 deletions
diff --git a/lib/System/Win32/Signals.cpp b/lib/System/Win32/Signals.cpp deleted file mode 100644 index afe6c8dfa6..0000000000 --- a/lib/System/Win32/Signals.cpp +++ /dev/null @@ -1,239 +0,0 @@ -//===- Win32/Signals.cpp - Win32 Signals Implementation ---------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file was developed by Jeff Cohen and is distributed under the -// University of Illinois Open Source License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file provides the Win32 specific implementation of the Signals class. -// -//===----------------------------------------------------------------------===// - -#include "Win32.h" -#include <stdio.h> -#include <vector> - -#ifdef __MINGW -#include <imagehlp.h> -#else -#include <dbghelp.h> -#endif -#include <psapi.h> - -#pragma comment(lib, "psapi.lib") -#pragma comment(lib, "dbghelp.lib") - -// Forward declare. -static LONG WINAPI LLVMUnhandledExceptionFilter(LPEXCEPTION_POINTERS ep); -static BOOL WINAPI LLVMConsoleCtrlHandler(DWORD dwCtrlType); - -static std::vector<llvm::sys::Path> *FilesToRemove = NULL; -static std::vector<llvm::sys::Path> *DirectoriesToRemove = NULL; -static bool RegisteredUnhandledExceptionFilter = false; -static bool CleanupExecuted = false; -static PTOP_LEVEL_EXCEPTION_FILTER OldFilter = NULL; - -// Windows creates a new thread to execute the console handler when an event -// (such as CTRL/C) occurs. This causes concurrency issues with the above -// globals which this critical section addresses. -static CRITICAL_SECTION CriticalSection; - -namespace llvm { - -//===----------------------------------------------------------------------===// -//=== WARNING: Implementation here must contain only Win32 specific code -//=== and must not be UNIX code -//===----------------------------------------------------------------------===// - - -static void RegisterHandler() { - if (RegisteredUnhandledExceptionFilter) { - EnterCriticalSection(&CriticalSection); - 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); - - // Enter it immediately. Now if someone hits CTRL/C, the console handler - // can't proceed until the globals are updated. - EnterCriticalSection(&CriticalSection); - - RegisteredUnhandledExceptionFilter = true; - OldFilter = SetUnhandledExceptionFilter(LLVMUnhandledExceptionFilter); - SetConsoleCtrlHandler(LLVMConsoleCtrlHandler, TRUE); - - // IMPORTANT NOTE: Caller must call LeaveCriticalSection(&CriticalSection) or - // else multi-threading problems will ensue. -} - -// RemoveFileOnSignal - The public API -void sys::RemoveFileOnSignal(const sys::Path &Filename) { - RegisterHandler(); - - if (CleanupExecuted) - throw std::string("Process terminating -- cannot register for removal"); - - if (FilesToRemove == NULL) - FilesToRemove = new std::vector<sys::Path>; - - FilesToRemove->push_back(Filename); - - LeaveCriticalSection(&CriticalSection); -} - -// RemoveDirectoryOnSignal - The public API -void sys::RemoveDirectoryOnSignal(const sys::Path& path) { - RegisterHandler(); - - if (CleanupExecuted) - throw std::string("Process terminating -- cannot register for removal"); - - if (path.isDirectory()) { - if (DirectoriesToRemove == NULL) - DirectoriesToRemove = new std::vector<sys::Path>; - - DirectoriesToRemove->push_back(path); - } - - LeaveCriticalSection(&CriticalSection); -} - -/// 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() { - RegisterHandler(); - LeaveCriticalSection(&CriticalSection); -} - -} - -static void Cleanup() { - EnterCriticalSection(&CriticalSection); - - // Prevent other thread from registering new files and directories for - // removal, should we be executing because of the console handler callback. - CleanupExecuted = true; - - // FIXME: open files cannot be deleted. - - if (FilesToRemove != NULL) - while (!FilesToRemove->empty()) { - try { - FilesToRemove->back().destroyFile(); - } catch (...) { - } - FilesToRemove->pop_back(); - } - - if (DirectoriesToRemove != NULL) - while (!DirectoriesToRemove->empty()) { - try { - DirectoriesToRemove->back().destroyDirectory(true); - } catch (...) { - } - DirectoriesToRemove->pop_back(); - } - - LeaveCriticalSection(&CriticalSection); -} - -static LONG WINAPI LLVMUnhandledExceptionFilter(LPEXCEPTION_POINTERS ep) { - try { - Cleanup(); - - // Initialize the STACKFRAME structure. - STACKFRAME StackFrame; - memset(&StackFrame, 0, sizeof(StackFrame)); - - StackFrame.AddrPC.Offset = ep->ContextRecord->Eip; - StackFrame.AddrPC.Mode = AddrModeFlat; - StackFrame.AddrStack.Offset = ep->ContextRecord->Esp; - StackFrame.AddrStack.Mode = AddrModeFlat; - StackFrame.AddrFrame.Offset = ep->ContextRecord->Ebp; - StackFrame.AddrFrame.Mode = AddrModeFlat; - - HANDLE hProcess = GetCurrentProcess(); - HANDLE hThread = GetCurrentThread(); - - // Initialize the symbol handler. - SymSetOptions(SYMOPT_DEFERRED_LOADS|SYMOPT_LOAD_LINES); - SymInitialize(hProcess, NULL, TRUE); - - while (true) { - if (!StackWalk(IMAGE_FILE_MACHINE_I386, hProcess, hThread, &StackFrame, - ep->ContextRecord, NULL, SymFunctionTableAccess, - SymGetModuleBase, NULL)) { - break; - } - - if (StackFrame.AddrFrame.Offset == 0) - break; - - // Print the PC in hexadecimal. - DWORD PC = StackFrame.AddrPC.Offset; - fprintf(stderr, "%08X", PC); - - // Print the parameters. Assume there are four. - fprintf(stderr, " (0x%08X 0x%08X 0x%08X 0x%08X)", StackFrame.Params[0], - StackFrame.Params[1], StackFrame.Params[2], StackFrame.Params[3]); - - // Verify the PC belongs to a module in this process. - if (!SymGetModuleBase(hProcess, PC)) { - fputs(" <unknown module>\n", stderr); - continue; - } - - // Print the symbol name. - char buffer[512]; - IMAGEHLP_SYMBOL *symbol = reinterpret_cast<IMAGEHLP_SYMBOL *>(buffer); - memset(symbol, 0, sizeof(IMAGEHLP_SYMBOL)); - symbol->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL); - symbol->MaxNameLength = 512 - sizeof(IMAGEHLP_SYMBOL); - - DWORD dwDisp; - if (!SymGetSymFromAddr(hProcess, PC, &dwDisp, symbol)) { - fputc('\n', stderr); - continue; - } - - buffer[511] = 0; - if (dwDisp > 0) - fprintf(stderr, ", %s()+%04d bytes(s)", symbol->Name, dwDisp); - else - fprintf(stderr, ", %s", symbol->Name); - - // Print the source file and line number information. - IMAGEHLP_LINE line; - memset(&line, 0, sizeof(line)); - line.SizeOfStruct = sizeof(line); - if (SymGetLineFromAddr(hProcess, PC, &dwDisp, &line)) { - fprintf(stderr, ", %s, line %d", line.FileName, line.LineNumber); - if (dwDisp > 0) - fprintf(stderr, "+%04d byte(s)", dwDisp); - } - - fputc('\n', stderr); - } - } catch (...) { - assert(!"Crashed in LLVMUnhandledExceptionFilter"); - } - - // 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) { - Cleanup(); - - // Allow normal processing to take place; i.e., the process dies. - return FALSE; -} - -// vim: sw=2 smartindent smarttab tw=80 autoindent expandtab |