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