1*9880d681SAndroid Build Coastguard Worker//===- Win32/Signals.cpp - Win32 Signals Implementation ---------*- C++ -*-===// 2*9880d681SAndroid Build Coastguard Worker// 3*9880d681SAndroid Build Coastguard Worker// The LLVM Compiler Infrastructure 4*9880d681SAndroid Build Coastguard Worker// 5*9880d681SAndroid Build Coastguard Worker// This file is distributed under the University of Illinois Open Source 6*9880d681SAndroid Build Coastguard Worker// License. See LICENSE.TXT for details. 7*9880d681SAndroid Build Coastguard Worker// 8*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===// 9*9880d681SAndroid Build Coastguard Worker// 10*9880d681SAndroid Build Coastguard Worker// This file provides the Win32 specific implementation of the Signals class. 11*9880d681SAndroid Build Coastguard Worker// 12*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===// 13*9880d681SAndroid Build Coastguard Worker#include "llvm/Support/FileSystem.h" 14*9880d681SAndroid Build Coastguard Worker#include "llvm/Support/Path.h" 15*9880d681SAndroid Build Coastguard Worker#include "llvm/Support/Process.h" 16*9880d681SAndroid Build Coastguard Worker#include "llvm/Support/WindowsError.h" 17*9880d681SAndroid Build Coastguard Worker#include <algorithm> 18*9880d681SAndroid Build Coastguard Worker#include <io.h> 19*9880d681SAndroid Build Coastguard Worker#include <signal.h> 20*9880d681SAndroid Build Coastguard Worker#include <stdio.h> 21*9880d681SAndroid Build Coastguard Worker 22*9880d681SAndroid Build Coastguard Worker#include "llvm/Support/Format.h" 23*9880d681SAndroid Build Coastguard Worker#include "llvm/Support/raw_ostream.h" 24*9880d681SAndroid Build Coastguard Worker 25*9880d681SAndroid Build Coastguard Worker// The Windows.h header must be after LLVM and standard headers. 26*9880d681SAndroid Build Coastguard Worker#include "WindowsSupport.h" 27*9880d681SAndroid Build Coastguard Worker 28*9880d681SAndroid Build Coastguard Worker#ifdef __MINGW32__ 29*9880d681SAndroid Build Coastguard Worker #include <imagehlp.h> 30*9880d681SAndroid Build Coastguard Worker#else 31*9880d681SAndroid Build Coastguard Worker #include <dbghelp.h> 32*9880d681SAndroid Build Coastguard Worker#endif 33*9880d681SAndroid Build Coastguard Worker#include <psapi.h> 34*9880d681SAndroid Build Coastguard Worker 35*9880d681SAndroid Build Coastguard Worker#ifdef _MSC_VER 36*9880d681SAndroid Build Coastguard Worker #pragma comment(lib, "psapi.lib") 37*9880d681SAndroid Build Coastguard Worker#elif __MINGW32__ 38*9880d681SAndroid Build Coastguard Worker #if (HAVE_LIBPSAPI != 1) 39*9880d681SAndroid Build Coastguard Worker #error "libpsapi.a should be present" 40*9880d681SAndroid Build Coastguard Worker #endif 41*9880d681SAndroid Build Coastguard Worker // The version of g++ that comes with MinGW does *not* properly understand 42*9880d681SAndroid Build Coastguard Worker // the ll format specifier for printf. However, MinGW passes the format 43*9880d681SAndroid Build Coastguard Worker // specifiers on to the MSVCRT entirely, and the CRT understands the ll 44*9880d681SAndroid Build Coastguard Worker // specifier. So these warnings are spurious in this case. Since we compile 45*9880d681SAndroid Build Coastguard Worker // with -Wall, this will generate these warnings which should be ignored. So 46*9880d681SAndroid Build Coastguard Worker // we will turn off the warnings for this just file. However, MinGW also does 47*9880d681SAndroid Build Coastguard Worker // not support push and pop for diagnostics, so we have to manually turn it 48*9880d681SAndroid Build Coastguard Worker // back on at the end of the file. 49*9880d681SAndroid Build Coastguard Worker #pragma GCC diagnostic ignored "-Wformat" 50*9880d681SAndroid Build Coastguard Worker #pragma GCC diagnostic ignored "-Wformat-extra-args" 51*9880d681SAndroid Build Coastguard Worker 52*9880d681SAndroid Build Coastguard Worker #if !defined(__MINGW64_VERSION_MAJOR) 53*9880d681SAndroid Build Coastguard Worker // MinGW.org does not have updated support for the 64-bit versions of the 54*9880d681SAndroid Build Coastguard Worker // DebugHlp APIs. So we will have to load them manually. The structures and 55*9880d681SAndroid Build Coastguard Worker // method signatures were pulled from DbgHelp.h in the Windows Platform SDK, 56*9880d681SAndroid Build Coastguard Worker // and adjusted for brevity. 57*9880d681SAndroid Build Coastguard Worker typedef struct _IMAGEHLP_LINE64 { 58*9880d681SAndroid Build Coastguard Worker DWORD SizeOfStruct; 59*9880d681SAndroid Build Coastguard Worker PVOID Key; 60*9880d681SAndroid Build Coastguard Worker DWORD LineNumber; 61*9880d681SAndroid Build Coastguard Worker PCHAR FileName; 62*9880d681SAndroid Build Coastguard Worker DWORD64 Address; 63*9880d681SAndroid Build Coastguard Worker } IMAGEHLP_LINE64, *PIMAGEHLP_LINE64; 64*9880d681SAndroid Build Coastguard Worker 65*9880d681SAndroid Build Coastguard Worker typedef struct _IMAGEHLP_SYMBOL64 { 66*9880d681SAndroid Build Coastguard Worker DWORD SizeOfStruct; 67*9880d681SAndroid Build Coastguard Worker DWORD64 Address; 68*9880d681SAndroid Build Coastguard Worker DWORD Size; 69*9880d681SAndroid Build Coastguard Worker DWORD Flags; 70*9880d681SAndroid Build Coastguard Worker DWORD MaxNameLength; 71*9880d681SAndroid Build Coastguard Worker CHAR Name[1]; 72*9880d681SAndroid Build Coastguard Worker } IMAGEHLP_SYMBOL64, *PIMAGEHLP_SYMBOL64; 73*9880d681SAndroid Build Coastguard Worker 74*9880d681SAndroid Build Coastguard Worker typedef struct _tagADDRESS64 { 75*9880d681SAndroid Build Coastguard Worker DWORD64 Offset; 76*9880d681SAndroid Build Coastguard Worker WORD Segment; 77*9880d681SAndroid Build Coastguard Worker ADDRESS_MODE Mode; 78*9880d681SAndroid Build Coastguard Worker } ADDRESS64, *LPADDRESS64; 79*9880d681SAndroid Build Coastguard Worker 80*9880d681SAndroid Build Coastguard Worker typedef struct _KDHELP64 { 81*9880d681SAndroid Build Coastguard Worker DWORD64 Thread; 82*9880d681SAndroid Build Coastguard Worker DWORD ThCallbackStack; 83*9880d681SAndroid Build Coastguard Worker DWORD ThCallbackBStore; 84*9880d681SAndroid Build Coastguard Worker DWORD NextCallback; 85*9880d681SAndroid Build Coastguard Worker DWORD FramePointer; 86*9880d681SAndroid Build Coastguard Worker DWORD64 KiCallUserMode; 87*9880d681SAndroid Build Coastguard Worker DWORD64 KeUserCallbackDispatcher; 88*9880d681SAndroid Build Coastguard Worker DWORD64 SystemRangeStart; 89*9880d681SAndroid Build Coastguard Worker DWORD64 KiUserExceptionDispatcher; 90*9880d681SAndroid Build Coastguard Worker DWORD64 StackBase; 91*9880d681SAndroid Build Coastguard Worker DWORD64 StackLimit; 92*9880d681SAndroid Build Coastguard Worker DWORD64 Reserved[5]; 93*9880d681SAndroid Build Coastguard Worker } KDHELP64, *PKDHELP64; 94*9880d681SAndroid Build Coastguard Worker 95*9880d681SAndroid Build Coastguard Worker typedef struct _tagSTACKFRAME64 { 96*9880d681SAndroid Build Coastguard Worker ADDRESS64 AddrPC; 97*9880d681SAndroid Build Coastguard Worker ADDRESS64 AddrReturn; 98*9880d681SAndroid Build Coastguard Worker ADDRESS64 AddrFrame; 99*9880d681SAndroid Build Coastguard Worker ADDRESS64 AddrStack; 100*9880d681SAndroid Build Coastguard Worker ADDRESS64 AddrBStore; 101*9880d681SAndroid Build Coastguard Worker PVOID FuncTableEntry; 102*9880d681SAndroid Build Coastguard Worker DWORD64 Params[4]; 103*9880d681SAndroid Build Coastguard Worker BOOL Far; 104*9880d681SAndroid Build Coastguard Worker BOOL Virtual; 105*9880d681SAndroid Build Coastguard Worker DWORD64 Reserved[3]; 106*9880d681SAndroid Build Coastguard Worker KDHELP64 KdHelp; 107*9880d681SAndroid Build Coastguard Worker } STACKFRAME64, *LPSTACKFRAME64; 108*9880d681SAndroid Build Coastguard Worker #endif // !defined(__MINGW64_VERSION_MAJOR) 109*9880d681SAndroid Build Coastguard Worker#endif // __MINGW32__ 110*9880d681SAndroid Build Coastguard Worker 111*9880d681SAndroid Build Coastguard Workertypedef BOOL (__stdcall *PREAD_PROCESS_MEMORY_ROUTINE64)(HANDLE hProcess, 112*9880d681SAndroid Build Coastguard Worker DWORD64 qwBaseAddress, PVOID lpBuffer, DWORD nSize, 113*9880d681SAndroid Build Coastguard Worker LPDWORD lpNumberOfBytesRead); 114*9880d681SAndroid Build Coastguard Worker 115*9880d681SAndroid Build Coastguard Workertypedef PVOID (__stdcall *PFUNCTION_TABLE_ACCESS_ROUTINE64)( HANDLE ahProcess, 116*9880d681SAndroid Build Coastguard Worker DWORD64 AddrBase); 117*9880d681SAndroid Build Coastguard Worker 118*9880d681SAndroid Build Coastguard Workertypedef DWORD64 (__stdcall *PGET_MODULE_BASE_ROUTINE64)(HANDLE hProcess, 119*9880d681SAndroid Build Coastguard Worker DWORD64 Address); 120*9880d681SAndroid Build Coastguard Worker 121*9880d681SAndroid Build Coastguard Workertypedef DWORD64 (__stdcall *PTRANSLATE_ADDRESS_ROUTINE64)(HANDLE hProcess, 122*9880d681SAndroid Build Coastguard Worker HANDLE hThread, LPADDRESS64 lpaddr); 123*9880d681SAndroid Build Coastguard Worker 124*9880d681SAndroid Build Coastguard Workertypedef BOOL(WINAPI *fpMiniDumpWriteDump)(HANDLE, DWORD, HANDLE, MINIDUMP_TYPE, 125*9880d681SAndroid Build Coastguard Worker PMINIDUMP_EXCEPTION_INFORMATION, 126*9880d681SAndroid Build Coastguard Worker PMINIDUMP_USER_STREAM_INFORMATION, 127*9880d681SAndroid Build Coastguard Worker PMINIDUMP_CALLBACK_INFORMATION); 128*9880d681SAndroid Build Coastguard Workerstatic fpMiniDumpWriteDump fMiniDumpWriteDump; 129*9880d681SAndroid Build Coastguard Worker 130*9880d681SAndroid Build Coastguard Workertypedef BOOL (WINAPI *fpStackWalk64)(DWORD, HANDLE, HANDLE, LPSTACKFRAME64, 131*9880d681SAndroid Build Coastguard Worker PVOID, PREAD_PROCESS_MEMORY_ROUTINE64, 132*9880d681SAndroid Build Coastguard Worker PFUNCTION_TABLE_ACCESS_ROUTINE64, 133*9880d681SAndroid Build Coastguard Worker PGET_MODULE_BASE_ROUTINE64, 134*9880d681SAndroid Build Coastguard Worker PTRANSLATE_ADDRESS_ROUTINE64); 135*9880d681SAndroid Build Coastguard Workerstatic fpStackWalk64 fStackWalk64; 136*9880d681SAndroid Build Coastguard Worker 137*9880d681SAndroid Build Coastguard Workertypedef DWORD64 (WINAPI *fpSymGetModuleBase64)(HANDLE, DWORD64); 138*9880d681SAndroid Build Coastguard Workerstatic fpSymGetModuleBase64 fSymGetModuleBase64; 139*9880d681SAndroid Build Coastguard Worker 140*9880d681SAndroid Build Coastguard Workertypedef BOOL (WINAPI *fpSymGetSymFromAddr64)(HANDLE, DWORD64, 141*9880d681SAndroid Build Coastguard Worker PDWORD64, PIMAGEHLP_SYMBOL64); 142*9880d681SAndroid Build Coastguard Workerstatic fpSymGetSymFromAddr64 fSymGetSymFromAddr64; 143*9880d681SAndroid Build Coastguard Worker 144*9880d681SAndroid Build Coastguard Workertypedef BOOL (WINAPI *fpSymGetLineFromAddr64)(HANDLE, DWORD64, 145*9880d681SAndroid Build Coastguard Worker PDWORD, PIMAGEHLP_LINE64); 146*9880d681SAndroid Build Coastguard Workerstatic fpSymGetLineFromAddr64 fSymGetLineFromAddr64; 147*9880d681SAndroid Build Coastguard Worker 148*9880d681SAndroid Build Coastguard Workertypedef BOOL(WINAPI *fpSymGetModuleInfo64)(HANDLE hProcess, DWORD64 dwAddr, 149*9880d681SAndroid Build Coastguard Worker PIMAGEHLP_MODULE64 ModuleInfo); 150*9880d681SAndroid Build Coastguard Workerstatic fpSymGetModuleInfo64 fSymGetModuleInfo64; 151*9880d681SAndroid Build Coastguard Worker 152*9880d681SAndroid Build Coastguard Workertypedef PVOID (WINAPI *fpSymFunctionTableAccess64)(HANDLE, DWORD64); 153*9880d681SAndroid Build Coastguard Workerstatic fpSymFunctionTableAccess64 fSymFunctionTableAccess64; 154*9880d681SAndroid Build Coastguard Worker 155*9880d681SAndroid Build Coastguard Workertypedef DWORD (WINAPI *fpSymSetOptions)(DWORD); 156*9880d681SAndroid Build Coastguard Workerstatic fpSymSetOptions fSymSetOptions; 157*9880d681SAndroid Build Coastguard Worker 158*9880d681SAndroid Build Coastguard Workertypedef BOOL (WINAPI *fpSymInitialize)(HANDLE, PCSTR, BOOL); 159*9880d681SAndroid Build Coastguard Workerstatic fpSymInitialize fSymInitialize; 160*9880d681SAndroid Build Coastguard Worker 161*9880d681SAndroid Build Coastguard Workertypedef BOOL (WINAPI *fpEnumerateLoadedModules)(HANDLE,PENUMLOADED_MODULES_CALLBACK64,PVOID); 162*9880d681SAndroid Build Coastguard Workerstatic fpEnumerateLoadedModules fEnumerateLoadedModules; 163*9880d681SAndroid Build Coastguard Worker 164*9880d681SAndroid Build Coastguard Workerstatic bool load64BitDebugHelp(void) { 165*9880d681SAndroid Build Coastguard Worker HMODULE hLib = ::LoadLibraryW(L"Dbghelp.dll"); 166*9880d681SAndroid Build Coastguard Worker if (hLib) { 167*9880d681SAndroid Build Coastguard Worker fMiniDumpWriteDump = (fpMiniDumpWriteDump) 168*9880d681SAndroid Build Coastguard Worker ::GetProcAddress(hLib, "MiniDumpWriteDump"); 169*9880d681SAndroid Build Coastguard Worker fStackWalk64 = (fpStackWalk64) 170*9880d681SAndroid Build Coastguard Worker ::GetProcAddress(hLib, "StackWalk64"); 171*9880d681SAndroid Build Coastguard Worker fSymGetModuleBase64 = (fpSymGetModuleBase64) 172*9880d681SAndroid Build Coastguard Worker ::GetProcAddress(hLib, "SymGetModuleBase64"); 173*9880d681SAndroid Build Coastguard Worker fSymGetSymFromAddr64 = (fpSymGetSymFromAddr64) 174*9880d681SAndroid Build Coastguard Worker ::GetProcAddress(hLib, "SymGetSymFromAddr64"); 175*9880d681SAndroid Build Coastguard Worker fSymGetLineFromAddr64 = (fpSymGetLineFromAddr64) 176*9880d681SAndroid Build Coastguard Worker ::GetProcAddress(hLib, "SymGetLineFromAddr64"); 177*9880d681SAndroid Build Coastguard Worker fSymGetModuleInfo64 = (fpSymGetModuleInfo64) 178*9880d681SAndroid Build Coastguard Worker ::GetProcAddress(hLib, "SymGetModuleInfo64"); 179*9880d681SAndroid Build Coastguard Worker fSymFunctionTableAccess64 = (fpSymFunctionTableAccess64) 180*9880d681SAndroid Build Coastguard Worker ::GetProcAddress(hLib, "SymFunctionTableAccess64"); 181*9880d681SAndroid Build Coastguard Worker fSymSetOptions = (fpSymSetOptions)::GetProcAddress(hLib, "SymSetOptions"); 182*9880d681SAndroid Build Coastguard Worker fSymInitialize = (fpSymInitialize)::GetProcAddress(hLib, "SymInitialize"); 183*9880d681SAndroid Build Coastguard Worker fEnumerateLoadedModules = (fpEnumerateLoadedModules) 184*9880d681SAndroid Build Coastguard Worker ::GetProcAddress(hLib, "EnumerateLoadedModules64"); 185*9880d681SAndroid Build Coastguard Worker } 186*9880d681SAndroid Build Coastguard Worker return fStackWalk64 && fSymInitialize && fSymSetOptions && fMiniDumpWriteDump; 187*9880d681SAndroid Build Coastguard Worker} 188*9880d681SAndroid Build Coastguard Worker 189*9880d681SAndroid Build Coastguard Workerusing namespace llvm; 190*9880d681SAndroid Build Coastguard Worker 191*9880d681SAndroid Build Coastguard Worker// Forward declare. 192*9880d681SAndroid Build Coastguard Workerstatic LONG WINAPI LLVMUnhandledExceptionFilter(LPEXCEPTION_POINTERS ep); 193*9880d681SAndroid Build Coastguard Workerstatic BOOL WINAPI LLVMConsoleCtrlHandler(DWORD dwCtrlType); 194*9880d681SAndroid Build Coastguard Worker 195*9880d681SAndroid Build Coastguard Worker// InterruptFunction - The function to call if ctrl-c is pressed. 196*9880d681SAndroid Build Coastguard Workerstatic void (*InterruptFunction)() = 0; 197*9880d681SAndroid Build Coastguard Worker 198*9880d681SAndroid Build Coastguard Workerstatic std::vector<std::string> *FilesToRemove = NULL; 199*9880d681SAndroid Build Coastguard Workerstatic bool RegisteredUnhandledExceptionFilter = false; 200*9880d681SAndroid Build Coastguard Workerstatic bool CleanupExecuted = false; 201*9880d681SAndroid Build Coastguard Workerstatic PTOP_LEVEL_EXCEPTION_FILTER OldFilter = NULL; 202*9880d681SAndroid Build Coastguard Worker 203*9880d681SAndroid Build Coastguard Worker// Windows creates a new thread to execute the console handler when an event 204*9880d681SAndroid Build Coastguard Worker// (such as CTRL/C) occurs. This causes concurrency issues with the above 205*9880d681SAndroid Build Coastguard Worker// globals which this critical section addresses. 206*9880d681SAndroid Build Coastguard Workerstatic CRITICAL_SECTION CriticalSection; 207*9880d681SAndroid Build Coastguard Workerstatic bool CriticalSectionInitialized = false; 208*9880d681SAndroid Build Coastguard Worker 209*9880d681SAndroid Build Coastguard Workerstatic StringRef Argv0; 210*9880d681SAndroid Build Coastguard Worker 211*9880d681SAndroid Build Coastguard Workerenum { 212*9880d681SAndroid Build Coastguard Worker#if defined(_M_X64) 213*9880d681SAndroid Build Coastguard Worker NativeMachineType = IMAGE_FILE_MACHINE_AMD64 214*9880d681SAndroid Build Coastguard Worker#else 215*9880d681SAndroid Build Coastguard Worker NativeMachineType = IMAGE_FILE_MACHINE_I386 216*9880d681SAndroid Build Coastguard Worker#endif 217*9880d681SAndroid Build Coastguard Worker}; 218*9880d681SAndroid Build Coastguard Worker 219*9880d681SAndroid Build Coastguard Workerstatic bool printStackTraceWithLLVMSymbolizer(llvm::raw_ostream &OS, 220*9880d681SAndroid Build Coastguard Worker HANDLE hProcess, HANDLE hThread, 221*9880d681SAndroid Build Coastguard Worker STACKFRAME64 &StackFrameOrig, 222*9880d681SAndroid Build Coastguard Worker CONTEXT *ContextOrig) { 223*9880d681SAndroid Build Coastguard Worker // StackWalk64 modifies the incoming stack frame and context, so copy them. 224*9880d681SAndroid Build Coastguard Worker STACKFRAME64 StackFrame = StackFrameOrig; 225*9880d681SAndroid Build Coastguard Worker 226*9880d681SAndroid Build Coastguard Worker // Copy the register context so that we don't modify it while we unwind. We 227*9880d681SAndroid Build Coastguard Worker // could use InitializeContext + CopyContext, but that's only required to get 228*9880d681SAndroid Build Coastguard Worker // at AVX registers, which typically aren't needed by StackWalk64. Reduce the 229*9880d681SAndroid Build Coastguard Worker // flag set to indicate that there's less data. 230*9880d681SAndroid Build Coastguard Worker CONTEXT Context = *ContextOrig; 231*9880d681SAndroid Build Coastguard Worker Context.ContextFlags = CONTEXT_CONTROL | CONTEXT_INTEGER; 232*9880d681SAndroid Build Coastguard Worker 233*9880d681SAndroid Build Coastguard Worker static void *StackTrace[256]; 234*9880d681SAndroid Build Coastguard Worker size_t Depth = 0; 235*9880d681SAndroid Build Coastguard Worker while (fStackWalk64(NativeMachineType, hProcess, hThread, &StackFrame, 236*9880d681SAndroid Build Coastguard Worker &Context, 0, fSymFunctionTableAccess64, 237*9880d681SAndroid Build Coastguard Worker fSymGetModuleBase64, 0)) { 238*9880d681SAndroid Build Coastguard Worker if (StackFrame.AddrFrame.Offset == 0) 239*9880d681SAndroid Build Coastguard Worker break; 240*9880d681SAndroid Build Coastguard Worker StackTrace[Depth++] = (void *)(uintptr_t)StackFrame.AddrPC.Offset; 241*9880d681SAndroid Build Coastguard Worker if (Depth >= array_lengthof(StackTrace)) 242*9880d681SAndroid Build Coastguard Worker break; 243*9880d681SAndroid Build Coastguard Worker } 244*9880d681SAndroid Build Coastguard Worker 245*9880d681SAndroid Build Coastguard Worker return printSymbolizedStackTrace(Argv0, &StackTrace[0], Depth, OS); 246*9880d681SAndroid Build Coastguard Worker} 247*9880d681SAndroid Build Coastguard Worker 248*9880d681SAndroid Build Coastguard Workernamespace { 249*9880d681SAndroid Build Coastguard Workerstruct FindModuleData { 250*9880d681SAndroid Build Coastguard Worker void **StackTrace; 251*9880d681SAndroid Build Coastguard Worker int Depth; 252*9880d681SAndroid Build Coastguard Worker const char **Modules; 253*9880d681SAndroid Build Coastguard Worker intptr_t *Offsets; 254*9880d681SAndroid Build Coastguard Worker StringSaver *StrPool; 255*9880d681SAndroid Build Coastguard Worker}; 256*9880d681SAndroid Build Coastguard Worker} 257*9880d681SAndroid Build Coastguard Worker 258*9880d681SAndroid Build Coastguard Workerstatic BOOL CALLBACK findModuleCallback(PCSTR ModuleName, 259*9880d681SAndroid Build Coastguard Worker DWORD64 ModuleBase, ULONG ModuleSize, 260*9880d681SAndroid Build Coastguard Worker void *VoidData) { 261*9880d681SAndroid Build Coastguard Worker FindModuleData *Data = (FindModuleData*)VoidData; 262*9880d681SAndroid Build Coastguard Worker intptr_t Beg = ModuleBase; 263*9880d681SAndroid Build Coastguard Worker intptr_t End = Beg + ModuleSize; 264*9880d681SAndroid Build Coastguard Worker for (int I = 0; I < Data->Depth; I++) { 265*9880d681SAndroid Build Coastguard Worker if (Data->Modules[I]) 266*9880d681SAndroid Build Coastguard Worker continue; 267*9880d681SAndroid Build Coastguard Worker intptr_t Addr = (intptr_t)Data->StackTrace[I]; 268*9880d681SAndroid Build Coastguard Worker if (Beg <= Addr && Addr < End) { 269*9880d681SAndroid Build Coastguard Worker Data->Modules[I] = Data->StrPool->save(ModuleName); 270*9880d681SAndroid Build Coastguard Worker Data->Offsets[I] = Addr - Beg; 271*9880d681SAndroid Build Coastguard Worker } 272*9880d681SAndroid Build Coastguard Worker } 273*9880d681SAndroid Build Coastguard Worker return TRUE; 274*9880d681SAndroid Build Coastguard Worker} 275*9880d681SAndroid Build Coastguard Worker 276*9880d681SAndroid Build Coastguard Workerstatic bool findModulesAndOffsets(void **StackTrace, int Depth, 277*9880d681SAndroid Build Coastguard Worker const char **Modules, intptr_t *Offsets, 278*9880d681SAndroid Build Coastguard Worker const char *MainExecutableName, 279*9880d681SAndroid Build Coastguard Worker StringSaver &StrPool) { 280*9880d681SAndroid Build Coastguard Worker if (!fEnumerateLoadedModules) 281*9880d681SAndroid Build Coastguard Worker return false; 282*9880d681SAndroid Build Coastguard Worker FindModuleData Data; 283*9880d681SAndroid Build Coastguard Worker Data.StackTrace = StackTrace; 284*9880d681SAndroid Build Coastguard Worker Data.Depth = Depth; 285*9880d681SAndroid Build Coastguard Worker Data.Modules = Modules; 286*9880d681SAndroid Build Coastguard Worker Data.Offsets = Offsets; 287*9880d681SAndroid Build Coastguard Worker Data.StrPool = &StrPool; 288*9880d681SAndroid Build Coastguard Worker fEnumerateLoadedModules(GetCurrentProcess(), findModuleCallback, &Data); 289*9880d681SAndroid Build Coastguard Worker return true; 290*9880d681SAndroid Build Coastguard Worker} 291*9880d681SAndroid Build Coastguard Worker 292*9880d681SAndroid Build Coastguard Workerstatic void PrintStackTraceForThread(llvm::raw_ostream &OS, HANDLE hProcess, 293*9880d681SAndroid Build Coastguard Worker HANDLE hThread, STACKFRAME64 &StackFrame, 294*9880d681SAndroid Build Coastguard Worker CONTEXT *Context) { 295*9880d681SAndroid Build Coastguard Worker // Initialize the symbol handler. 296*9880d681SAndroid Build Coastguard Worker fSymSetOptions(SYMOPT_DEFERRED_LOADS | SYMOPT_LOAD_LINES); 297*9880d681SAndroid Build Coastguard Worker fSymInitialize(hProcess, NULL, TRUE); 298*9880d681SAndroid Build Coastguard Worker 299*9880d681SAndroid Build Coastguard Worker // Try llvm-symbolizer first. llvm-symbolizer knows how to deal with both PDBs 300*9880d681SAndroid Build Coastguard Worker // and DWARF, so it should do a good job regardless of what debug info or 301*9880d681SAndroid Build Coastguard Worker // linker is in use. 302*9880d681SAndroid Build Coastguard Worker if (printStackTraceWithLLVMSymbolizer(OS, hProcess, hThread, StackFrame, 303*9880d681SAndroid Build Coastguard Worker Context)) { 304*9880d681SAndroid Build Coastguard Worker return; 305*9880d681SAndroid Build Coastguard Worker } 306*9880d681SAndroid Build Coastguard Worker 307*9880d681SAndroid Build Coastguard Worker while (true) { 308*9880d681SAndroid Build Coastguard Worker if (!fStackWalk64(NativeMachineType, hProcess, hThread, &StackFrame, 309*9880d681SAndroid Build Coastguard Worker Context, 0, fSymFunctionTableAccess64, 310*9880d681SAndroid Build Coastguard Worker fSymGetModuleBase64, 0)) { 311*9880d681SAndroid Build Coastguard Worker break; 312*9880d681SAndroid Build Coastguard Worker } 313*9880d681SAndroid Build Coastguard Worker 314*9880d681SAndroid Build Coastguard Worker if (StackFrame.AddrFrame.Offset == 0) 315*9880d681SAndroid Build Coastguard Worker break; 316*9880d681SAndroid Build Coastguard Worker 317*9880d681SAndroid Build Coastguard Worker using namespace llvm; 318*9880d681SAndroid Build Coastguard Worker // Print the PC in hexadecimal. 319*9880d681SAndroid Build Coastguard Worker DWORD64 PC = StackFrame.AddrPC.Offset; 320*9880d681SAndroid Build Coastguard Worker#if defined(_M_X64) 321*9880d681SAndroid Build Coastguard Worker OS << format("0x%016llX", PC); 322*9880d681SAndroid Build Coastguard Worker#elif defined(_M_IX86) 323*9880d681SAndroid Build Coastguard Worker OS << format("0x%08lX", static_cast<DWORD>(PC)); 324*9880d681SAndroid Build Coastguard Worker#endif 325*9880d681SAndroid Build Coastguard Worker 326*9880d681SAndroid Build Coastguard Worker// Print the parameters. Assume there are four. 327*9880d681SAndroid Build Coastguard Worker#if defined(_M_X64) 328*9880d681SAndroid Build Coastguard Worker OS << format(" (0x%016llX 0x%016llX 0x%016llX 0x%016llX)", 329*9880d681SAndroid Build Coastguard Worker StackFrame.Params[0], StackFrame.Params[1], StackFrame.Params[2], 330*9880d681SAndroid Build Coastguard Worker StackFrame.Params[3]); 331*9880d681SAndroid Build Coastguard Worker#elif defined(_M_IX86) 332*9880d681SAndroid Build Coastguard Worker OS << format(" (0x%08lX 0x%08lX 0x%08lX 0x%08lX)", 333*9880d681SAndroid Build Coastguard Worker static_cast<DWORD>(StackFrame.Params[0]), 334*9880d681SAndroid Build Coastguard Worker static_cast<DWORD>(StackFrame.Params[1]), 335*9880d681SAndroid Build Coastguard Worker static_cast<DWORD>(StackFrame.Params[2]), 336*9880d681SAndroid Build Coastguard Worker static_cast<DWORD>(StackFrame.Params[3])); 337*9880d681SAndroid Build Coastguard Worker#endif 338*9880d681SAndroid Build Coastguard Worker // Verify the PC belongs to a module in this process. 339*9880d681SAndroid Build Coastguard Worker if (!fSymGetModuleBase64(hProcess, PC)) { 340*9880d681SAndroid Build Coastguard Worker OS << " <unknown module>\n"; 341*9880d681SAndroid Build Coastguard Worker continue; 342*9880d681SAndroid Build Coastguard Worker } 343*9880d681SAndroid Build Coastguard Worker 344*9880d681SAndroid Build Coastguard Worker // Print the symbol name. 345*9880d681SAndroid Build Coastguard Worker char buffer[512]; 346*9880d681SAndroid Build Coastguard Worker IMAGEHLP_SYMBOL64 *symbol = reinterpret_cast<IMAGEHLP_SYMBOL64 *>(buffer); 347*9880d681SAndroid Build Coastguard Worker memset(symbol, 0, sizeof(IMAGEHLP_SYMBOL64)); 348*9880d681SAndroid Build Coastguard Worker symbol->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL64); 349*9880d681SAndroid Build Coastguard Worker symbol->MaxNameLength = 512 - sizeof(IMAGEHLP_SYMBOL64); 350*9880d681SAndroid Build Coastguard Worker 351*9880d681SAndroid Build Coastguard Worker DWORD64 dwDisp; 352*9880d681SAndroid Build Coastguard Worker if (!fSymGetSymFromAddr64(hProcess, PC, &dwDisp, symbol)) { 353*9880d681SAndroid Build Coastguard Worker OS << '\n'; 354*9880d681SAndroid Build Coastguard Worker continue; 355*9880d681SAndroid Build Coastguard Worker } 356*9880d681SAndroid Build Coastguard Worker 357*9880d681SAndroid Build Coastguard Worker buffer[511] = 0; 358*9880d681SAndroid Build Coastguard Worker if (dwDisp > 0) 359*9880d681SAndroid Build Coastguard Worker OS << format(", %s() + 0x%llX bytes(s)", (const char*)symbol->Name, 360*9880d681SAndroid Build Coastguard Worker dwDisp); 361*9880d681SAndroid Build Coastguard Worker else 362*9880d681SAndroid Build Coastguard Worker OS << format(", %s", (const char*)symbol->Name); 363*9880d681SAndroid Build Coastguard Worker 364*9880d681SAndroid Build Coastguard Worker // Print the source file and line number information. 365*9880d681SAndroid Build Coastguard Worker IMAGEHLP_LINE64 line = {}; 366*9880d681SAndroid Build Coastguard Worker DWORD dwLineDisp; 367*9880d681SAndroid Build Coastguard Worker line.SizeOfStruct = sizeof(line); 368*9880d681SAndroid Build Coastguard Worker if (fSymGetLineFromAddr64(hProcess, PC, &dwLineDisp, &line)) { 369*9880d681SAndroid Build Coastguard Worker OS << format(", %s, line %lu", line.FileName, line.LineNumber); 370*9880d681SAndroid Build Coastguard Worker if (dwLineDisp > 0) 371*9880d681SAndroid Build Coastguard Worker OS << format(" + 0x%lX byte(s)", dwLineDisp); 372*9880d681SAndroid Build Coastguard Worker } 373*9880d681SAndroid Build Coastguard Worker 374*9880d681SAndroid Build Coastguard Worker OS << '\n'; 375*9880d681SAndroid Build Coastguard Worker } 376*9880d681SAndroid Build Coastguard Worker} 377*9880d681SAndroid Build Coastguard Worker 378*9880d681SAndroid Build Coastguard Workernamespace llvm { 379*9880d681SAndroid Build Coastguard Worker 380*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===// 381*9880d681SAndroid Build Coastguard Worker//=== WARNING: Implementation here must contain only Win32 specific code 382*9880d681SAndroid Build Coastguard Worker//=== and must not be UNIX code 383*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===// 384*9880d681SAndroid Build Coastguard Worker 385*9880d681SAndroid Build Coastguard Worker#ifdef _MSC_VER 386*9880d681SAndroid Build Coastguard Worker/// AvoidMessageBoxHook - Emulates hitting "retry" from an "abort, retry, 387*9880d681SAndroid Build Coastguard Worker/// ignore" CRT debug report dialog. "retry" raises an exception which 388*9880d681SAndroid Build Coastguard Worker/// ultimately triggers our stack dumper. 389*9880d681SAndroid Build Coastguard Workerstatic LLVM_ATTRIBUTE_UNUSED int 390*9880d681SAndroid Build Coastguard WorkerAvoidMessageBoxHook(int ReportType, char *Message, int *Return) { 391*9880d681SAndroid Build Coastguard Worker // Set *Return to the retry code for the return value of _CrtDbgReport: 392*9880d681SAndroid Build Coastguard Worker // http://msdn.microsoft.com/en-us/library/8hyw4sy7(v=vs.71).aspx 393*9880d681SAndroid Build Coastguard Worker // This may also trigger just-in-time debugging via DebugBreak(). 394*9880d681SAndroid Build Coastguard Worker if (Return) 395*9880d681SAndroid Build Coastguard Worker *Return = 1; 396*9880d681SAndroid Build Coastguard Worker // Don't call _CrtDbgReport. 397*9880d681SAndroid Build Coastguard Worker return TRUE; 398*9880d681SAndroid Build Coastguard Worker} 399*9880d681SAndroid Build Coastguard Worker 400*9880d681SAndroid Build Coastguard Worker#endif 401*9880d681SAndroid Build Coastguard Worker 402*9880d681SAndroid Build Coastguard Workerextern "C" void HandleAbort(int Sig) { 403*9880d681SAndroid Build Coastguard Worker if (Sig == SIGABRT) { 404*9880d681SAndroid Build Coastguard Worker LLVM_BUILTIN_TRAP; 405*9880d681SAndroid Build Coastguard Worker } 406*9880d681SAndroid Build Coastguard Worker} 407*9880d681SAndroid Build Coastguard Worker 408*9880d681SAndroid Build Coastguard Workerstatic void InitializeThreading() { 409*9880d681SAndroid Build Coastguard Worker if (CriticalSectionInitialized) 410*9880d681SAndroid Build Coastguard Worker return; 411*9880d681SAndroid Build Coastguard Worker 412*9880d681SAndroid Build Coastguard Worker // Now's the time to create the critical section. This is the first time 413*9880d681SAndroid Build Coastguard Worker // through here, and there's only one thread. 414*9880d681SAndroid Build Coastguard Worker InitializeCriticalSection(&CriticalSection); 415*9880d681SAndroid Build Coastguard Worker CriticalSectionInitialized = true; 416*9880d681SAndroid Build Coastguard Worker} 417*9880d681SAndroid Build Coastguard Worker 418*9880d681SAndroid Build Coastguard Workerstatic void RegisterHandler() { 419*9880d681SAndroid Build Coastguard Worker // If we cannot load up the APIs (which would be unexpected as they should 420*9880d681SAndroid Build Coastguard Worker // exist on every version of Windows we support), we will bail out since 421*9880d681SAndroid Build Coastguard Worker // there would be nothing to report. 422*9880d681SAndroid Build Coastguard Worker if (!load64BitDebugHelp()) { 423*9880d681SAndroid Build Coastguard Worker assert(false && "These APIs should always be available"); 424*9880d681SAndroid Build Coastguard Worker return; 425*9880d681SAndroid Build Coastguard Worker } 426*9880d681SAndroid Build Coastguard Worker 427*9880d681SAndroid Build Coastguard Worker if (RegisteredUnhandledExceptionFilter) { 428*9880d681SAndroid Build Coastguard Worker EnterCriticalSection(&CriticalSection); 429*9880d681SAndroid Build Coastguard Worker return; 430*9880d681SAndroid Build Coastguard Worker } 431*9880d681SAndroid Build Coastguard Worker 432*9880d681SAndroid Build Coastguard Worker InitializeThreading(); 433*9880d681SAndroid Build Coastguard Worker 434*9880d681SAndroid Build Coastguard Worker // Enter it immediately. Now if someone hits CTRL/C, the console handler 435*9880d681SAndroid Build Coastguard Worker // can't proceed until the globals are updated. 436*9880d681SAndroid Build Coastguard Worker EnterCriticalSection(&CriticalSection); 437*9880d681SAndroid Build Coastguard Worker 438*9880d681SAndroid Build Coastguard Worker RegisteredUnhandledExceptionFilter = true; 439*9880d681SAndroid Build Coastguard Worker OldFilter = SetUnhandledExceptionFilter(LLVMUnhandledExceptionFilter); 440*9880d681SAndroid Build Coastguard Worker SetConsoleCtrlHandler(LLVMConsoleCtrlHandler, TRUE); 441*9880d681SAndroid Build Coastguard Worker 442*9880d681SAndroid Build Coastguard Worker // IMPORTANT NOTE: Caller must call LeaveCriticalSection(&CriticalSection) or 443*9880d681SAndroid Build Coastguard Worker // else multi-threading problems will ensue. 444*9880d681SAndroid Build Coastguard Worker} 445*9880d681SAndroid Build Coastguard Worker 446*9880d681SAndroid Build Coastguard Worker// RemoveFileOnSignal - The public API 447*9880d681SAndroid Build Coastguard Workerbool sys::RemoveFileOnSignal(StringRef Filename, std::string* ErrMsg) { 448*9880d681SAndroid Build Coastguard Worker RegisterHandler(); 449*9880d681SAndroid Build Coastguard Worker 450*9880d681SAndroid Build Coastguard Worker if (CleanupExecuted) { 451*9880d681SAndroid Build Coastguard Worker if (ErrMsg) 452*9880d681SAndroid Build Coastguard Worker *ErrMsg = "Process terminating -- cannot register for removal"; 453*9880d681SAndroid Build Coastguard Worker return true; 454*9880d681SAndroid Build Coastguard Worker } 455*9880d681SAndroid Build Coastguard Worker 456*9880d681SAndroid Build Coastguard Worker if (FilesToRemove == NULL) 457*9880d681SAndroid Build Coastguard Worker FilesToRemove = new std::vector<std::string>; 458*9880d681SAndroid Build Coastguard Worker 459*9880d681SAndroid Build Coastguard Worker FilesToRemove->push_back(Filename); 460*9880d681SAndroid Build Coastguard Worker 461*9880d681SAndroid Build Coastguard Worker LeaveCriticalSection(&CriticalSection); 462*9880d681SAndroid Build Coastguard Worker return false; 463*9880d681SAndroid Build Coastguard Worker} 464*9880d681SAndroid Build Coastguard Worker 465*9880d681SAndroid Build Coastguard Worker// DontRemoveFileOnSignal - The public API 466*9880d681SAndroid Build Coastguard Workervoid sys::DontRemoveFileOnSignal(StringRef Filename) { 467*9880d681SAndroid Build Coastguard Worker if (FilesToRemove == NULL) 468*9880d681SAndroid Build Coastguard Worker return; 469*9880d681SAndroid Build Coastguard Worker 470*9880d681SAndroid Build Coastguard Worker RegisterHandler(); 471*9880d681SAndroid Build Coastguard Worker 472*9880d681SAndroid Build Coastguard Worker std::vector<std::string>::reverse_iterator I = 473*9880d681SAndroid Build Coastguard Worker std::find(FilesToRemove->rbegin(), FilesToRemove->rend(), Filename); 474*9880d681SAndroid Build Coastguard Worker if (I != FilesToRemove->rend()) 475*9880d681SAndroid Build Coastguard Worker FilesToRemove->erase(I.base()-1); 476*9880d681SAndroid Build Coastguard Worker 477*9880d681SAndroid Build Coastguard Worker LeaveCriticalSection(&CriticalSection); 478*9880d681SAndroid Build Coastguard Worker} 479*9880d681SAndroid Build Coastguard Worker 480*9880d681SAndroid Build Coastguard Workervoid sys::DisableSystemDialogsOnCrash() { 481*9880d681SAndroid Build Coastguard Worker // Crash to stack trace handler on abort. 482*9880d681SAndroid Build Coastguard Worker signal(SIGABRT, HandleAbort); 483*9880d681SAndroid Build Coastguard Worker 484*9880d681SAndroid Build Coastguard Worker // The following functions are not reliably accessible on MinGW. 485*9880d681SAndroid Build Coastguard Worker#ifdef _MSC_VER 486*9880d681SAndroid Build Coastguard Worker // We're already handling writing a "something went wrong" message. 487*9880d681SAndroid Build Coastguard Worker _set_abort_behavior(0, _WRITE_ABORT_MSG); 488*9880d681SAndroid Build Coastguard Worker // Disable Dr. Watson. 489*9880d681SAndroid Build Coastguard Worker _set_abort_behavior(0, _CALL_REPORTFAULT); 490*9880d681SAndroid Build Coastguard Worker _CrtSetReportHook(AvoidMessageBoxHook); 491*9880d681SAndroid Build Coastguard Worker#endif 492*9880d681SAndroid Build Coastguard Worker 493*9880d681SAndroid Build Coastguard Worker // Disable standard error dialog box. 494*9880d681SAndroid Build Coastguard Worker SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX | 495*9880d681SAndroid Build Coastguard Worker SEM_NOOPENFILEERRORBOX); 496*9880d681SAndroid Build Coastguard Worker _set_error_mode(_OUT_TO_STDERR); 497*9880d681SAndroid Build Coastguard Worker} 498*9880d681SAndroid Build Coastguard Worker 499*9880d681SAndroid Build Coastguard Worker/// PrintStackTraceOnErrorSignal - When an error signal (such as SIBABRT or 500*9880d681SAndroid Build Coastguard Worker/// SIGSEGV) is delivered to the process, print a stack trace and then exit. 501*9880d681SAndroid Build Coastguard Workervoid sys::PrintStackTraceOnErrorSignal(StringRef Argv0, 502*9880d681SAndroid Build Coastguard Worker bool DisableCrashReporting) { 503*9880d681SAndroid Build Coastguard Worker ::Argv0 = Argv0; 504*9880d681SAndroid Build Coastguard Worker 505*9880d681SAndroid Build Coastguard Worker if (DisableCrashReporting || getenv("LLVM_DISABLE_CRASH_REPORT")) 506*9880d681SAndroid Build Coastguard Worker Process::PreventCoreFiles(); 507*9880d681SAndroid Build Coastguard Worker 508*9880d681SAndroid Build Coastguard Worker DisableSystemDialogsOnCrash(); 509*9880d681SAndroid Build Coastguard Worker RegisterHandler(); 510*9880d681SAndroid Build Coastguard Worker LeaveCriticalSection(&CriticalSection); 511*9880d681SAndroid Build Coastguard Worker} 512*9880d681SAndroid Build Coastguard Worker} 513*9880d681SAndroid Build Coastguard Worker 514*9880d681SAndroid Build Coastguard Worker#if defined(__MINGW32__) && !defined(__MINGW64_VERSION_MAJOR) 515*9880d681SAndroid Build Coastguard Worker// Provide a prototype for RtlCaptureContext, mingw32 from mingw.org is 516*9880d681SAndroid Build Coastguard Worker// missing it but mingw-w64 has it. 517*9880d681SAndroid Build Coastguard Workerextern "C" VOID WINAPI RtlCaptureContext(PCONTEXT ContextRecord); 518*9880d681SAndroid Build Coastguard Worker#endif 519*9880d681SAndroid Build Coastguard Worker 520*9880d681SAndroid Build Coastguard Workervoid llvm::sys::PrintStackTrace(raw_ostream &OS) { 521*9880d681SAndroid Build Coastguard Worker STACKFRAME64 StackFrame = {}; 522*9880d681SAndroid Build Coastguard Worker CONTEXT Context = {}; 523*9880d681SAndroid Build Coastguard Worker ::RtlCaptureContext(&Context); 524*9880d681SAndroid Build Coastguard Worker#if defined(_M_X64) 525*9880d681SAndroid Build Coastguard Worker StackFrame.AddrPC.Offset = Context.Rip; 526*9880d681SAndroid Build Coastguard Worker StackFrame.AddrStack.Offset = Context.Rsp; 527*9880d681SAndroid Build Coastguard Worker StackFrame.AddrFrame.Offset = Context.Rbp; 528*9880d681SAndroid Build Coastguard Worker#else 529*9880d681SAndroid Build Coastguard Worker StackFrame.AddrPC.Offset = Context.Eip; 530*9880d681SAndroid Build Coastguard Worker StackFrame.AddrStack.Offset = Context.Esp; 531*9880d681SAndroid Build Coastguard Worker StackFrame.AddrFrame.Offset = Context.Ebp; 532*9880d681SAndroid Build Coastguard Worker#endif 533*9880d681SAndroid Build Coastguard Worker StackFrame.AddrPC.Mode = AddrModeFlat; 534*9880d681SAndroid Build Coastguard Worker StackFrame.AddrStack.Mode = AddrModeFlat; 535*9880d681SAndroid Build Coastguard Worker StackFrame.AddrFrame.Mode = AddrModeFlat; 536*9880d681SAndroid Build Coastguard Worker PrintStackTraceForThread(OS, GetCurrentProcess(), GetCurrentThread(), 537*9880d681SAndroid Build Coastguard Worker StackFrame, &Context); 538*9880d681SAndroid Build Coastguard Worker} 539*9880d681SAndroid Build Coastguard Worker 540*9880d681SAndroid Build Coastguard Worker 541*9880d681SAndroid Build Coastguard Workervoid llvm::sys::SetInterruptFunction(void (*IF)()) { 542*9880d681SAndroid Build Coastguard Worker RegisterHandler(); 543*9880d681SAndroid Build Coastguard Worker InterruptFunction = IF; 544*9880d681SAndroid Build Coastguard Worker LeaveCriticalSection(&CriticalSection); 545*9880d681SAndroid Build Coastguard Worker} 546*9880d681SAndroid Build Coastguard Worker 547*9880d681SAndroid Build Coastguard Worker 548*9880d681SAndroid Build Coastguard Worker/// AddSignalHandler - Add a function to be called when a signal is delivered 549*9880d681SAndroid Build Coastguard Worker/// to the process. The handler can have a cookie passed to it to identify 550*9880d681SAndroid Build Coastguard Worker/// what instance of the handler it is. 551*9880d681SAndroid Build Coastguard Workervoid llvm::sys::AddSignalHandler(void (*FnPtr)(void *), void *Cookie) { 552*9880d681SAndroid Build Coastguard Worker CallBacksToRun->push_back(std::make_pair(FnPtr, Cookie)); 553*9880d681SAndroid Build Coastguard Worker RegisterHandler(); 554*9880d681SAndroid Build Coastguard Worker LeaveCriticalSection(&CriticalSection); 555*9880d681SAndroid Build Coastguard Worker} 556*9880d681SAndroid Build Coastguard Worker 557*9880d681SAndroid Build Coastguard Workerstatic void Cleanup() { 558*9880d681SAndroid Build Coastguard Worker if (CleanupExecuted) 559*9880d681SAndroid Build Coastguard Worker return; 560*9880d681SAndroid Build Coastguard Worker 561*9880d681SAndroid Build Coastguard Worker EnterCriticalSection(&CriticalSection); 562*9880d681SAndroid Build Coastguard Worker 563*9880d681SAndroid Build Coastguard Worker // Prevent other thread from registering new files and directories for 564*9880d681SAndroid Build Coastguard Worker // removal, should we be executing because of the console handler callback. 565*9880d681SAndroid Build Coastguard Worker CleanupExecuted = true; 566*9880d681SAndroid Build Coastguard Worker 567*9880d681SAndroid Build Coastguard Worker // FIXME: open files cannot be deleted. 568*9880d681SAndroid Build Coastguard Worker if (FilesToRemove != NULL) 569*9880d681SAndroid Build Coastguard Worker while (!FilesToRemove->empty()) { 570*9880d681SAndroid Build Coastguard Worker llvm::sys::fs::remove(FilesToRemove->back()); 571*9880d681SAndroid Build Coastguard Worker FilesToRemove->pop_back(); 572*9880d681SAndroid Build Coastguard Worker } 573*9880d681SAndroid Build Coastguard Worker llvm::sys::RunSignalHandlers(); 574*9880d681SAndroid Build Coastguard Worker LeaveCriticalSection(&CriticalSection); 575*9880d681SAndroid Build Coastguard Worker} 576*9880d681SAndroid Build Coastguard Worker 577*9880d681SAndroid Build Coastguard Workervoid llvm::sys::RunInterruptHandlers() { 578*9880d681SAndroid Build Coastguard Worker // The interrupt handler may be called from an interrupt, but it may also be 579*9880d681SAndroid Build Coastguard Worker // called manually (such as the case of report_fatal_error with no registered 580*9880d681SAndroid Build Coastguard Worker // error handler). We must ensure that the critical section is properly 581*9880d681SAndroid Build Coastguard Worker // initialized. 582*9880d681SAndroid Build Coastguard Worker InitializeThreading(); 583*9880d681SAndroid Build Coastguard Worker Cleanup(); 584*9880d681SAndroid Build Coastguard Worker} 585*9880d681SAndroid Build Coastguard Worker 586*9880d681SAndroid Build Coastguard Worker/// \brief Find the Windows Registry Key for a given location. 587*9880d681SAndroid Build Coastguard Worker/// 588*9880d681SAndroid Build Coastguard Worker/// \returns a valid HKEY if the location exists, else NULL. 589*9880d681SAndroid Build Coastguard Workerstatic HKEY FindWERKey(const llvm::Twine &RegistryLocation) { 590*9880d681SAndroid Build Coastguard Worker HKEY Key; 591*9880d681SAndroid Build Coastguard Worker if (ERROR_SUCCESS != ::RegOpenKeyExA(HKEY_LOCAL_MACHINE, 592*9880d681SAndroid Build Coastguard Worker RegistryLocation.str().c_str(), 0, 593*9880d681SAndroid Build Coastguard Worker KEY_QUERY_VALUE | KEY_READ, &Key)) 594*9880d681SAndroid Build Coastguard Worker return NULL; 595*9880d681SAndroid Build Coastguard Worker 596*9880d681SAndroid Build Coastguard Worker return Key; 597*9880d681SAndroid Build Coastguard Worker} 598*9880d681SAndroid Build Coastguard Worker 599*9880d681SAndroid Build Coastguard Worker/// \brief Populate ResultDirectory with the value for "DumpFolder" for a given 600*9880d681SAndroid Build Coastguard Worker/// Windows Registry key. 601*9880d681SAndroid Build Coastguard Worker/// 602*9880d681SAndroid Build Coastguard Worker/// \returns true if a valid value for DumpFolder exists, false otherwise. 603*9880d681SAndroid Build Coastguard Workerstatic bool GetDumpFolder(HKEY Key, 604*9880d681SAndroid Build Coastguard Worker llvm::SmallVectorImpl<char> &ResultDirectory) { 605*9880d681SAndroid Build Coastguard Worker using llvm::sys::windows::UTF16ToUTF8; 606*9880d681SAndroid Build Coastguard Worker 607*9880d681SAndroid Build Coastguard Worker if (!Key) 608*9880d681SAndroid Build Coastguard Worker return false; 609*9880d681SAndroid Build Coastguard Worker 610*9880d681SAndroid Build Coastguard Worker DWORD BufferLengthBytes = 0; 611*9880d681SAndroid Build Coastguard Worker 612*9880d681SAndroid Build Coastguard Worker if (ERROR_SUCCESS != ::RegGetValueW(Key, 0, L"DumpFolder", REG_EXPAND_SZ, 613*9880d681SAndroid Build Coastguard Worker NULL, NULL, &BufferLengthBytes)) 614*9880d681SAndroid Build Coastguard Worker return false; 615*9880d681SAndroid Build Coastguard Worker 616*9880d681SAndroid Build Coastguard Worker SmallVector<wchar_t, MAX_PATH> Buffer(BufferLengthBytes); 617*9880d681SAndroid Build Coastguard Worker 618*9880d681SAndroid Build Coastguard Worker if (ERROR_SUCCESS != ::RegGetValueW(Key, 0, L"DumpFolder", REG_EXPAND_SZ, 619*9880d681SAndroid Build Coastguard Worker NULL, Buffer.data(), &BufferLengthBytes)) 620*9880d681SAndroid Build Coastguard Worker return false; 621*9880d681SAndroid Build Coastguard Worker 622*9880d681SAndroid Build Coastguard Worker DWORD ExpandBufferSize = ::ExpandEnvironmentStringsW(Buffer.data(), NULL, 0); 623*9880d681SAndroid Build Coastguard Worker 624*9880d681SAndroid Build Coastguard Worker if (!ExpandBufferSize) 625*9880d681SAndroid Build Coastguard Worker return false; 626*9880d681SAndroid Build Coastguard Worker 627*9880d681SAndroid Build Coastguard Worker SmallVector<wchar_t, MAX_PATH> ExpandBuffer(ExpandBufferSize); 628*9880d681SAndroid Build Coastguard Worker 629*9880d681SAndroid Build Coastguard Worker if (ExpandBufferSize != ::ExpandEnvironmentStringsW(Buffer.data(), 630*9880d681SAndroid Build Coastguard Worker ExpandBuffer.data(), 631*9880d681SAndroid Build Coastguard Worker ExpandBufferSize)) 632*9880d681SAndroid Build Coastguard Worker return false; 633*9880d681SAndroid Build Coastguard Worker 634*9880d681SAndroid Build Coastguard Worker if (UTF16ToUTF8(ExpandBuffer.data(), ExpandBufferSize - 1, ResultDirectory)) 635*9880d681SAndroid Build Coastguard Worker return false; 636*9880d681SAndroid Build Coastguard Worker 637*9880d681SAndroid Build Coastguard Worker return true; 638*9880d681SAndroid Build Coastguard Worker} 639*9880d681SAndroid Build Coastguard Worker 640*9880d681SAndroid Build Coastguard Worker/// \brief Populate ResultType with a valid MINIDUMP_TYPE based on the value of 641*9880d681SAndroid Build Coastguard Worker/// "DumpType" for a given Windows Registry key. 642*9880d681SAndroid Build Coastguard Worker/// 643*9880d681SAndroid Build Coastguard Worker/// According to 644*9880d681SAndroid Build Coastguard Worker/// https://msdn.microsoft.com/en-us/library/windows/desktop/bb787181(v=vs.85).aspx 645*9880d681SAndroid Build Coastguard Worker/// valid values for DumpType are: 646*9880d681SAndroid Build Coastguard Worker/// * 0: Custom dump 647*9880d681SAndroid Build Coastguard Worker/// * 1: Mini dump 648*9880d681SAndroid Build Coastguard Worker/// * 2: Full dump 649*9880d681SAndroid Build Coastguard Worker/// If "Custom dump" is specified then the "CustomDumpFlags" field is read 650*9880d681SAndroid Build Coastguard Worker/// containing a bitwise combination of MINIDUMP_TYPE values. 651*9880d681SAndroid Build Coastguard Worker/// 652*9880d681SAndroid Build Coastguard Worker/// \returns true if a valid value for ResultType can be set, false otherwise. 653*9880d681SAndroid Build Coastguard Workerstatic bool GetDumpType(HKEY Key, MINIDUMP_TYPE &ResultType) { 654*9880d681SAndroid Build Coastguard Worker if (!Key) 655*9880d681SAndroid Build Coastguard Worker return false; 656*9880d681SAndroid Build Coastguard Worker 657*9880d681SAndroid Build Coastguard Worker DWORD DumpType; 658*9880d681SAndroid Build Coastguard Worker DWORD TypeSize = sizeof(DumpType); 659*9880d681SAndroid Build Coastguard Worker if (ERROR_SUCCESS != ::RegGetValueW(Key, NULL, L"DumpType", RRF_RT_REG_DWORD, 660*9880d681SAndroid Build Coastguard Worker NULL, &DumpType, 661*9880d681SAndroid Build Coastguard Worker &TypeSize)) 662*9880d681SAndroid Build Coastguard Worker return false; 663*9880d681SAndroid Build Coastguard Worker 664*9880d681SAndroid Build Coastguard Worker switch (DumpType) { 665*9880d681SAndroid Build Coastguard Worker case 0: { 666*9880d681SAndroid Build Coastguard Worker DWORD Flags = 0; 667*9880d681SAndroid Build Coastguard Worker if (ERROR_SUCCESS != ::RegGetValueW(Key, NULL, L"CustomDumpFlags", 668*9880d681SAndroid Build Coastguard Worker RRF_RT_REG_DWORD, NULL, &Flags, 669*9880d681SAndroid Build Coastguard Worker &TypeSize)) 670*9880d681SAndroid Build Coastguard Worker return false; 671*9880d681SAndroid Build Coastguard Worker 672*9880d681SAndroid Build Coastguard Worker ResultType = static_cast<MINIDUMP_TYPE>(Flags); 673*9880d681SAndroid Build Coastguard Worker break; 674*9880d681SAndroid Build Coastguard Worker } 675*9880d681SAndroid Build Coastguard Worker case 1: 676*9880d681SAndroid Build Coastguard Worker ResultType = MiniDumpNormal; 677*9880d681SAndroid Build Coastguard Worker break; 678*9880d681SAndroid Build Coastguard Worker case 2: 679*9880d681SAndroid Build Coastguard Worker ResultType = MiniDumpWithFullMemory; 680*9880d681SAndroid Build Coastguard Worker break; 681*9880d681SAndroid Build Coastguard Worker default: 682*9880d681SAndroid Build Coastguard Worker return false; 683*9880d681SAndroid Build Coastguard Worker } 684*9880d681SAndroid Build Coastguard Worker return true; 685*9880d681SAndroid Build Coastguard Worker} 686*9880d681SAndroid Build Coastguard Worker 687*9880d681SAndroid Build Coastguard Worker/// \brief Write a Windows dump file containing process information that can be 688*9880d681SAndroid Build Coastguard Worker/// used for post-mortem debugging. 689*9880d681SAndroid Build Coastguard Worker/// 690*9880d681SAndroid Build Coastguard Worker/// \returns zero error code if a mini dump created, actual error code 691*9880d681SAndroid Build Coastguard Worker/// otherwise. 692*9880d681SAndroid Build Coastguard Workerstatic std::error_code WINAPI 693*9880d681SAndroid Build Coastguard WorkerWriteWindowsDumpFile(PMINIDUMP_EXCEPTION_INFORMATION ExceptionInfo) { 694*9880d681SAndroid Build Coastguard Worker using namespace llvm; 695*9880d681SAndroid Build Coastguard Worker using namespace llvm::sys; 696*9880d681SAndroid Build Coastguard Worker 697*9880d681SAndroid Build Coastguard Worker std::string MainExecutableName = fs::getMainExecutable(nullptr, nullptr); 698*9880d681SAndroid Build Coastguard Worker StringRef ProgramName; 699*9880d681SAndroid Build Coastguard Worker 700*9880d681SAndroid Build Coastguard Worker if (MainExecutableName.empty()) { 701*9880d681SAndroid Build Coastguard Worker // If we can't get the executable filename, 702*9880d681SAndroid Build Coastguard Worker // things are in worse shape than we realize 703*9880d681SAndroid Build Coastguard Worker // and we should just bail out. 704*9880d681SAndroid Build Coastguard Worker return mapWindowsError(::GetLastError()); 705*9880d681SAndroid Build Coastguard Worker } 706*9880d681SAndroid Build Coastguard Worker 707*9880d681SAndroid Build Coastguard Worker ProgramName = path::filename(MainExecutableName.c_str()); 708*9880d681SAndroid Build Coastguard Worker 709*9880d681SAndroid Build Coastguard Worker // The Windows Registry location as specified at 710*9880d681SAndroid Build Coastguard Worker // https://msdn.microsoft.com/en-us/library/windows/desktop/bb787181%28v=vs.85%29.aspx 711*9880d681SAndroid Build Coastguard Worker // "Collecting User-Mode Dumps" that may optionally be set to collect crash 712*9880d681SAndroid Build Coastguard Worker // dumps in a specified location. 713*9880d681SAndroid Build Coastguard Worker StringRef LocalDumpsRegistryLocation = 714*9880d681SAndroid Build Coastguard Worker "SOFTWARE\\Microsoft\\Windows\\Windows Error Reporting\\LocalDumps"; 715*9880d681SAndroid Build Coastguard Worker 716*9880d681SAndroid Build Coastguard Worker // The key pointing to the Registry location that may contain global crash 717*9880d681SAndroid Build Coastguard Worker // dump settings. This will be NULL if the location can not be found. 718*9880d681SAndroid Build Coastguard Worker ScopedRegHandle DefaultLocalDumpsKey(FindWERKey(LocalDumpsRegistryLocation)); 719*9880d681SAndroid Build Coastguard Worker 720*9880d681SAndroid Build Coastguard Worker // The key pointing to the Registry location that may contain 721*9880d681SAndroid Build Coastguard Worker // application-specific crash dump settings. This will be NULL if the 722*9880d681SAndroid Build Coastguard Worker // location can not be found. 723*9880d681SAndroid Build Coastguard Worker ScopedRegHandle AppSpecificKey( 724*9880d681SAndroid Build Coastguard Worker FindWERKey(Twine(LocalDumpsRegistryLocation) + "\\" + ProgramName)); 725*9880d681SAndroid Build Coastguard Worker 726*9880d681SAndroid Build Coastguard Worker // Look to see if a dump type is specified in the registry; first with the 727*9880d681SAndroid Build Coastguard Worker // app-specific key and failing that with the global key. If none are found 728*9880d681SAndroid Build Coastguard Worker // default to a normal dump (GetDumpType will return false either if the key 729*9880d681SAndroid Build Coastguard Worker // is NULL or if there is no valid DumpType value at its location). 730*9880d681SAndroid Build Coastguard Worker MINIDUMP_TYPE DumpType; 731*9880d681SAndroid Build Coastguard Worker if (!GetDumpType(AppSpecificKey, DumpType)) 732*9880d681SAndroid Build Coastguard Worker if (!GetDumpType(DefaultLocalDumpsKey, DumpType)) 733*9880d681SAndroid Build Coastguard Worker DumpType = MiniDumpNormal; 734*9880d681SAndroid Build Coastguard Worker 735*9880d681SAndroid Build Coastguard Worker // Look to see if a dump location is specified in the registry; first with the 736*9880d681SAndroid Build Coastguard Worker // app-specific key and failing that with the global key. If none are found 737*9880d681SAndroid Build Coastguard Worker // we'll just create the dump file in the default temporary file location 738*9880d681SAndroid Build Coastguard Worker // (GetDumpFolder will return false either if the key is NULL or if there is 739*9880d681SAndroid Build Coastguard Worker // no valid DumpFolder value at its location). 740*9880d681SAndroid Build Coastguard Worker bool ExplicitDumpDirectorySet = true; 741*9880d681SAndroid Build Coastguard Worker SmallString<MAX_PATH> DumpDirectory; 742*9880d681SAndroid Build Coastguard Worker if (!GetDumpFolder(AppSpecificKey, DumpDirectory)) 743*9880d681SAndroid Build Coastguard Worker if (!GetDumpFolder(DefaultLocalDumpsKey, DumpDirectory)) 744*9880d681SAndroid Build Coastguard Worker ExplicitDumpDirectorySet = false; 745*9880d681SAndroid Build Coastguard Worker 746*9880d681SAndroid Build Coastguard Worker int FD; 747*9880d681SAndroid Build Coastguard Worker SmallString<MAX_PATH> DumpPath; 748*9880d681SAndroid Build Coastguard Worker 749*9880d681SAndroid Build Coastguard Worker if (ExplicitDumpDirectorySet) { 750*9880d681SAndroid Build Coastguard Worker if (std::error_code EC = fs::create_directories(DumpDirectory)) 751*9880d681SAndroid Build Coastguard Worker return EC; 752*9880d681SAndroid Build Coastguard Worker if (std::error_code EC = fs::createUniqueFile( 753*9880d681SAndroid Build Coastguard Worker Twine(DumpDirectory) + "\\" + ProgramName + ".%%%%%%.dmp", FD, 754*9880d681SAndroid Build Coastguard Worker DumpPath)) 755*9880d681SAndroid Build Coastguard Worker return EC; 756*9880d681SAndroid Build Coastguard Worker } else if (std::error_code EC = 757*9880d681SAndroid Build Coastguard Worker fs::createTemporaryFile(ProgramName, "dmp", FD, DumpPath)) 758*9880d681SAndroid Build Coastguard Worker return EC; 759*9880d681SAndroid Build Coastguard Worker 760*9880d681SAndroid Build Coastguard Worker // Our support functions return a file descriptor but Windows wants a handle. 761*9880d681SAndroid Build Coastguard Worker ScopedCommonHandle FileHandle(reinterpret_cast<HANDLE>(_get_osfhandle(FD))); 762*9880d681SAndroid Build Coastguard Worker 763*9880d681SAndroid Build Coastguard Worker if (!fMiniDumpWriteDump(::GetCurrentProcess(), ::GetCurrentProcessId(), 764*9880d681SAndroid Build Coastguard Worker FileHandle, DumpType, ExceptionInfo, NULL, NULL)) 765*9880d681SAndroid Build Coastguard Worker return mapWindowsError(::GetLastError()); 766*9880d681SAndroid Build Coastguard Worker 767*9880d681SAndroid Build Coastguard Worker llvm::errs() << "Wrote crash dump file \"" << DumpPath << "\"\n"; 768*9880d681SAndroid Build Coastguard Worker return std::error_code(); 769*9880d681SAndroid Build Coastguard Worker} 770*9880d681SAndroid Build Coastguard Worker 771*9880d681SAndroid Build Coastguard Workerstatic LONG WINAPI LLVMUnhandledExceptionFilter(LPEXCEPTION_POINTERS ep) { 772*9880d681SAndroid Build Coastguard Worker Cleanup(); 773*9880d681SAndroid Build Coastguard Worker 774*9880d681SAndroid Build Coastguard Worker // We'll automatically write a Minidump file here to help diagnose 775*9880d681SAndroid Build Coastguard Worker // the nasty sorts of crashes that aren't 100% reproducible from a set of 776*9880d681SAndroid Build Coastguard Worker // inputs (or in the event that the user is unable or unwilling to provide a 777*9880d681SAndroid Build Coastguard Worker // reproducible case). 778*9880d681SAndroid Build Coastguard Worker if (!llvm::Process::AreCoreFilesPrevented()) { 779*9880d681SAndroid Build Coastguard Worker MINIDUMP_EXCEPTION_INFORMATION ExceptionInfo; 780*9880d681SAndroid Build Coastguard Worker ExceptionInfo.ThreadId = ::GetCurrentThreadId(); 781*9880d681SAndroid Build Coastguard Worker ExceptionInfo.ExceptionPointers = ep; 782*9880d681SAndroid Build Coastguard Worker ExceptionInfo.ClientPointers = FALSE; 783*9880d681SAndroid Build Coastguard Worker 784*9880d681SAndroid Build Coastguard Worker if (std::error_code EC = WriteWindowsDumpFile(&ExceptionInfo)) 785*9880d681SAndroid Build Coastguard Worker llvm::errs() << "Could not write crash dump file: " << EC.message() 786*9880d681SAndroid Build Coastguard Worker << "\n"; 787*9880d681SAndroid Build Coastguard Worker } 788*9880d681SAndroid Build Coastguard Worker 789*9880d681SAndroid Build Coastguard Worker // Initialize the STACKFRAME structure. 790*9880d681SAndroid Build Coastguard Worker STACKFRAME64 StackFrame = {}; 791*9880d681SAndroid Build Coastguard Worker 792*9880d681SAndroid Build Coastguard Worker#if defined(_M_X64) 793*9880d681SAndroid Build Coastguard Worker StackFrame.AddrPC.Offset = ep->ContextRecord->Rip; 794*9880d681SAndroid Build Coastguard Worker StackFrame.AddrPC.Mode = AddrModeFlat; 795*9880d681SAndroid Build Coastguard Worker StackFrame.AddrStack.Offset = ep->ContextRecord->Rsp; 796*9880d681SAndroid Build Coastguard Worker StackFrame.AddrStack.Mode = AddrModeFlat; 797*9880d681SAndroid Build Coastguard Worker StackFrame.AddrFrame.Offset = ep->ContextRecord->Rbp; 798*9880d681SAndroid Build Coastguard Worker StackFrame.AddrFrame.Mode = AddrModeFlat; 799*9880d681SAndroid Build Coastguard Worker#elif defined(_M_IX86) 800*9880d681SAndroid Build Coastguard Worker StackFrame.AddrPC.Offset = ep->ContextRecord->Eip; 801*9880d681SAndroid Build Coastguard Worker StackFrame.AddrPC.Mode = AddrModeFlat; 802*9880d681SAndroid Build Coastguard Worker StackFrame.AddrStack.Offset = ep->ContextRecord->Esp; 803*9880d681SAndroid Build Coastguard Worker StackFrame.AddrStack.Mode = AddrModeFlat; 804*9880d681SAndroid Build Coastguard Worker StackFrame.AddrFrame.Offset = ep->ContextRecord->Ebp; 805*9880d681SAndroid Build Coastguard Worker StackFrame.AddrFrame.Mode = AddrModeFlat; 806*9880d681SAndroid Build Coastguard Worker#endif 807*9880d681SAndroid Build Coastguard Worker 808*9880d681SAndroid Build Coastguard Worker HANDLE hProcess = GetCurrentProcess(); 809*9880d681SAndroid Build Coastguard Worker HANDLE hThread = GetCurrentThread(); 810*9880d681SAndroid Build Coastguard Worker PrintStackTraceForThread(llvm::errs(), hProcess, hThread, StackFrame, 811*9880d681SAndroid Build Coastguard Worker ep->ContextRecord); 812*9880d681SAndroid Build Coastguard Worker 813*9880d681SAndroid Build Coastguard Worker _exit(ep->ExceptionRecord->ExceptionCode); 814*9880d681SAndroid Build Coastguard Worker} 815*9880d681SAndroid Build Coastguard Worker 816*9880d681SAndroid Build Coastguard Workerstatic BOOL WINAPI LLVMConsoleCtrlHandler(DWORD dwCtrlType) { 817*9880d681SAndroid Build Coastguard Worker // We are running in our very own thread, courtesy of Windows. 818*9880d681SAndroid Build Coastguard Worker EnterCriticalSection(&CriticalSection); 819*9880d681SAndroid Build Coastguard Worker Cleanup(); 820*9880d681SAndroid Build Coastguard Worker 821*9880d681SAndroid Build Coastguard Worker // If an interrupt function has been set, go and run one it; otherwise, 822*9880d681SAndroid Build Coastguard Worker // the process dies. 823*9880d681SAndroid Build Coastguard Worker void (*IF)() = InterruptFunction; 824*9880d681SAndroid Build Coastguard Worker InterruptFunction = 0; // Don't run it on another CTRL-C. 825*9880d681SAndroid Build Coastguard Worker 826*9880d681SAndroid Build Coastguard Worker if (IF) { 827*9880d681SAndroid Build Coastguard Worker // Note: if the interrupt function throws an exception, there is nothing 828*9880d681SAndroid Build Coastguard Worker // to catch it in this thread so it will kill the process. 829*9880d681SAndroid Build Coastguard Worker IF(); // Run it now. 830*9880d681SAndroid Build Coastguard Worker LeaveCriticalSection(&CriticalSection); 831*9880d681SAndroid Build Coastguard Worker return TRUE; // Don't kill the process. 832*9880d681SAndroid Build Coastguard Worker } 833*9880d681SAndroid Build Coastguard Worker 834*9880d681SAndroid Build Coastguard Worker // Allow normal processing to take place; i.e., the process dies. 835*9880d681SAndroid Build Coastguard Worker LeaveCriticalSection(&CriticalSection); 836*9880d681SAndroid Build Coastguard Worker return FALSE; 837*9880d681SAndroid Build Coastguard Worker} 838*9880d681SAndroid Build Coastguard Worker 839*9880d681SAndroid Build Coastguard Worker#if __MINGW32__ 840*9880d681SAndroid Build Coastguard Worker // We turned these warnings off for this file so that MinGW-g++ doesn't 841*9880d681SAndroid Build Coastguard Worker // complain about the ll format specifiers used. Now we are turning the 842*9880d681SAndroid Build Coastguard Worker // warnings back on. If MinGW starts to support diagnostic stacks, we can 843*9880d681SAndroid Build Coastguard Worker // replace this with a pop. 844*9880d681SAndroid Build Coastguard Worker #pragma GCC diagnostic warning "-Wformat" 845*9880d681SAndroid Build Coastguard Worker #pragma GCC diagnostic warning "-Wformat-extra-args" 846*9880d681SAndroid Build Coastguard Worker#endif 847