Signals.inc revision 36b56886974eae4f9c5ebc96befd3e7bfe5de338
1496c277a6d161413e3f6976c9991ddccd8ecae8aReid Spencer//===- Win32/Signals.cpp - Win32 Signals Implementation ---------*- C++ -*-===//
284ba14f6d016ab181f1fd5de8050e1b9bbc83904Mikhail Glushenkov//
3496c277a6d161413e3f6976c9991ddccd8ecae8aReid Spencer//                     The LLVM Compiler Infrastructure
4496c277a6d161413e3f6976c9991ddccd8ecae8aReid Spencer//
54ee451de366474b9c228b4e5fa573795a715216dChris Lattner// This file is distributed under the University of Illinois Open Source
64ee451de366474b9c228b4e5fa573795a715216dChris Lattner// License. See LICENSE.TXT for details.
784ba14f6d016ab181f1fd5de8050e1b9bbc83904Mikhail Glushenkov//
8496c277a6d161413e3f6976c9991ddccd8ecae8aReid Spencer//===----------------------------------------------------------------------===//
9496c277a6d161413e3f6976c9991ddccd8ecae8aReid Spencer//
10496c277a6d161413e3f6976c9991ddccd8ecae8aReid Spencer// This file provides the Win32 specific implementation of the Signals class.
11496c277a6d161413e3f6976c9991ddccd8ecae8aReid Spencer//
12496c277a6d161413e3f6976c9991ddccd8ecae8aReid Spencer//===----------------------------------------------------------------------===//
13496c277a6d161413e3f6976c9991ddccd8ecae8aReid Spencer
14d86dd4a29d8cdfcbae03dedaa5ee24c6c02f4839Rafael Espindola#include "llvm/Support/FileSystem.h"
15d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include <algorithm>
16ced4110f5b068b9b64e3a55a9ee57b621ce4acb1Reid Spencer#include <stdio.h>
1790b54138834a057179c7a02931217ab5a82ed389Reid Spencer#include <vector>
1890b54138834a057179c7a02931217ab5a82ed389Reid Spencer
1936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// The Windows.h header must be after LLVM and standard headers.
2036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "WindowsSupport.h"
2136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
2223a1cf3e085325783ef2e4078308f913cba5012eJeff Cohen#ifdef __MINGW32__
2348fdf91d0f17b19bb7345156b928689df94d0c6cReid Spencer #include <imagehlp.h>
24f6cbc0fd6494e50c48ebe4b5eecde1c70bcd5165Reid Spencer#else
2548fdf91d0f17b19bb7345156b928689df94d0c6cReid Spencer #include <dbghelp.h>
26f6cbc0fd6494e50c48ebe4b5eecde1c70bcd5165Reid Spencer#endif
27f6cbc0fd6494e50c48ebe4b5eecde1c70bcd5165Reid Spencer#include <psapi.h>
2890b54138834a057179c7a02931217ab5a82ed389Reid Spencer
290bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer#ifdef _MSC_VER
300bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer #pragma comment(lib, "psapi.lib")
310bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer #pragma comment(lib, "dbghelp.lib")
320bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer#elif __MINGW32__
3348fdf91d0f17b19bb7345156b928689df94d0c6cReid Spencer #if ((HAVE_LIBIMAGEHLP != 1) || (HAVE_LIBPSAPI != 1))
3448fdf91d0f17b19bb7345156b928689df94d0c6cReid Spencer  #error "libimagehlp.a & libpsapi.a should be present"
3548fdf91d0f17b19bb7345156b928689df94d0c6cReid Spencer #endif
360bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer // The version of g++ that comes with MinGW does *not* properly understand
370bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer // the ll format specifier for printf. However, MinGW passes the format
380bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer // specifiers on to the MSVCRT entirely, and the CRT understands the ll
390bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer // specifier. So these warnings are spurious in this case. Since we compile
400bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer // with -Wall, this will generate these warnings which should be ignored. So
410bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer // we will turn off the warnings for this just file. However, MinGW also does
420bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer // not support push and pop for diagnostics, so we have to manually turn it
430bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer // back on at the end of the file.
440bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer #pragma GCC diagnostic ignored "-Wformat"
450bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer #pragma GCC diagnostic ignored "-Wformat-extra-args"
460bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer
47cda065df614dbf7ca0f6a169e9536d2241539b75Anton Korobeynikov #if !defined(__MINGW64_VERSION_MAJOR)
48cda065df614dbf7ca0f6a169e9536d2241539b75Anton Korobeynikov // MinGW.org does not have updated support for the 64-bit versions of the
49cda065df614dbf7ca0f6a169e9536d2241539b75Anton Korobeynikov // DebugHlp APIs. So we will have to load them manually. The structures and
50cda065df614dbf7ca0f6a169e9536d2241539b75Anton Korobeynikov // method signatures were pulled from DbgHelp.h in the Windows Platform SDK,
51cda065df614dbf7ca0f6a169e9536d2241539b75Anton Korobeynikov // and adjusted for brevity.
520bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer typedef struct _IMAGEHLP_LINE64 {
530bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer   DWORD    SizeOfStruct;
540bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer   PVOID    Key;
550bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer   DWORD    LineNumber;
560bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer   PCHAR    FileName;
570bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer   DWORD64  Address;
580bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer } IMAGEHLP_LINE64, *PIMAGEHLP_LINE64;
590bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer
600bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer typedef struct _IMAGEHLP_SYMBOL64 {
610bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer   DWORD   SizeOfStruct;
620bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer   DWORD64 Address;
630bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer   DWORD   Size;
640bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer   DWORD   Flags;
650bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer   DWORD   MaxNameLength;
660bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer   CHAR    Name[1];
670bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer } IMAGEHLP_SYMBOL64, *PIMAGEHLP_SYMBOL64;
680bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer
690bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer typedef struct _tagADDRESS64 {
700bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer   DWORD64       Offset;
710bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer   WORD          Segment;
720bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer   ADDRESS_MODE  Mode;
730bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer } ADDRESS64, *LPADDRESS64;
740bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer
750bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer typedef struct _KDHELP64 {
760bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer   DWORD64   Thread;
770bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer   DWORD   ThCallbackStack;
780bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer   DWORD   ThCallbackBStore;
790bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer   DWORD   NextCallback;
800bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer   DWORD   FramePointer;
810bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer   DWORD64   KiCallUserMode;
820bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer   DWORD64   KeUserCallbackDispatcher;
830bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer   DWORD64   SystemRangeStart;
840bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer   DWORD64   KiUserExceptionDispatcher;
850bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer   DWORD64   StackBase;
860bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer   DWORD64   StackLimit;
870bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer   DWORD64   Reserved[5];
880bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer } KDHELP64, *PKDHELP64;
890bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer
900bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer typedef struct _tagSTACKFRAME64 {
910bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer   ADDRESS64   AddrPC;
920bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer   ADDRESS64   AddrReturn;
930bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer   ADDRESS64   AddrFrame;
940bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer   ADDRESS64   AddrStack;
950bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer   ADDRESS64   AddrBStore;
960bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer   PVOID       FuncTableEntry;
970bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer   DWORD64     Params[4];
980bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer   BOOL        Far;
990bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer   BOOL        Virtual;
1000bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer   DWORD64     Reserved[3];
1010bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer   KDHELP64    KdHelp;
1020bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer } STACKFRAME64, *LPSTACKFRAME64;
1030bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer
1040bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencertypedef BOOL (__stdcall *PREAD_PROCESS_MEMORY_ROUTINE64)(HANDLE hProcess,
1050bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer                      DWORD64 qwBaseAddress, PVOID lpBuffer, DWORD nSize,
1060bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer                      LPDWORD lpNumberOfBytesRead);
1070bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer
1080bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencertypedef PVOID (__stdcall *PFUNCTION_TABLE_ACCESS_ROUTINE64)( HANDLE ahProcess,
1090bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer                      DWORD64 AddrBase);
1100bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer
1110bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencertypedef DWORD64 (__stdcall *PGET_MODULE_BASE_ROUTINE64)(HANDLE hProcess,
1120bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer                      DWORD64 Address);
1130bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer
1140bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencertypedef DWORD64 (__stdcall *PTRANSLATE_ADDRESS_ROUTINE64)(HANDLE hProcess,
1150bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer                      HANDLE hThread, LPADDRESS64 lpaddr);
1160bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer
1170bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencertypedef BOOL (WINAPI *fpStackWalk64)(DWORD, HANDLE, HANDLE, LPSTACKFRAME64,
1180bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer                      PVOID, PREAD_PROCESS_MEMORY_ROUTINE64,
1190bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer                      PFUNCTION_TABLE_ACCESS_ROUTINE64,
1200bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer                      PGET_MODULE_BASE_ROUTINE64,
1210bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer                      PTRANSLATE_ADDRESS_ROUTINE64);
1220bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencerstatic fpStackWalk64 StackWalk64;
1230bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer
1240bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencertypedef DWORD64 (WINAPI *fpSymGetModuleBase64)(HANDLE, DWORD64);
1250bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencerstatic fpSymGetModuleBase64 SymGetModuleBase64;
1260bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer
1270bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencertypedef BOOL (WINAPI *fpSymGetSymFromAddr64)(HANDLE, DWORD64,
1280bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer                      PDWORD64, PIMAGEHLP_SYMBOL64);
1290bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencerstatic fpSymGetSymFromAddr64 SymGetSymFromAddr64;
1300bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer
1310bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencertypedef BOOL (WINAPI *fpSymGetLineFromAddr64)(HANDLE, DWORD64,
1320bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer                      PDWORD, PIMAGEHLP_LINE64);
1330bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencerstatic fpSymGetLineFromAddr64 SymGetLineFromAddr64;
1340bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer
1350bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencertypedef PVOID (WINAPI *fpSymFunctionTableAccess64)(HANDLE, DWORD64);
1360bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencerstatic fpSymFunctionTableAccess64 SymFunctionTableAccess64;
1370bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer
1380bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencerstatic bool load64BitDebugHelp(void) {
139ae06a63be5a1279739e0c8a2006e72f4bc687d57David Majnemer  HMODULE hLib = ::LoadLibraryW(L"Dbghelp.dll");
1400bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer  if (hLib) {
1410bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer    StackWalk64 = (fpStackWalk64)
1420bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer                      ::GetProcAddress(hLib, "StackWalk64");
1430bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer    SymGetModuleBase64 = (fpSymGetModuleBase64)
1440bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer                      ::GetProcAddress(hLib, "SymGetModuleBase64");
1450bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer    SymGetSymFromAddr64 = (fpSymGetSymFromAddr64)
1460bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer                      ::GetProcAddress(hLib, "SymGetSymFromAddr64");
1470bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer    SymGetLineFromAddr64 = (fpSymGetLineFromAddr64)
1480bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer                      ::GetProcAddress(hLib, "SymGetLineFromAddr64");
1490bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer    SymFunctionTableAccess64 = (fpSymFunctionTableAccess64)
1500bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer                     ::GetProcAddress(hLib, "SymFunctionTableAccess64");
1510bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer  }
1520bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer  return StackWalk64 != NULL;
1530bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer}
154cda065df614dbf7ca0f6a169e9536d2241539b75Anton Korobeynikov #endif // !defined(__MINGW64_VERSION_MAJOR)
1550bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer#endif // __MINGW32__
15690b54138834a057179c7a02931217ab5a82ed389Reid Spencer
15790b54138834a057179c7a02931217ab5a82ed389Reid Spencer// Forward declare.
15890b54138834a057179c7a02931217ab5a82ed389Reid Spencerstatic LONG WINAPI LLVMUnhandledExceptionFilter(LPEXCEPTION_POINTERS ep);
15990b54138834a057179c7a02931217ab5a82ed389Reid Spencerstatic BOOL WINAPI LLVMConsoleCtrlHandler(DWORD dwCtrlType);
16090b54138834a057179c7a02931217ab5a82ed389Reid Spencer
161ee841a1a8735805f84d609ae105bec92525033c6Jeff Cohen// InterruptFunction - The function to call if ctrl-c is pressed.
162ee841a1a8735805f84d609ae105bec92525033c6Jeff Cohenstatic void (*InterruptFunction)() = 0;
163ee841a1a8735805f84d609ae105bec92525033c6Jeff Cohen
164b7e2188f7fb9a1c1cb6dbd32b206e44b11b4a157Rafael Espindolastatic std::vector<std::string> *FilesToRemove = NULL;
16535033a5876aa27ea5729bc29b41bb4460a303cadChris Lattnerstatic std::vector<std::pair<void(*)(void*), void*> > *CallBacksToRun = 0;
16690b54138834a057179c7a02931217ab5a82ed389Reid Spencerstatic bool RegisteredUnhandledExceptionFilter = false;
1677b60a15abc155196d9515a1e242ec0137afff753Reid Spencerstatic bool CleanupExecuted = false;
168df3388492bc2bfc73b3e0195693e2f67f10dcf52Daniel Dunbarstatic bool ExitOnUnhandledExceptions = false;
1697b60a15abc155196d9515a1e242ec0137afff753Reid Spencerstatic PTOP_LEVEL_EXCEPTION_FILTER OldFilter = NULL;
170298d6c14ca1936677aaf6cca3efc569b6e53d294Reid Spencer
171298d6c14ca1936677aaf6cca3efc569b6e53d294Reid Spencer// Windows creates a new thread to execute the console handler when an event
172298d6c14ca1936677aaf6cca3efc569b6e53d294Reid Spencer// (such as CTRL/C) occurs.  This causes concurrency issues with the above
173298d6c14ca1936677aaf6cca3efc569b6e53d294Reid Spencer// globals which this critical section addresses.
17490b54138834a057179c7a02931217ab5a82ed389Reid Spencerstatic CRITICAL_SECTION CriticalSection;
17590b54138834a057179c7a02931217ab5a82ed389Reid Spencer
176496c277a6d161413e3f6976c9991ddccd8ecae8aReid Spencernamespace llvm {
177496c277a6d161413e3f6976c9991ddccd8ecae8aReid Spencer
178496c277a6d161413e3f6976c9991ddccd8ecae8aReid Spencer//===----------------------------------------------------------------------===//
17984ba14f6d016ab181f1fd5de8050e1b9bbc83904Mikhail Glushenkov//=== WARNING: Implementation here must contain only Win32 specific code
18090b54138834a057179c7a02931217ab5a82ed389Reid Spencer//===          and must not be UNIX code
181496c277a6d161413e3f6976c9991ddccd8ecae8aReid Spencer//===----------------------------------------------------------------------===//
182496c277a6d161413e3f6976c9991ddccd8ecae8aReid Spencer
1833be2d12bdec9ec3a244aae695d3b586ac27dcfdeDaniel Dunbar#ifdef _MSC_VER
1849463c0f3da8e325fea96e36540da18cadaa3f303Reid Kleckner/// AvoidMessageBoxHook - Emulates hitting "retry" from an "abort, retry,
1859463c0f3da8e325fea96e36540da18cadaa3f303Reid Kleckner/// ignore" CRT debug report dialog.  "retry" raises an exception which
1869463c0f3da8e325fea96e36540da18cadaa3f303Reid Kleckner/// ultimately triggers our stack dumper.
1879463c0f3da8e325fea96e36540da18cadaa3f303Reid Klecknerstatic int AvoidMessageBoxHook(int ReportType, char *Message, int *Return) {
1889463c0f3da8e325fea96e36540da18cadaa3f303Reid Kleckner  // Set *Return to the retry code for the return value of _CrtDbgReport:
1899463c0f3da8e325fea96e36540da18cadaa3f303Reid Kleckner  // http://msdn.microsoft.com/en-us/library/8hyw4sy7(v=vs.71).aspx
1909463c0f3da8e325fea96e36540da18cadaa3f303Reid Kleckner  // This may also trigger just-in-time debugging via DebugBreak().
1919463c0f3da8e325fea96e36540da18cadaa3f303Reid Kleckner  if (Return)
1929463c0f3da8e325fea96e36540da18cadaa3f303Reid Kleckner    *Return = 1;
1939463c0f3da8e325fea96e36540da18cadaa3f303Reid Kleckner  // Don't call _CrtDbgReport.
1949463c0f3da8e325fea96e36540da18cadaa3f303Reid Kleckner  return TRUE;
1959463c0f3da8e325fea96e36540da18cadaa3f303Reid Kleckner}
1969463c0f3da8e325fea96e36540da18cadaa3f303Reid Kleckner
1973be2d12bdec9ec3a244aae695d3b586ac27dcfdeDaniel Dunbar#endif
19890b54138834a057179c7a02931217ab5a82ed389Reid Spencer
199df3388492bc2bfc73b3e0195693e2f67f10dcf52Daniel Dunbarstatic void RegisterHandler() {
200cda065df614dbf7ca0f6a169e9536d2241539b75Anton Korobeynikov#if __MINGW32__ && !defined(__MINGW64_VERSION_MAJOR)
201cda065df614dbf7ca0f6a169e9536d2241539b75Anton Korobeynikov  // On MinGW.org, we need to load up the symbols explicitly, because the
2020bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer  // Win32 framework they include does not have support for the 64-bit
2030bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer  // versions of the APIs we need.  If we cannot load up the APIs (which
2040bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer  // would be unexpected as they should exist on every version of Windows
2050bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer  // we support), we will bail out since there would be nothing to report.
2060bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer  if (!load64BitDebugHelp()) {
2070bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer    assert(false && "These APIs should always be available");
2080bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer    return;
2090bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer  }
2100bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer#endif
2110bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer
2127b60a15abc155196d9515a1e242ec0137afff753Reid Spencer  if (RegisteredUnhandledExceptionFilter) {
213298d6c14ca1936677aaf6cca3efc569b6e53d294Reid Spencer    EnterCriticalSection(&CriticalSection);
21490b54138834a057179c7a02931217ab5a82ed389Reid Spencer    return;
215298d6c14ca1936677aaf6cca3efc569b6e53d294Reid Spencer  }
21690b54138834a057179c7a02931217ab5a82ed389Reid Spencer
21790b54138834a057179c7a02931217ab5a82ed389Reid Spencer  // Now's the time to create the critical section.  This is the first time
21890b54138834a057179c7a02931217ab5a82ed389Reid Spencer  // through here, and there's only one thread.
21990b54138834a057179c7a02931217ab5a82ed389Reid Spencer  InitializeCriticalSection(&CriticalSection);
22090b54138834a057179c7a02931217ab5a82ed389Reid Spencer
22190b54138834a057179c7a02931217ab5a82ed389Reid Spencer  // Enter it immediately.  Now if someone hits CTRL/C, the console handler
22290b54138834a057179c7a02931217ab5a82ed389Reid Spencer  // can't proceed until the globals are updated.
22390b54138834a057179c7a02931217ab5a82ed389Reid Spencer  EnterCriticalSection(&CriticalSection);
22490b54138834a057179c7a02931217ab5a82ed389Reid Spencer
22590b54138834a057179c7a02931217ab5a82ed389Reid Spencer  RegisteredUnhandledExceptionFilter = true;
2267b60a15abc155196d9515a1e242ec0137afff753Reid Spencer  OldFilter = SetUnhandledExceptionFilter(LLVMUnhandledExceptionFilter);
22790b54138834a057179c7a02931217ab5a82ed389Reid Spencer  SetConsoleCtrlHandler(LLVMConsoleCtrlHandler, TRUE);
22890b54138834a057179c7a02931217ab5a82ed389Reid Spencer
229df3388492bc2bfc73b3e0195693e2f67f10dcf52Daniel Dunbar  // Environment variable to disable any kind of crash dialog.
23008713b37c367b9db29058092c46b41981a74ceffArgyrios Kyrtzidis  if (getenv("LLVM_DISABLE_CRASH_REPORT")) {
231a8bbe707dc0c397d4020e7348fda64b3cb2a0e21NAKAMURA Takumi#ifdef _MSC_VER
23271b1c76cdf349b1cc838336a62374ca8e06db5a0Rafael Espindola    _CrtSetReportHook(AvoidMessageBoxHook);
233a8bbe707dc0c397d4020e7348fda64b3cb2a0e21NAKAMURA Takumi#endif
234ac25e44d8905e88f91f998ce27a82cea641f5ff9NAKAMURA Takumi    SetErrorMode(SEM_FAILCRITICALERRORS |
235ac25e44d8905e88f91f998ce27a82cea641f5ff9NAKAMURA Takumi                 SEM_NOGPFAULTERRORBOX |
236ac25e44d8905e88f91f998ce27a82cea641f5ff9NAKAMURA Takumi                 SEM_NOOPENFILEERRORBOX);
2373be2d12bdec9ec3a244aae695d3b586ac27dcfdeDaniel Dunbar    ExitOnUnhandledExceptions = true;
238df3388492bc2bfc73b3e0195693e2f67f10dcf52Daniel Dunbar  }
239df3388492bc2bfc73b3e0195693e2f67f10dcf52Daniel Dunbar
24090b54138834a057179c7a02931217ab5a82ed389Reid Spencer  // IMPORTANT NOTE: Caller must call LeaveCriticalSection(&CriticalSection) or
24190b54138834a057179c7a02931217ab5a82ed389Reid Spencer  // else multi-threading problems will ensue.
24290b54138834a057179c7a02931217ab5a82ed389Reid Spencer}
24390b54138834a057179c7a02931217ab5a82ed389Reid Spencer
244496c277a6d161413e3f6976c9991ddccd8ecae8aReid Spencer// RemoveFileOnSignal - The public API
245b7e2188f7fb9a1c1cb6dbd32b206e44b11b4a157Rafael Espindolabool sys::RemoveFileOnSignal(StringRef Filename, std::string* ErrMsg) {
24690b54138834a057179c7a02931217ab5a82ed389Reid Spencer  RegisterHandler();
24790b54138834a057179c7a02931217ab5a82ed389Reid Spencer
24805545755676b9ff35d244e55d749a15e28bb228bReid Spencer  if (CleanupExecuted) {
24905545755676b9ff35d244e55d749a15e28bb228bReid Spencer    if (ErrMsg)
25005545755676b9ff35d244e55d749a15e28bb228bReid Spencer      *ErrMsg = "Process terminating -- cannot register for removal";
25105545755676b9ff35d244e55d749a15e28bb228bReid Spencer    return true;
25205545755676b9ff35d244e55d749a15e28bb228bReid Spencer  }
2537b60a15abc155196d9515a1e242ec0137afff753Reid Spencer
25490b54138834a057179c7a02931217ab5a82ed389Reid Spencer  if (FilesToRemove == NULL)
255b7e2188f7fb9a1c1cb6dbd32b206e44b11b4a157Rafael Espindola    FilesToRemove = new std::vector<std::string>;
25690b54138834a057179c7a02931217ab5a82ed389Reid Spencer
25798601218901190d9d3bb5ebccae659f8db265b5dReid Spencer  FilesToRemove->push_back(Filename);
25890b54138834a057179c7a02931217ab5a82ed389Reid Spencer
25990b54138834a057179c7a02931217ab5a82ed389Reid Spencer  LeaveCriticalSection(&CriticalSection);
26005545755676b9ff35d244e55d749a15e28bb228bReid Spencer  return false;
261496c277a6d161413e3f6976c9991ddccd8ecae8aReid Spencer}
262496c277a6d161413e3f6976c9991ddccd8ecae8aReid Spencer
26341154114f64c1531764236e9268d2a5ac52e3e91Dan Gohman// DontRemoveFileOnSignal - The public API
264b7e2188f7fb9a1c1cb6dbd32b206e44b11b4a157Rafael Espindolavoid sys::DontRemoveFileOnSignal(StringRef Filename) {
26541154114f64c1531764236e9268d2a5ac52e3e91Dan Gohman  if (FilesToRemove == NULL)
26641154114f64c1531764236e9268d2a5ac52e3e91Dan Gohman    return;
26741154114f64c1531764236e9268d2a5ac52e3e91Dan Gohman
2682172f3cd971d7446123f8bdc72b381adde0ea559NAKAMURA Takumi  RegisterHandler();
2692172f3cd971d7446123f8bdc72b381adde0ea559NAKAMURA Takumi
27041154114f64c1531764236e9268d2a5ac52e3e91Dan Gohman  FilesToRemove->push_back(Filename);
271b7e2188f7fb9a1c1cb6dbd32b206e44b11b4a157Rafael Espindola  std::vector<std::string>::reverse_iterator I =
27241154114f64c1531764236e9268d2a5ac52e3e91Dan Gohman  std::find(FilesToRemove->rbegin(), FilesToRemove->rend(), Filename);
27341154114f64c1531764236e9268d2a5ac52e3e91Dan Gohman  if (I != FilesToRemove->rend())
27441154114f64c1531764236e9268d2a5ac52e3e91Dan Gohman    FilesToRemove->erase(I.base()-1);
27541154114f64c1531764236e9268d2a5ac52e3e91Dan Gohman
27641154114f64c1531764236e9268d2a5ac52e3e91Dan Gohman  LeaveCriticalSection(&CriticalSection);
27741154114f64c1531764236e9268d2a5ac52e3e91Dan Gohman}
27841154114f64c1531764236e9268d2a5ac52e3e91Dan Gohman
279496c277a6d161413e3f6976c9991ddccd8ecae8aReid Spencer/// PrintStackTraceOnErrorSignal - When an error signal (such as SIBABRT or
280496c277a6d161413e3f6976c9991ddccd8ecae8aReid Spencer/// SIGSEGV) is delivered to the process, print a stack trace and then exit.
28190b54138834a057179c7a02931217ab5a82ed389Reid Spencervoid sys::PrintStackTraceOnErrorSignal() {
28290b54138834a057179c7a02931217ab5a82ed389Reid Spencer  RegisterHandler();
28390b54138834a057179c7a02931217ab5a82ed389Reid Spencer  LeaveCriticalSection(&CriticalSection);
28490b54138834a057179c7a02931217ab5a82ed389Reid Spencer}
28590b54138834a057179c7a02931217ab5a82ed389Reid Spencer
286f48acd5ecd2616623f441f2922d8b4c637e3cd6cArgyrios Kyrtzidisvoid llvm::sys::PrintStackTrace(FILE *) {
287f48acd5ecd2616623f441f2922d8b4c637e3cd6cArgyrios Kyrtzidis  // FIXME: Implement.
288f48acd5ecd2616623f441f2922d8b4c637e3cd6cArgyrios Kyrtzidis}
289f48acd5ecd2616623f441f2922d8b4c637e3cd6cArgyrios Kyrtzidis
290fa8c292ebd893b3effef4ead9c88d261c628c340Chris Lattner
291fa8c292ebd893b3effef4ead9c88d261c628c340Chris Lattnervoid sys::SetInterruptFunction(void (*IF)()) {
292ee841a1a8735805f84d609ae105bec92525033c6Jeff Cohen  RegisterHandler();
29364fe58490d28b7f7ba3ecb78fd9290688ded8f0cJeff Cohen  InterruptFunction = IF;
294ee841a1a8735805f84d609ae105bec92525033c6Jeff Cohen  LeaveCriticalSection(&CriticalSection);
295fa8c292ebd893b3effef4ead9c88d261c628c340Chris Lattner}
29648fe63526e35ddaee7e98879596a569911f41319Sebastian Redl
29748fe63526e35ddaee7e98879596a569911f41319Sebastian Redl
29848fe63526e35ddaee7e98879596a569911f41319Sebastian Redl/// AddSignalHandler - Add a function to be called when a signal is delivered
29948fe63526e35ddaee7e98879596a569911f41319Sebastian Redl/// to the process.  The handler can have a cookie passed to it to identify
30048fe63526e35ddaee7e98879596a569911f41319Sebastian Redl/// what instance of the handler it is.
30148fe63526e35ddaee7e98879596a569911f41319Sebastian Redlvoid sys::AddSignalHandler(void (*FnPtr)(void *), void *Cookie) {
30248fe63526e35ddaee7e98879596a569911f41319Sebastian Redl  if (CallBacksToRun == 0)
30348fe63526e35ddaee7e98879596a569911f41319Sebastian Redl    CallBacksToRun = new std::vector<std::pair<void(*)(void*), void*> >();
30448fe63526e35ddaee7e98879596a569911f41319Sebastian Redl  CallBacksToRun->push_back(std::make_pair(FnPtr, Cookie));
30548fe63526e35ddaee7e98879596a569911f41319Sebastian Redl  RegisterHandler();
30661633368cfc04697d8e2030d66ab220464298acaTorok Edwin  LeaveCriticalSection(&CriticalSection);
30748fe63526e35ddaee7e98879596a569911f41319Sebastian Redl}
308496c277a6d161413e3f6976c9991ddccd8ecae8aReid Spencer}
309496c277a6d161413e3f6976c9991ddccd8ecae8aReid Spencer
31090b54138834a057179c7a02931217ab5a82ed389Reid Spencerstatic void Cleanup() {
31190b54138834a057179c7a02931217ab5a82ed389Reid Spencer  EnterCriticalSection(&CriticalSection);
31290b54138834a057179c7a02931217ab5a82ed389Reid Spencer
3137b60a15abc155196d9515a1e242ec0137afff753Reid Spencer  // Prevent other thread from registering new files and directories for
3147b60a15abc155196d9515a1e242ec0137afff753Reid Spencer  // removal, should we be executing because of the console handler callback.
3157b60a15abc155196d9515a1e242ec0137afff753Reid Spencer  CleanupExecuted = true;
3167b60a15abc155196d9515a1e242ec0137afff753Reid Spencer
3177b60a15abc155196d9515a1e242ec0137afff753Reid Spencer  // FIXME: open files cannot be deleted.
3187b60a15abc155196d9515a1e242ec0137afff753Reid Spencer
31990b54138834a057179c7a02931217ab5a82ed389Reid Spencer  if (FilesToRemove != NULL)
32090b54138834a057179c7a02931217ab5a82ed389Reid Spencer    while (!FilesToRemove->empty()) {
32136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      llvm::sys::fs::remove(FilesToRemove->back());
32290b54138834a057179c7a02931217ab5a82ed389Reid Spencer      FilesToRemove->pop_back();
32390b54138834a057179c7a02931217ab5a82ed389Reid Spencer    }
32490b54138834a057179c7a02931217ab5a82ed389Reid Spencer
32535033a5876aa27ea5729bc29b41bb4460a303cadChris Lattner  if (CallBacksToRun)
32635033a5876aa27ea5729bc29b41bb4460a303cadChris Lattner    for (unsigned i = 0, e = CallBacksToRun->size(); i != e; ++i)
32735033a5876aa27ea5729bc29b41bb4460a303cadChris Lattner      (*CallBacksToRun)[i].first((*CallBacksToRun)[i].second);
32890b54138834a057179c7a02931217ab5a82ed389Reid Spencer
32990b54138834a057179c7a02931217ab5a82ed389Reid Spencer  LeaveCriticalSection(&CriticalSection);
33090b54138834a057179c7a02931217ab5a82ed389Reid Spencer}
33190b54138834a057179c7a02931217ab5a82ed389Reid Spencer
332fb89e08413878571c1c1fc6ff15cdbf5cd8692dcDaniel Dunbarvoid llvm::sys::RunInterruptHandlers() {
333fb89e08413878571c1c1fc6ff15cdbf5cd8692dcDaniel Dunbar  Cleanup();
334fb89e08413878571c1c1fc6ff15cdbf5cd8692dcDaniel Dunbar}
335fb89e08413878571c1c1fc6ff15cdbf5cd8692dcDaniel Dunbar
33690b54138834a057179c7a02931217ab5a82ed389Reid Spencerstatic LONG WINAPI LLVMUnhandledExceptionFilter(LPEXCEPTION_POINTERS ep) {
33711d03f690e7fe019c33c3a066a9171c61f6d61f9Mikhail Glushenkov  Cleanup();
33884ba14f6d016ab181f1fd5de8050e1b9bbc83904Mikhail Glushenkov
3396d8ac5ac6d87451d52651ba5e6cc0abffb4c264eMikhail Glushenkov  // Initialize the STACKFRAME structure.
3400bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer  STACKFRAME64 StackFrame;
3416d8ac5ac6d87451d52651ba5e6cc0abffb4c264eMikhail Glushenkov  memset(&StackFrame, 0, sizeof(StackFrame));
3426d8ac5ac6d87451d52651ba5e6cc0abffb4c264eMikhail Glushenkov
3430bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer  DWORD machineType;
3440bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer#if defined(_M_X64)
3450bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer  machineType = IMAGE_FILE_MACHINE_AMD64;
3460bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer  StackFrame.AddrPC.Offset = ep->ContextRecord->Rip;
3470bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer  StackFrame.AddrPC.Mode = AddrModeFlat;
3480bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer  StackFrame.AddrStack.Offset = ep->ContextRecord->Rsp;
3490bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer  StackFrame.AddrStack.Mode = AddrModeFlat;
3500bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer  StackFrame.AddrFrame.Offset = ep->ContextRecord->Rbp;
3510bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer  StackFrame.AddrFrame.Mode = AddrModeFlat;
3520bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer#elif defined(_M_IX86)
3530bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer  machineType = IMAGE_FILE_MACHINE_I386;
3546d8ac5ac6d87451d52651ba5e6cc0abffb4c264eMikhail Glushenkov  StackFrame.AddrPC.Offset = ep->ContextRecord->Eip;
3556d8ac5ac6d87451d52651ba5e6cc0abffb4c264eMikhail Glushenkov  StackFrame.AddrPC.Mode = AddrModeFlat;
3566d8ac5ac6d87451d52651ba5e6cc0abffb4c264eMikhail Glushenkov  StackFrame.AddrStack.Offset = ep->ContextRecord->Esp;
3576d8ac5ac6d87451d52651ba5e6cc0abffb4c264eMikhail Glushenkov  StackFrame.AddrStack.Mode = AddrModeFlat;
3586d8ac5ac6d87451d52651ba5e6cc0abffb4c264eMikhail Glushenkov  StackFrame.AddrFrame.Offset = ep->ContextRecord->Ebp;
3596d8ac5ac6d87451d52651ba5e6cc0abffb4c264eMikhail Glushenkov  StackFrame.AddrFrame.Mode = AddrModeFlat;
3600bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer#endif
3616d8ac5ac6d87451d52651ba5e6cc0abffb4c264eMikhail Glushenkov
3626d8ac5ac6d87451d52651ba5e6cc0abffb4c264eMikhail Glushenkov  HANDLE hProcess = GetCurrentProcess();
3636d8ac5ac6d87451d52651ba5e6cc0abffb4c264eMikhail Glushenkov  HANDLE hThread = GetCurrentThread();
3646d8ac5ac6d87451d52651ba5e6cc0abffb4c264eMikhail Glushenkov
3656d8ac5ac6d87451d52651ba5e6cc0abffb4c264eMikhail Glushenkov  // Initialize the symbol handler.
3666d8ac5ac6d87451d52651ba5e6cc0abffb4c264eMikhail Glushenkov  SymSetOptions(SYMOPT_DEFERRED_LOADS|SYMOPT_LOAD_LINES);
3676d8ac5ac6d87451d52651ba5e6cc0abffb4c264eMikhail Glushenkov  SymInitialize(hProcess, NULL, TRUE);
3686d8ac5ac6d87451d52651ba5e6cc0abffb4c264eMikhail Glushenkov
3696d8ac5ac6d87451d52651ba5e6cc0abffb4c264eMikhail Glushenkov  while (true) {
3700bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer    if (!StackWalk64(machineType, hProcess, hThread, &StackFrame,
3710bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer                   ep->ContextRecord, NULL, SymFunctionTableAccess64,
3720bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer                   SymGetModuleBase64, NULL)) {
3736d8ac5ac6d87451d52651ba5e6cc0abffb4c264eMikhail Glushenkov      break;
3746d8ac5ac6d87451d52651ba5e6cc0abffb4c264eMikhail Glushenkov    }
3756d8ac5ac6d87451d52651ba5e6cc0abffb4c264eMikhail Glushenkov
3766d8ac5ac6d87451d52651ba5e6cc0abffb4c264eMikhail Glushenkov    if (StackFrame.AddrFrame.Offset == 0)
3776d8ac5ac6d87451d52651ba5e6cc0abffb4c264eMikhail Glushenkov      break;
3786d8ac5ac6d87451d52651ba5e6cc0abffb4c264eMikhail Glushenkov
3796d8ac5ac6d87451d52651ba5e6cc0abffb4c264eMikhail Glushenkov    // Print the PC in hexadecimal.
3800bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer    DWORD64 PC = StackFrame.AddrPC.Offset;
3810bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer#if defined(_M_X64)
3820bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer    fprintf(stderr, "0x%016llX", PC);
3830bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer#elif defined(_M_IX86)
3840bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer    fprintf(stderr, "0x%08lX", static_cast<DWORD>(PC));
3850bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer#endif
3866d8ac5ac6d87451d52651ba5e6cc0abffb4c264eMikhail Glushenkov
3876d8ac5ac6d87451d52651ba5e6cc0abffb4c264eMikhail Glushenkov    // Print the parameters.  Assume there are four.
3880bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer#if defined(_M_X64)
3890bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer    fprintf(stderr, " (0x%016llX 0x%016llX 0x%016llX 0x%016llX)",
3900bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer                StackFrame.Params[0],
3910bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer                StackFrame.Params[1],
3920bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer                StackFrame.Params[2],
3930bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer                StackFrame.Params[3]);
3940bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer#elif defined(_M_IX86)
3956d8ac5ac6d87451d52651ba5e6cc0abffb4c264eMikhail Glushenkov    fprintf(stderr, " (0x%08lX 0x%08lX 0x%08lX 0x%08lX)",
3960bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer                static_cast<DWORD>(StackFrame.Params[0]),
3970bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer                static_cast<DWORD>(StackFrame.Params[1]),
3980bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer                static_cast<DWORD>(StackFrame.Params[2]),
3990bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer                static_cast<DWORD>(StackFrame.Params[3]));
4000bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer#endif
4016d8ac5ac6d87451d52651ba5e6cc0abffb4c264eMikhail Glushenkov    // Verify the PC belongs to a module in this process.
4020bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer    if (!SymGetModuleBase64(hProcess, PC)) {
4036d8ac5ac6d87451d52651ba5e6cc0abffb4c264eMikhail Glushenkov      fputs(" <unknown module>\n", stderr);
4046d8ac5ac6d87451d52651ba5e6cc0abffb4c264eMikhail Glushenkov      continue;
4056d8ac5ac6d87451d52651ba5e6cc0abffb4c264eMikhail Glushenkov    }
40690b54138834a057179c7a02931217ab5a82ed389Reid Spencer
4076d8ac5ac6d87451d52651ba5e6cc0abffb4c264eMikhail Glushenkov    // Print the symbol name.
4086d8ac5ac6d87451d52651ba5e6cc0abffb4c264eMikhail Glushenkov    char buffer[512];
4090bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer    IMAGEHLP_SYMBOL64 *symbol = reinterpret_cast<IMAGEHLP_SYMBOL64 *>(buffer);
4100bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer    memset(symbol, 0, sizeof(IMAGEHLP_SYMBOL64));
4110bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer    symbol->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL64);
4120bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer    symbol->MaxNameLength = 512 - sizeof(IMAGEHLP_SYMBOL64);
4136d8ac5ac6d87451d52651ba5e6cc0abffb4c264eMikhail Glushenkov
4140bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer    DWORD64 dwDisp;
4150bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer    if (!SymGetSymFromAddr64(hProcess, PC, &dwDisp, symbol)) {
41690b54138834a057179c7a02931217ab5a82ed389Reid Spencer      fputc('\n', stderr);
4176d8ac5ac6d87451d52651ba5e6cc0abffb4c264eMikhail Glushenkov      continue;
4186d8ac5ac6d87451d52651ba5e6cc0abffb4c264eMikhail Glushenkov    }
4196d8ac5ac6d87451d52651ba5e6cc0abffb4c264eMikhail Glushenkov
4206d8ac5ac6d87451d52651ba5e6cc0abffb4c264eMikhail Glushenkov    buffer[511] = 0;
4216d8ac5ac6d87451d52651ba5e6cc0abffb4c264eMikhail Glushenkov    if (dwDisp > 0)
4220bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer      fprintf(stderr, ", %s() + 0x%llX bytes(s)", symbol->Name, dwDisp);
4236d8ac5ac6d87451d52651ba5e6cc0abffb4c264eMikhail Glushenkov    else
4246d8ac5ac6d87451d52651ba5e6cc0abffb4c264eMikhail Glushenkov      fprintf(stderr, ", %s", symbol->Name);
4256d8ac5ac6d87451d52651ba5e6cc0abffb4c264eMikhail Glushenkov
4266d8ac5ac6d87451d52651ba5e6cc0abffb4c264eMikhail Glushenkov    // Print the source file and line number information.
4270bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer    IMAGEHLP_LINE64 line;
4280bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer    DWORD dwLineDisp;
4296d8ac5ac6d87451d52651ba5e6cc0abffb4c264eMikhail Glushenkov    memset(&line, 0, sizeof(line));
4306d8ac5ac6d87451d52651ba5e6cc0abffb4c264eMikhail Glushenkov    line.SizeOfStruct = sizeof(line);
4310bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer    if (SymGetLineFromAddr64(hProcess, PC, &dwLineDisp, &line)) {
4326d8ac5ac6d87451d52651ba5e6cc0abffb4c264eMikhail Glushenkov      fprintf(stderr, ", %s, line %lu", line.FileName, line.LineNumber);
4330bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer      if (dwLineDisp > 0)
4340bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer        fprintf(stderr, " + 0x%lX byte(s)", dwLineDisp);
43590b54138834a057179c7a02931217ab5a82ed389Reid Spencer    }
4360ccb93034a47303509ee2c89b8bf13956a510b94Chuck Rose III
4376d8ac5ac6d87451d52651ba5e6cc0abffb4c264eMikhail Glushenkov    fputc('\n', stderr);
4386d8ac5ac6d87451d52651ba5e6cc0abffb4c264eMikhail Glushenkov  }
4396d8ac5ac6d87451d52651ba5e6cc0abffb4c264eMikhail Glushenkov
440df3388492bc2bfc73b3e0195693e2f67f10dcf52Daniel Dunbar  if (ExitOnUnhandledExceptions)
4415d2f8c31556b6a5ce29d2cad314bc48af879c5b3NAKAMURA Takumi    _exit(ep->ExceptionRecord->ExceptionCode);
442df3388492bc2bfc73b3e0195693e2f67f10dcf52Daniel Dunbar
44390b54138834a057179c7a02931217ab5a82ed389Reid Spencer  // Allow dialog box to pop up allowing choice to start debugger.
4447b60a15abc155196d9515a1e242ec0137afff753Reid Spencer  if (OldFilter)
4457b60a15abc155196d9515a1e242ec0137afff753Reid Spencer    return (*OldFilter)(ep);
4467b60a15abc155196d9515a1e242ec0137afff753Reid Spencer  else
4477b60a15abc155196d9515a1e242ec0137afff753Reid Spencer    return EXCEPTION_CONTINUE_SEARCH;
44890b54138834a057179c7a02931217ab5a82ed389Reid Spencer}
44990b54138834a057179c7a02931217ab5a82ed389Reid Spencer
45090b54138834a057179c7a02931217ab5a82ed389Reid Spencerstatic BOOL WINAPI LLVMConsoleCtrlHandler(DWORD dwCtrlType) {
45164fe58490d28b7f7ba3ecb78fd9290688ded8f0cJeff Cohen  // We are running in our very own thread, courtesy of Windows.
452ee841a1a8735805f84d609ae105bec92525033c6Jeff Cohen  EnterCriticalSection(&CriticalSection);
45390b54138834a057179c7a02931217ab5a82ed389Reid Spencer  Cleanup();
45490b54138834a057179c7a02931217ab5a82ed389Reid Spencer
455ee841a1a8735805f84d609ae105bec92525033c6Jeff Cohen  // If an interrupt function has been set, go and run one it; otherwise,
456ee841a1a8735805f84d609ae105bec92525033c6Jeff Cohen  // the process dies.
457ee841a1a8735805f84d609ae105bec92525033c6Jeff Cohen  void (*IF)() = InterruptFunction;
458ee841a1a8735805f84d609ae105bec92525033c6Jeff Cohen  InterruptFunction = 0;      // Don't run it on another CTRL-C.
459ee841a1a8735805f84d609ae105bec92525033c6Jeff Cohen
460ee841a1a8735805f84d609ae105bec92525033c6Jeff Cohen  if (IF) {
46164fe58490d28b7f7ba3ecb78fd9290688ded8f0cJeff Cohen    // Note: if the interrupt function throws an exception, there is nothing
46264fe58490d28b7f7ba3ecb78fd9290688ded8f0cJeff Cohen    // to catch it in this thread so it will kill the process.
46364fe58490d28b7f7ba3ecb78fd9290688ded8f0cJeff Cohen    IF();                     // Run it now.
464ee841a1a8735805f84d609ae105bec92525033c6Jeff Cohen    LeaveCriticalSection(&CriticalSection);
465ee841a1a8735805f84d609ae105bec92525033c6Jeff Cohen    return TRUE;              // Don't kill the process.
466ee841a1a8735805f84d609ae105bec92525033c6Jeff Cohen  }
467ee841a1a8735805f84d609ae105bec92525033c6Jeff Cohen
468298d6c14ca1936677aaf6cca3efc569b6e53d294Reid Spencer  // Allow normal processing to take place; i.e., the process dies.
469ee841a1a8735805f84d609ae105bec92525033c6Jeff Cohen  LeaveCriticalSection(&CriticalSection);
47090b54138834a057179c7a02931217ab5a82ed389Reid Spencer  return FALSE;
471496c277a6d161413e3f6976c9991ddccd8ecae8aReid Spencer}
4720bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer
4730bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer#if __MINGW32__
4740bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer // We turned these warnings off for this file so that MinGW-g++ doesn't
4750bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer // complain about the ll format specifiers used.  Now we are turning the
4760bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer // warnings back on.  If MinGW starts to support diagnostic stacks, we can
4770bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer // replace this with a pop.
4780bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer #pragma GCC diagnostic warning "-Wformat"
4790bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer #pragma GCC diagnostic warning "-Wformat-extra-args"
4800bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer#endif
481