Signals.inc revision 5d2f8c31556b6a5ce29d2cad314bc48af879c5b3
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 141f6efa3996dd1929fbc129203ce5009b620e6969Michael J. Spencer#include "Windows.h" 15ced4110f5b068b9b64e3a55a9ee57b621ce4acb1Reid Spencer#include <stdio.h> 1690b54138834a057179c7a02931217ab5a82ed389Reid Spencer#include <vector> 1748fe63526e35ddaee7e98879596a569911f41319Sebastian Redl#include <algorithm> 1890b54138834a057179c7a02931217ab5a82ed389Reid Spencer 1923a1cf3e085325783ef2e4078308f913cba5012eJeff Cohen#ifdef __MINGW32__ 2048fdf91d0f17b19bb7345156b928689df94d0c6cReid Spencer #include <imagehlp.h> 21f6cbc0fd6494e50c48ebe4b5eecde1c70bcd5165Reid Spencer#else 2248fdf91d0f17b19bb7345156b928689df94d0c6cReid Spencer #include <dbghelp.h> 23f6cbc0fd6494e50c48ebe4b5eecde1c70bcd5165Reid Spencer#endif 24f6cbc0fd6494e50c48ebe4b5eecde1c70bcd5165Reid Spencer#include <psapi.h> 2590b54138834a057179c7a02931217ab5a82ed389Reid Spencer 260bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer#ifdef _MSC_VER 270bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer #pragma comment(lib, "psapi.lib") 280bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer #pragma comment(lib, "dbghelp.lib") 290bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer#elif __MINGW32__ 3048fdf91d0f17b19bb7345156b928689df94d0c6cReid Spencer #if ((HAVE_LIBIMAGEHLP != 1) || (HAVE_LIBPSAPI != 1)) 3148fdf91d0f17b19bb7345156b928689df94d0c6cReid Spencer #error "libimagehlp.a & libpsapi.a should be present" 3248fdf91d0f17b19bb7345156b928689df94d0c6cReid Spencer #endif 330bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer // The version of g++ that comes with MinGW does *not* properly understand 340bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer // the ll format specifier for printf. However, MinGW passes the format 350bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer // specifiers on to the MSVCRT entirely, and the CRT understands the ll 360bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer // specifier. So these warnings are spurious in this case. Since we compile 370bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer // with -Wall, this will generate these warnings which should be ignored. So 380bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer // we will turn off the warnings for this just file. However, MinGW also does 390bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer // not support push and pop for diagnostics, so we have to manually turn it 400bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer // back on at the end of the file. 410bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer #pragma GCC diagnostic ignored "-Wformat" 420bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer #pragma GCC diagnostic ignored "-Wformat-extra-args" 430bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer 44cda065df614dbf7ca0f6a169e9536d2241539b75Anton Korobeynikov #if !defined(__MINGW64_VERSION_MAJOR) 45cda065df614dbf7ca0f6a169e9536d2241539b75Anton Korobeynikov // MinGW.org does not have updated support for the 64-bit versions of the 46cda065df614dbf7ca0f6a169e9536d2241539b75Anton Korobeynikov // DebugHlp APIs. So we will have to load them manually. The structures and 47cda065df614dbf7ca0f6a169e9536d2241539b75Anton Korobeynikov // method signatures were pulled from DbgHelp.h in the Windows Platform SDK, 48cda065df614dbf7ca0f6a169e9536d2241539b75Anton Korobeynikov // and adjusted for brevity. 490bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer typedef struct _IMAGEHLP_LINE64 { 500bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer DWORD SizeOfStruct; 510bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer PVOID Key; 520bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer DWORD LineNumber; 530bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer PCHAR FileName; 540bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer DWORD64 Address; 550bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer } IMAGEHLP_LINE64, *PIMAGEHLP_LINE64; 560bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer 570bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer typedef struct _IMAGEHLP_SYMBOL64 { 580bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer DWORD SizeOfStruct; 590bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer DWORD64 Address; 600bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer DWORD Size; 610bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer DWORD Flags; 620bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer DWORD MaxNameLength; 630bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer CHAR Name[1]; 640bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer } IMAGEHLP_SYMBOL64, *PIMAGEHLP_SYMBOL64; 650bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer 660bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer typedef struct _tagADDRESS64 { 670bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer DWORD64 Offset; 680bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer WORD Segment; 690bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer ADDRESS_MODE Mode; 700bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer } ADDRESS64, *LPADDRESS64; 710bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer 720bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer typedef struct _KDHELP64 { 730bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer DWORD64 Thread; 740bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer DWORD ThCallbackStack; 750bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer DWORD ThCallbackBStore; 760bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer DWORD NextCallback; 770bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer DWORD FramePointer; 780bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer DWORD64 KiCallUserMode; 790bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer DWORD64 KeUserCallbackDispatcher; 800bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer DWORD64 SystemRangeStart; 810bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer DWORD64 KiUserExceptionDispatcher; 820bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer DWORD64 StackBase; 830bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer DWORD64 StackLimit; 840bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer DWORD64 Reserved[5]; 850bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer } KDHELP64, *PKDHELP64; 860bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer 870bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer typedef struct _tagSTACKFRAME64 { 880bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer ADDRESS64 AddrPC; 890bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer ADDRESS64 AddrReturn; 900bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer ADDRESS64 AddrFrame; 910bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer ADDRESS64 AddrStack; 920bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer ADDRESS64 AddrBStore; 930bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer PVOID FuncTableEntry; 940bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer DWORD64 Params[4]; 950bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer BOOL Far; 960bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer BOOL Virtual; 970bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer DWORD64 Reserved[3]; 980bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer KDHELP64 KdHelp; 990bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer } STACKFRAME64, *LPSTACKFRAME64; 1000bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer 1010bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencertypedef BOOL (__stdcall *PREAD_PROCESS_MEMORY_ROUTINE64)(HANDLE hProcess, 1020bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer DWORD64 qwBaseAddress, PVOID lpBuffer, DWORD nSize, 1030bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer LPDWORD lpNumberOfBytesRead); 1040bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer 1050bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencertypedef PVOID (__stdcall *PFUNCTION_TABLE_ACCESS_ROUTINE64)( HANDLE ahProcess, 1060bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer DWORD64 AddrBase); 1070bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer 1080bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencertypedef DWORD64 (__stdcall *PGET_MODULE_BASE_ROUTINE64)(HANDLE hProcess, 1090bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer DWORD64 Address); 1100bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer 1110bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencertypedef DWORD64 (__stdcall *PTRANSLATE_ADDRESS_ROUTINE64)(HANDLE hProcess, 1120bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer HANDLE hThread, LPADDRESS64 lpaddr); 1130bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer 1140bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencertypedef BOOL (WINAPI *fpStackWalk64)(DWORD, HANDLE, HANDLE, LPSTACKFRAME64, 1150bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer PVOID, PREAD_PROCESS_MEMORY_ROUTINE64, 1160bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer PFUNCTION_TABLE_ACCESS_ROUTINE64, 1170bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer PGET_MODULE_BASE_ROUTINE64, 1180bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer PTRANSLATE_ADDRESS_ROUTINE64); 1190bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencerstatic fpStackWalk64 StackWalk64; 1200bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer 1210bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencertypedef DWORD64 (WINAPI *fpSymGetModuleBase64)(HANDLE, DWORD64); 1220bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencerstatic fpSymGetModuleBase64 SymGetModuleBase64; 1230bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer 1240bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencertypedef BOOL (WINAPI *fpSymGetSymFromAddr64)(HANDLE, DWORD64, 1250bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer PDWORD64, PIMAGEHLP_SYMBOL64); 1260bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencerstatic fpSymGetSymFromAddr64 SymGetSymFromAddr64; 1270bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer 1280bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencertypedef BOOL (WINAPI *fpSymGetLineFromAddr64)(HANDLE, DWORD64, 1290bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer PDWORD, PIMAGEHLP_LINE64); 1300bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencerstatic fpSymGetLineFromAddr64 SymGetLineFromAddr64; 1310bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer 1320bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencertypedef PVOID (WINAPI *fpSymFunctionTableAccess64)(HANDLE, DWORD64); 1330bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencerstatic fpSymFunctionTableAccess64 SymFunctionTableAccess64; 1340bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer 1350bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencerstatic bool load64BitDebugHelp(void) { 1360bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer HMODULE hLib = ::LoadLibrary("Dbghelp.dll"); 1370bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer if (hLib) { 1380bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer StackWalk64 = (fpStackWalk64) 1390bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer ::GetProcAddress(hLib, "StackWalk64"); 1400bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer SymGetModuleBase64 = (fpSymGetModuleBase64) 1410bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer ::GetProcAddress(hLib, "SymGetModuleBase64"); 1420bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer SymGetSymFromAddr64 = (fpSymGetSymFromAddr64) 1430bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer ::GetProcAddress(hLib, "SymGetSymFromAddr64"); 1440bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer SymGetLineFromAddr64 = (fpSymGetLineFromAddr64) 1450bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer ::GetProcAddress(hLib, "SymGetLineFromAddr64"); 1460bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer SymFunctionTableAccess64 = (fpSymFunctionTableAccess64) 1470bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer ::GetProcAddress(hLib, "SymFunctionTableAccess64"); 1480bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer } 1490bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer return StackWalk64 != NULL; 1500bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer} 151cda065df614dbf7ca0f6a169e9536d2241539b75Anton Korobeynikov #endif // !defined(__MINGW64_VERSION_MAJOR) 1520bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer#endif // __MINGW32__ 15390b54138834a057179c7a02931217ab5a82ed389Reid Spencer 15490b54138834a057179c7a02931217ab5a82ed389Reid Spencer// Forward declare. 15590b54138834a057179c7a02931217ab5a82ed389Reid Spencerstatic LONG WINAPI LLVMUnhandledExceptionFilter(LPEXCEPTION_POINTERS ep); 15690b54138834a057179c7a02931217ab5a82ed389Reid Spencerstatic BOOL WINAPI LLVMConsoleCtrlHandler(DWORD dwCtrlType); 15790b54138834a057179c7a02931217ab5a82ed389Reid Spencer 158ee841a1a8735805f84d609ae105bec92525033c6Jeff Cohen// InterruptFunction - The function to call if ctrl-c is pressed. 159ee841a1a8735805f84d609ae105bec92525033c6Jeff Cohenstatic void (*InterruptFunction)() = 0; 160ee841a1a8735805f84d609ae105bec92525033c6Jeff Cohen 161ced4110f5b068b9b64e3a55a9ee57b621ce4acb1Reid Spencerstatic std::vector<llvm::sys::Path> *FilesToRemove = NULL; 16235033a5876aa27ea5729bc29b41bb4460a303cadChris Lattnerstatic std::vector<std::pair<void(*)(void*), void*> > *CallBacksToRun = 0; 16390b54138834a057179c7a02931217ab5a82ed389Reid Spencerstatic bool RegisteredUnhandledExceptionFilter = false; 1647b60a15abc155196d9515a1e242ec0137afff753Reid Spencerstatic bool CleanupExecuted = false; 165df3388492bc2bfc73b3e0195693e2f67f10dcf52Daniel Dunbarstatic bool ExitOnUnhandledExceptions = false; 1667b60a15abc155196d9515a1e242ec0137afff753Reid Spencerstatic PTOP_LEVEL_EXCEPTION_FILTER OldFilter = NULL; 167298d6c14ca1936677aaf6cca3efc569b6e53d294Reid Spencer 168298d6c14ca1936677aaf6cca3efc569b6e53d294Reid Spencer// Windows creates a new thread to execute the console handler when an event 169298d6c14ca1936677aaf6cca3efc569b6e53d294Reid Spencer// (such as CTRL/C) occurs. This causes concurrency issues with the above 170298d6c14ca1936677aaf6cca3efc569b6e53d294Reid Spencer// globals which this critical section addresses. 17190b54138834a057179c7a02931217ab5a82ed389Reid Spencerstatic CRITICAL_SECTION CriticalSection; 17290b54138834a057179c7a02931217ab5a82ed389Reid Spencer 173496c277a6d161413e3f6976c9991ddccd8ecae8aReid Spencernamespace llvm { 174496c277a6d161413e3f6976c9991ddccd8ecae8aReid Spencer 175496c277a6d161413e3f6976c9991ddccd8ecae8aReid Spencer//===----------------------------------------------------------------------===// 17684ba14f6d016ab181f1fd5de8050e1b9bbc83904Mikhail Glushenkov//=== WARNING: Implementation here must contain only Win32 specific code 17790b54138834a057179c7a02931217ab5a82ed389Reid Spencer//=== and must not be UNIX code 178496c277a6d161413e3f6976c9991ddccd8ecae8aReid Spencer//===----------------------------------------------------------------------===// 179496c277a6d161413e3f6976c9991ddccd8ecae8aReid Spencer 1803be2d12bdec9ec3a244aae695d3b586ac27dcfdeDaniel Dunbar#ifdef _MSC_VER 181df3388492bc2bfc73b3e0195693e2f67f10dcf52Daniel Dunbar/// CRTReportHook - Function called on a CRT debugging event. 182df3388492bc2bfc73b3e0195693e2f67f10dcf52Daniel Dunbarstatic int CRTReportHook(int ReportType, char *Message, int *Return) { 183df3388492bc2bfc73b3e0195693e2f67f10dcf52Daniel Dunbar // Don't cause a DebugBreak() on return. 184df3388492bc2bfc73b3e0195693e2f67f10dcf52Daniel Dunbar if (Return) 185df3388492bc2bfc73b3e0195693e2f67f10dcf52Daniel Dunbar *Return = 0; 186df3388492bc2bfc73b3e0195693e2f67f10dcf52Daniel Dunbar 187df3388492bc2bfc73b3e0195693e2f67f10dcf52Daniel Dunbar switch (ReportType) { 188df3388492bc2bfc73b3e0195693e2f67f10dcf52Daniel Dunbar default: 189df3388492bc2bfc73b3e0195693e2f67f10dcf52Daniel Dunbar case _CRT_ASSERT: 190df3388492bc2bfc73b3e0195693e2f67f10dcf52Daniel Dunbar fprintf(stderr, "CRT assert: %s\n", Message); 191df3388492bc2bfc73b3e0195693e2f67f10dcf52Daniel Dunbar // FIXME: Is there a way to just crash? Perhaps throw to the unhandled 192df3388492bc2bfc73b3e0195693e2f67f10dcf52Daniel Dunbar // exception code? Perhaps SetErrorMode() handles this. 193df3388492bc2bfc73b3e0195693e2f67f10dcf52Daniel Dunbar _exit(3); 194df3388492bc2bfc73b3e0195693e2f67f10dcf52Daniel Dunbar break; 195df3388492bc2bfc73b3e0195693e2f67f10dcf52Daniel Dunbar case _CRT_ERROR: 196df3388492bc2bfc73b3e0195693e2f67f10dcf52Daniel Dunbar fprintf(stderr, "CRT error: %s\n", Message); 197df3388492bc2bfc73b3e0195693e2f67f10dcf52Daniel Dunbar // FIXME: Is there a way to just crash? Perhaps throw to the unhandled 198df3388492bc2bfc73b3e0195693e2f67f10dcf52Daniel Dunbar // exception code? Perhaps SetErrorMode() handles this. 199df3388492bc2bfc73b3e0195693e2f67f10dcf52Daniel Dunbar _exit(3); 200df3388492bc2bfc73b3e0195693e2f67f10dcf52Daniel Dunbar break; 201df3388492bc2bfc73b3e0195693e2f67f10dcf52Daniel Dunbar case _CRT_WARN: 202df3388492bc2bfc73b3e0195693e2f67f10dcf52Daniel Dunbar fprintf(stderr, "CRT warn: %s\n", Message); 203df3388492bc2bfc73b3e0195693e2f67f10dcf52Daniel Dunbar break; 204df3388492bc2bfc73b3e0195693e2f67f10dcf52Daniel Dunbar } 205df3388492bc2bfc73b3e0195693e2f67f10dcf52Daniel Dunbar 206df3388492bc2bfc73b3e0195693e2f67f10dcf52Daniel Dunbar // Don't call _CrtDbgReport. 207df3388492bc2bfc73b3e0195693e2f67f10dcf52Daniel Dunbar return TRUE; 208df3388492bc2bfc73b3e0195693e2f67f10dcf52Daniel Dunbar} 2093be2d12bdec9ec3a244aae695d3b586ac27dcfdeDaniel Dunbar#endif 21090b54138834a057179c7a02931217ab5a82ed389Reid Spencer 211df3388492bc2bfc73b3e0195693e2f67f10dcf52Daniel Dunbarstatic void RegisterHandler() { 212cda065df614dbf7ca0f6a169e9536d2241539b75Anton Korobeynikov#if __MINGW32__ && !defined(__MINGW64_VERSION_MAJOR) 213cda065df614dbf7ca0f6a169e9536d2241539b75Anton Korobeynikov // On MinGW.org, we need to load up the symbols explicitly, because the 2140bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer // Win32 framework they include does not have support for the 64-bit 2150bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer // versions of the APIs we need. If we cannot load up the APIs (which 2160bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer // would be unexpected as they should exist on every version of Windows 2170bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer // we support), we will bail out since there would be nothing to report. 2180bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer if (!load64BitDebugHelp()) { 2190bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer assert(false && "These APIs should always be available"); 2200bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer return; 2210bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer } 2220bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer#endif 2230bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer 2247b60a15abc155196d9515a1e242ec0137afff753Reid Spencer if (RegisteredUnhandledExceptionFilter) { 225298d6c14ca1936677aaf6cca3efc569b6e53d294Reid Spencer EnterCriticalSection(&CriticalSection); 22690b54138834a057179c7a02931217ab5a82ed389Reid Spencer return; 227298d6c14ca1936677aaf6cca3efc569b6e53d294Reid Spencer } 22890b54138834a057179c7a02931217ab5a82ed389Reid Spencer 22990b54138834a057179c7a02931217ab5a82ed389Reid Spencer // Now's the time to create the critical section. This is the first time 23090b54138834a057179c7a02931217ab5a82ed389Reid Spencer // through here, and there's only one thread. 23190b54138834a057179c7a02931217ab5a82ed389Reid Spencer InitializeCriticalSection(&CriticalSection); 23290b54138834a057179c7a02931217ab5a82ed389Reid Spencer 23390b54138834a057179c7a02931217ab5a82ed389Reid Spencer // Enter it immediately. Now if someone hits CTRL/C, the console handler 23490b54138834a057179c7a02931217ab5a82ed389Reid Spencer // can't proceed until the globals are updated. 23590b54138834a057179c7a02931217ab5a82ed389Reid Spencer EnterCriticalSection(&CriticalSection); 23690b54138834a057179c7a02931217ab5a82ed389Reid Spencer 23790b54138834a057179c7a02931217ab5a82ed389Reid Spencer RegisteredUnhandledExceptionFilter = true; 2387b60a15abc155196d9515a1e242ec0137afff753Reid Spencer OldFilter = SetUnhandledExceptionFilter(LLVMUnhandledExceptionFilter); 23990b54138834a057179c7a02931217ab5a82ed389Reid Spencer SetConsoleCtrlHandler(LLVMConsoleCtrlHandler, TRUE); 24090b54138834a057179c7a02931217ab5a82ed389Reid Spencer 241df3388492bc2bfc73b3e0195693e2f67f10dcf52Daniel Dunbar // Environment variable to disable any kind of crash dialog. 242df3388492bc2bfc73b3e0195693e2f67f10dcf52Daniel Dunbar if (getenv("LLVM_DISABLE_CRT_DEBUG")) { 243a8bbe707dc0c397d4020e7348fda64b3cb2a0e21NAKAMURA Takumi#ifdef _MSC_VER 244df3388492bc2bfc73b3e0195693e2f67f10dcf52Daniel Dunbar _CrtSetReportHook(CRTReportHook); 245a8bbe707dc0c397d4020e7348fda64b3cb2a0e21NAKAMURA Takumi#endif 246ac25e44d8905e88f91f998ce27a82cea641f5ff9NAKAMURA Takumi SetErrorMode(SEM_FAILCRITICALERRORS | 247ac25e44d8905e88f91f998ce27a82cea641f5ff9NAKAMURA Takumi SEM_NOGPFAULTERRORBOX | 248ac25e44d8905e88f91f998ce27a82cea641f5ff9NAKAMURA Takumi SEM_NOOPENFILEERRORBOX); 2493be2d12bdec9ec3a244aae695d3b586ac27dcfdeDaniel Dunbar ExitOnUnhandledExceptions = true; 250df3388492bc2bfc73b3e0195693e2f67f10dcf52Daniel Dunbar } 251df3388492bc2bfc73b3e0195693e2f67f10dcf52Daniel Dunbar 25290b54138834a057179c7a02931217ab5a82ed389Reid Spencer // IMPORTANT NOTE: Caller must call LeaveCriticalSection(&CriticalSection) or 25390b54138834a057179c7a02931217ab5a82ed389Reid Spencer // else multi-threading problems will ensue. 25490b54138834a057179c7a02931217ab5a82ed389Reid Spencer} 25590b54138834a057179c7a02931217ab5a82ed389Reid Spencer 256496c277a6d161413e3f6976c9991ddccd8ecae8aReid Spencer// RemoveFileOnSignal - The public API 25705545755676b9ff35d244e55d749a15e28bb228bReid Spencerbool sys::RemoveFileOnSignal(const sys::Path &Filename, std::string* ErrMsg) { 25890b54138834a057179c7a02931217ab5a82ed389Reid Spencer RegisterHandler(); 25990b54138834a057179c7a02931217ab5a82ed389Reid Spencer 26005545755676b9ff35d244e55d749a15e28bb228bReid Spencer if (CleanupExecuted) { 26105545755676b9ff35d244e55d749a15e28bb228bReid Spencer if (ErrMsg) 26205545755676b9ff35d244e55d749a15e28bb228bReid Spencer *ErrMsg = "Process terminating -- cannot register for removal"; 26305545755676b9ff35d244e55d749a15e28bb228bReid Spencer return true; 26405545755676b9ff35d244e55d749a15e28bb228bReid Spencer } 2657b60a15abc155196d9515a1e242ec0137afff753Reid Spencer 26690b54138834a057179c7a02931217ab5a82ed389Reid Spencer if (FilesToRemove == NULL) 267ced4110f5b068b9b64e3a55a9ee57b621ce4acb1Reid Spencer FilesToRemove = new std::vector<sys::Path>; 26890b54138834a057179c7a02931217ab5a82ed389Reid Spencer 26998601218901190d9d3bb5ebccae659f8db265b5dReid Spencer FilesToRemove->push_back(Filename); 27090b54138834a057179c7a02931217ab5a82ed389Reid Spencer 27190b54138834a057179c7a02931217ab5a82ed389Reid Spencer LeaveCriticalSection(&CriticalSection); 27205545755676b9ff35d244e55d749a15e28bb228bReid Spencer return false; 273496c277a6d161413e3f6976c9991ddccd8ecae8aReid Spencer} 274496c277a6d161413e3f6976c9991ddccd8ecae8aReid Spencer 27541154114f64c1531764236e9268d2a5ac52e3e91Dan Gohman// DontRemoveFileOnSignal - The public API 27641154114f64c1531764236e9268d2a5ac52e3e91Dan Gohmanvoid sys::DontRemoveFileOnSignal(const sys::Path &Filename) { 27741154114f64c1531764236e9268d2a5ac52e3e91Dan Gohman if (FilesToRemove == NULL) 27841154114f64c1531764236e9268d2a5ac52e3e91Dan Gohman return; 27941154114f64c1531764236e9268d2a5ac52e3e91Dan Gohman 2802172f3cd971d7446123f8bdc72b381adde0ea559NAKAMURA Takumi RegisterHandler(); 2812172f3cd971d7446123f8bdc72b381adde0ea559NAKAMURA Takumi 28241154114f64c1531764236e9268d2a5ac52e3e91Dan Gohman FilesToRemove->push_back(Filename); 28341154114f64c1531764236e9268d2a5ac52e3e91Dan Gohman std::vector<sys::Path>::reverse_iterator I = 28441154114f64c1531764236e9268d2a5ac52e3e91Dan Gohman std::find(FilesToRemove->rbegin(), FilesToRemove->rend(), Filename); 28541154114f64c1531764236e9268d2a5ac52e3e91Dan Gohman if (I != FilesToRemove->rend()) 28641154114f64c1531764236e9268d2a5ac52e3e91Dan Gohman FilesToRemove->erase(I.base()-1); 28741154114f64c1531764236e9268d2a5ac52e3e91Dan Gohman 28841154114f64c1531764236e9268d2a5ac52e3e91Dan Gohman LeaveCriticalSection(&CriticalSection); 28941154114f64c1531764236e9268d2a5ac52e3e91Dan Gohman} 29041154114f64c1531764236e9268d2a5ac52e3e91Dan Gohman 291496c277a6d161413e3f6976c9991ddccd8ecae8aReid Spencer/// PrintStackTraceOnErrorSignal - When an error signal (such as SIBABRT or 292496c277a6d161413e3f6976c9991ddccd8ecae8aReid Spencer/// SIGSEGV) is delivered to the process, print a stack trace and then exit. 29390b54138834a057179c7a02931217ab5a82ed389Reid Spencervoid sys::PrintStackTraceOnErrorSignal() { 29490b54138834a057179c7a02931217ab5a82ed389Reid Spencer RegisterHandler(); 29590b54138834a057179c7a02931217ab5a82ed389Reid Spencer LeaveCriticalSection(&CriticalSection); 29690b54138834a057179c7a02931217ab5a82ed389Reid Spencer} 29790b54138834a057179c7a02931217ab5a82ed389Reid Spencer 298fa8c292ebd893b3effef4ead9c88d261c628c340Chris Lattner 299fa8c292ebd893b3effef4ead9c88d261c628c340Chris Lattnervoid sys::SetInterruptFunction(void (*IF)()) { 300ee841a1a8735805f84d609ae105bec92525033c6Jeff Cohen RegisterHandler(); 30164fe58490d28b7f7ba3ecb78fd9290688ded8f0cJeff Cohen InterruptFunction = IF; 302ee841a1a8735805f84d609ae105bec92525033c6Jeff Cohen LeaveCriticalSection(&CriticalSection); 303fa8c292ebd893b3effef4ead9c88d261c628c340Chris Lattner} 30448fe63526e35ddaee7e98879596a569911f41319Sebastian Redl 30548fe63526e35ddaee7e98879596a569911f41319Sebastian Redl 30648fe63526e35ddaee7e98879596a569911f41319Sebastian Redl/// AddSignalHandler - Add a function to be called when a signal is delivered 30748fe63526e35ddaee7e98879596a569911f41319Sebastian Redl/// to the process. The handler can have a cookie passed to it to identify 30848fe63526e35ddaee7e98879596a569911f41319Sebastian Redl/// what instance of the handler it is. 30948fe63526e35ddaee7e98879596a569911f41319Sebastian Redlvoid sys::AddSignalHandler(void (*FnPtr)(void *), void *Cookie) { 31048fe63526e35ddaee7e98879596a569911f41319Sebastian Redl if (CallBacksToRun == 0) 31148fe63526e35ddaee7e98879596a569911f41319Sebastian Redl CallBacksToRun = new std::vector<std::pair<void(*)(void*), void*> >(); 31248fe63526e35ddaee7e98879596a569911f41319Sebastian Redl CallBacksToRun->push_back(std::make_pair(FnPtr, Cookie)); 31348fe63526e35ddaee7e98879596a569911f41319Sebastian Redl RegisterHandler(); 31461633368cfc04697d8e2030d66ab220464298acaTorok Edwin LeaveCriticalSection(&CriticalSection); 31548fe63526e35ddaee7e98879596a569911f41319Sebastian Redl} 316496c277a6d161413e3f6976c9991ddccd8ecae8aReid Spencer} 317496c277a6d161413e3f6976c9991ddccd8ecae8aReid Spencer 31890b54138834a057179c7a02931217ab5a82ed389Reid Spencerstatic void Cleanup() { 31990b54138834a057179c7a02931217ab5a82ed389Reid Spencer EnterCriticalSection(&CriticalSection); 32090b54138834a057179c7a02931217ab5a82ed389Reid Spencer 3217b60a15abc155196d9515a1e242ec0137afff753Reid Spencer // Prevent other thread from registering new files and directories for 3227b60a15abc155196d9515a1e242ec0137afff753Reid Spencer // removal, should we be executing because of the console handler callback. 3237b60a15abc155196d9515a1e242ec0137afff753Reid Spencer CleanupExecuted = true; 3247b60a15abc155196d9515a1e242ec0137afff753Reid Spencer 3257b60a15abc155196d9515a1e242ec0137afff753Reid Spencer // FIXME: open files cannot be deleted. 3267b60a15abc155196d9515a1e242ec0137afff753Reid Spencer 32790b54138834a057179c7a02931217ab5a82ed389Reid Spencer if (FilesToRemove != NULL) 32890b54138834a057179c7a02931217ab5a82ed389Reid Spencer while (!FilesToRemove->empty()) { 329ac356602f2fa0be3d198ada31c51c36d38a6f6ecChris Lattner FilesToRemove->back().eraseFromDisk(); 33090b54138834a057179c7a02931217ab5a82ed389Reid Spencer FilesToRemove->pop_back(); 33190b54138834a057179c7a02931217ab5a82ed389Reid Spencer } 33290b54138834a057179c7a02931217ab5a82ed389Reid Spencer 33335033a5876aa27ea5729bc29b41bb4460a303cadChris Lattner if (CallBacksToRun) 33435033a5876aa27ea5729bc29b41bb4460a303cadChris Lattner for (unsigned i = 0, e = CallBacksToRun->size(); i != e; ++i) 33535033a5876aa27ea5729bc29b41bb4460a303cadChris Lattner (*CallBacksToRun)[i].first((*CallBacksToRun)[i].second); 33690b54138834a057179c7a02931217ab5a82ed389Reid Spencer 33790b54138834a057179c7a02931217ab5a82ed389Reid Spencer LeaveCriticalSection(&CriticalSection); 33890b54138834a057179c7a02931217ab5a82ed389Reid Spencer} 33990b54138834a057179c7a02931217ab5a82ed389Reid Spencer 340fb89e08413878571c1c1fc6ff15cdbf5cd8692dcDaniel Dunbarvoid llvm::sys::RunInterruptHandlers() { 341fb89e08413878571c1c1fc6ff15cdbf5cd8692dcDaniel Dunbar Cleanup(); 342fb89e08413878571c1c1fc6ff15cdbf5cd8692dcDaniel Dunbar} 343fb89e08413878571c1c1fc6ff15cdbf5cd8692dcDaniel Dunbar 34490b54138834a057179c7a02931217ab5a82ed389Reid Spencerstatic LONG WINAPI LLVMUnhandledExceptionFilter(LPEXCEPTION_POINTERS ep) { 34511d03f690e7fe019c33c3a066a9171c61f6d61f9Mikhail Glushenkov Cleanup(); 34684ba14f6d016ab181f1fd5de8050e1b9bbc83904Mikhail Glushenkov 3476d8ac5ac6d87451d52651ba5e6cc0abffb4c264eMikhail Glushenkov // Initialize the STACKFRAME structure. 3480bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer STACKFRAME64 StackFrame; 3496d8ac5ac6d87451d52651ba5e6cc0abffb4c264eMikhail Glushenkov memset(&StackFrame, 0, sizeof(StackFrame)); 3506d8ac5ac6d87451d52651ba5e6cc0abffb4c264eMikhail Glushenkov 3510bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer DWORD machineType; 3520bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer#if defined(_M_X64) 3530bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer machineType = IMAGE_FILE_MACHINE_AMD64; 3540bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer StackFrame.AddrPC.Offset = ep->ContextRecord->Rip; 3550bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer StackFrame.AddrPC.Mode = AddrModeFlat; 3560bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer StackFrame.AddrStack.Offset = ep->ContextRecord->Rsp; 3570bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer StackFrame.AddrStack.Mode = AddrModeFlat; 3580bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer StackFrame.AddrFrame.Offset = ep->ContextRecord->Rbp; 3590bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer StackFrame.AddrFrame.Mode = AddrModeFlat; 3600bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer#elif defined(_M_IX86) 3610bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer machineType = IMAGE_FILE_MACHINE_I386; 3626d8ac5ac6d87451d52651ba5e6cc0abffb4c264eMikhail Glushenkov StackFrame.AddrPC.Offset = ep->ContextRecord->Eip; 3636d8ac5ac6d87451d52651ba5e6cc0abffb4c264eMikhail Glushenkov StackFrame.AddrPC.Mode = AddrModeFlat; 3646d8ac5ac6d87451d52651ba5e6cc0abffb4c264eMikhail Glushenkov StackFrame.AddrStack.Offset = ep->ContextRecord->Esp; 3656d8ac5ac6d87451d52651ba5e6cc0abffb4c264eMikhail Glushenkov StackFrame.AddrStack.Mode = AddrModeFlat; 3666d8ac5ac6d87451d52651ba5e6cc0abffb4c264eMikhail Glushenkov StackFrame.AddrFrame.Offset = ep->ContextRecord->Ebp; 3676d8ac5ac6d87451d52651ba5e6cc0abffb4c264eMikhail Glushenkov StackFrame.AddrFrame.Mode = AddrModeFlat; 3680bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer#endif 3696d8ac5ac6d87451d52651ba5e6cc0abffb4c264eMikhail Glushenkov 3706d8ac5ac6d87451d52651ba5e6cc0abffb4c264eMikhail Glushenkov HANDLE hProcess = GetCurrentProcess(); 3716d8ac5ac6d87451d52651ba5e6cc0abffb4c264eMikhail Glushenkov HANDLE hThread = GetCurrentThread(); 3726d8ac5ac6d87451d52651ba5e6cc0abffb4c264eMikhail Glushenkov 3736d8ac5ac6d87451d52651ba5e6cc0abffb4c264eMikhail Glushenkov // Initialize the symbol handler. 3746d8ac5ac6d87451d52651ba5e6cc0abffb4c264eMikhail Glushenkov SymSetOptions(SYMOPT_DEFERRED_LOADS|SYMOPT_LOAD_LINES); 3756d8ac5ac6d87451d52651ba5e6cc0abffb4c264eMikhail Glushenkov SymInitialize(hProcess, NULL, TRUE); 3766d8ac5ac6d87451d52651ba5e6cc0abffb4c264eMikhail Glushenkov 3776d8ac5ac6d87451d52651ba5e6cc0abffb4c264eMikhail Glushenkov while (true) { 3780bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer if (!StackWalk64(machineType, hProcess, hThread, &StackFrame, 3790bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer ep->ContextRecord, NULL, SymFunctionTableAccess64, 3800bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer SymGetModuleBase64, NULL)) { 3816d8ac5ac6d87451d52651ba5e6cc0abffb4c264eMikhail Glushenkov break; 3826d8ac5ac6d87451d52651ba5e6cc0abffb4c264eMikhail Glushenkov } 3836d8ac5ac6d87451d52651ba5e6cc0abffb4c264eMikhail Glushenkov 3846d8ac5ac6d87451d52651ba5e6cc0abffb4c264eMikhail Glushenkov if (StackFrame.AddrFrame.Offset == 0) 3856d8ac5ac6d87451d52651ba5e6cc0abffb4c264eMikhail Glushenkov break; 3866d8ac5ac6d87451d52651ba5e6cc0abffb4c264eMikhail Glushenkov 3876d8ac5ac6d87451d52651ba5e6cc0abffb4c264eMikhail Glushenkov // Print the PC in hexadecimal. 3880bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer DWORD64 PC = StackFrame.AddrPC.Offset; 3890bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer#if defined(_M_X64) 3900bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer fprintf(stderr, "0x%016llX", PC); 3910bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer#elif defined(_M_IX86) 3920bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer fprintf(stderr, "0x%08lX", static_cast<DWORD>(PC)); 3930bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer#endif 3946d8ac5ac6d87451d52651ba5e6cc0abffb4c264eMikhail Glushenkov 3956d8ac5ac6d87451d52651ba5e6cc0abffb4c264eMikhail Glushenkov // Print the parameters. Assume there are four. 3960bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer#if defined(_M_X64) 3970bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer fprintf(stderr, " (0x%016llX 0x%016llX 0x%016llX 0x%016llX)", 3980bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer StackFrame.Params[0], 3990bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer StackFrame.Params[1], 4000bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer StackFrame.Params[2], 4010bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer StackFrame.Params[3]); 4020bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer#elif defined(_M_IX86) 4036d8ac5ac6d87451d52651ba5e6cc0abffb4c264eMikhail Glushenkov fprintf(stderr, " (0x%08lX 0x%08lX 0x%08lX 0x%08lX)", 4040bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer static_cast<DWORD>(StackFrame.Params[0]), 4050bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer static_cast<DWORD>(StackFrame.Params[1]), 4060bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer static_cast<DWORD>(StackFrame.Params[2]), 4070bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer static_cast<DWORD>(StackFrame.Params[3])); 4080bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer#endif 4096d8ac5ac6d87451d52651ba5e6cc0abffb4c264eMikhail Glushenkov // Verify the PC belongs to a module in this process. 4100bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer if (!SymGetModuleBase64(hProcess, PC)) { 4116d8ac5ac6d87451d52651ba5e6cc0abffb4c264eMikhail Glushenkov fputs(" <unknown module>\n", stderr); 4126d8ac5ac6d87451d52651ba5e6cc0abffb4c264eMikhail Glushenkov continue; 4136d8ac5ac6d87451d52651ba5e6cc0abffb4c264eMikhail Glushenkov } 41490b54138834a057179c7a02931217ab5a82ed389Reid Spencer 4156d8ac5ac6d87451d52651ba5e6cc0abffb4c264eMikhail Glushenkov // Print the symbol name. 4166d8ac5ac6d87451d52651ba5e6cc0abffb4c264eMikhail Glushenkov char buffer[512]; 4170bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer IMAGEHLP_SYMBOL64 *symbol = reinterpret_cast<IMAGEHLP_SYMBOL64 *>(buffer); 4180bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer memset(symbol, 0, sizeof(IMAGEHLP_SYMBOL64)); 4190bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer symbol->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL64); 4200bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer symbol->MaxNameLength = 512 - sizeof(IMAGEHLP_SYMBOL64); 4216d8ac5ac6d87451d52651ba5e6cc0abffb4c264eMikhail Glushenkov 4220bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer DWORD64 dwDisp; 4230bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer if (!SymGetSymFromAddr64(hProcess, PC, &dwDisp, symbol)) { 42490b54138834a057179c7a02931217ab5a82ed389Reid Spencer fputc('\n', stderr); 4256d8ac5ac6d87451d52651ba5e6cc0abffb4c264eMikhail Glushenkov continue; 4266d8ac5ac6d87451d52651ba5e6cc0abffb4c264eMikhail Glushenkov } 4276d8ac5ac6d87451d52651ba5e6cc0abffb4c264eMikhail Glushenkov 4286d8ac5ac6d87451d52651ba5e6cc0abffb4c264eMikhail Glushenkov buffer[511] = 0; 4296d8ac5ac6d87451d52651ba5e6cc0abffb4c264eMikhail Glushenkov if (dwDisp > 0) 4300bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer fprintf(stderr, ", %s() + 0x%llX bytes(s)", symbol->Name, dwDisp); 4316d8ac5ac6d87451d52651ba5e6cc0abffb4c264eMikhail Glushenkov else 4326d8ac5ac6d87451d52651ba5e6cc0abffb4c264eMikhail Glushenkov fprintf(stderr, ", %s", symbol->Name); 4336d8ac5ac6d87451d52651ba5e6cc0abffb4c264eMikhail Glushenkov 4346d8ac5ac6d87451d52651ba5e6cc0abffb4c264eMikhail Glushenkov // Print the source file and line number information. 4350bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer IMAGEHLP_LINE64 line; 4360bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer DWORD dwLineDisp; 4376d8ac5ac6d87451d52651ba5e6cc0abffb4c264eMikhail Glushenkov memset(&line, 0, sizeof(line)); 4386d8ac5ac6d87451d52651ba5e6cc0abffb4c264eMikhail Glushenkov line.SizeOfStruct = sizeof(line); 4390bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer if (SymGetLineFromAddr64(hProcess, PC, &dwLineDisp, &line)) { 4406d8ac5ac6d87451d52651ba5e6cc0abffb4c264eMikhail Glushenkov fprintf(stderr, ", %s, line %lu", line.FileName, line.LineNumber); 4410bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer if (dwLineDisp > 0) 4420bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer fprintf(stderr, " + 0x%lX byte(s)", dwLineDisp); 44390b54138834a057179c7a02931217ab5a82ed389Reid Spencer } 4440ccb93034a47303509ee2c89b8bf13956a510b94Chuck Rose III 4456d8ac5ac6d87451d52651ba5e6cc0abffb4c264eMikhail Glushenkov fputc('\n', stderr); 4466d8ac5ac6d87451d52651ba5e6cc0abffb4c264eMikhail Glushenkov } 4476d8ac5ac6d87451d52651ba5e6cc0abffb4c264eMikhail Glushenkov 448df3388492bc2bfc73b3e0195693e2f67f10dcf52Daniel Dunbar if (ExitOnUnhandledExceptions) 4495d2f8c31556b6a5ce29d2cad314bc48af879c5b3NAKAMURA Takumi _exit(ep->ExceptionRecord->ExceptionCode); 450df3388492bc2bfc73b3e0195693e2f67f10dcf52Daniel Dunbar 45190b54138834a057179c7a02931217ab5a82ed389Reid Spencer // Allow dialog box to pop up allowing choice to start debugger. 4527b60a15abc155196d9515a1e242ec0137afff753Reid Spencer if (OldFilter) 4537b60a15abc155196d9515a1e242ec0137afff753Reid Spencer return (*OldFilter)(ep); 4547b60a15abc155196d9515a1e242ec0137afff753Reid Spencer else 4557b60a15abc155196d9515a1e242ec0137afff753Reid Spencer return EXCEPTION_CONTINUE_SEARCH; 45690b54138834a057179c7a02931217ab5a82ed389Reid Spencer} 45790b54138834a057179c7a02931217ab5a82ed389Reid Spencer 45890b54138834a057179c7a02931217ab5a82ed389Reid Spencerstatic BOOL WINAPI LLVMConsoleCtrlHandler(DWORD dwCtrlType) { 45964fe58490d28b7f7ba3ecb78fd9290688ded8f0cJeff Cohen // We are running in our very own thread, courtesy of Windows. 460ee841a1a8735805f84d609ae105bec92525033c6Jeff Cohen EnterCriticalSection(&CriticalSection); 46190b54138834a057179c7a02931217ab5a82ed389Reid Spencer Cleanup(); 46290b54138834a057179c7a02931217ab5a82ed389Reid Spencer 463ee841a1a8735805f84d609ae105bec92525033c6Jeff Cohen // If an interrupt function has been set, go and run one it; otherwise, 464ee841a1a8735805f84d609ae105bec92525033c6Jeff Cohen // the process dies. 465ee841a1a8735805f84d609ae105bec92525033c6Jeff Cohen void (*IF)() = InterruptFunction; 466ee841a1a8735805f84d609ae105bec92525033c6Jeff Cohen InterruptFunction = 0; // Don't run it on another CTRL-C. 467ee841a1a8735805f84d609ae105bec92525033c6Jeff Cohen 468ee841a1a8735805f84d609ae105bec92525033c6Jeff Cohen if (IF) { 46964fe58490d28b7f7ba3ecb78fd9290688ded8f0cJeff Cohen // Note: if the interrupt function throws an exception, there is nothing 47064fe58490d28b7f7ba3ecb78fd9290688ded8f0cJeff Cohen // to catch it in this thread so it will kill the process. 47164fe58490d28b7f7ba3ecb78fd9290688ded8f0cJeff Cohen IF(); // Run it now. 472ee841a1a8735805f84d609ae105bec92525033c6Jeff Cohen LeaveCriticalSection(&CriticalSection); 473ee841a1a8735805f84d609ae105bec92525033c6Jeff Cohen return TRUE; // Don't kill the process. 474ee841a1a8735805f84d609ae105bec92525033c6Jeff Cohen } 475ee841a1a8735805f84d609ae105bec92525033c6Jeff Cohen 476298d6c14ca1936677aaf6cca3efc569b6e53d294Reid Spencer // Allow normal processing to take place; i.e., the process dies. 477ee841a1a8735805f84d609ae105bec92525033c6Jeff Cohen LeaveCriticalSection(&CriticalSection); 47890b54138834a057179c7a02931217ab5a82ed389Reid Spencer return FALSE; 479496c277a6d161413e3f6976c9991ddccd8ecae8aReid Spencer} 4800bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer 4810bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer#if __MINGW32__ 4820bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer // We turned these warnings off for this file so that MinGW-g++ doesn't 4830bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer // complain about the ll format specifiers used. Now we are turning the 4840bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer // warnings back on. If MinGW starts to support diagnostic stacks, we can 4850bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer // replace this with a pop. 4860bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer #pragma GCC diagnostic warning "-Wformat" 4870bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer #pragma GCC diagnostic warning "-Wformat-extra-args" 4880bcd9c70b12b684706fbc0e337a827fd73c4f30aMichael J. Spencer#endif 489