xref: /aosp_15_r20/external/llvm/lib/Support/Windows/Signals.inc (revision 9880d6810fe72a1726cb53787c6711e909410d58)
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