Signals.inc 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561
  1. //===- Win32/Signals.cpp - Win32 Signals Implementation ---------*- C++ -*-===//
  2. //
  3. // The LLVM Compiler Infrastructure
  4. //
  5. // This file is distributed under the University of Illinois Open Source
  6. // License. See LICENSE.TXT for details.
  7. //
  8. //===----------------------------------------------------------------------===//
  9. //
  10. // This file provides the Win32 specific implementation of the Signals class.
  11. //
  12. //===----------------------------------------------------------------------===//
  13. #if 0 // HLSL Change - disable signal processing
  14. #include "llvm/Support/FileSystem.h"
  15. #include <algorithm>
  16. #include <signal.h>
  17. #include <stdio.h>
  18. #include <vector>
  19. #include "llvm/Support/Format.h"
  20. #include "llvm/Support/raw_ostream.h"
  21. // The Windows.h header must be after LLVM and standard headers.
  22. #include "WindowsSupport.h"
  23. #ifdef __MINGW32__
  24. #include <imagehlp.h>
  25. #else
  26. #include <dbghelp.h>
  27. #endif
  28. #include <psapi.h>
  29. #ifdef _MSC_VER
  30. #pragma comment(lib, "psapi.lib")
  31. #elif __MINGW32__
  32. #if (HAVE_LIBPSAPI != 1)
  33. #error "libpsapi.a should be present"
  34. #endif
  35. // The version of g++ that comes with MinGW does *not* properly understand
  36. // the ll format specifier for printf. However, MinGW passes the format
  37. // specifiers on to the MSVCRT entirely, and the CRT understands the ll
  38. // specifier. So these warnings are spurious in this case. Since we compile
  39. // with -Wall, this will generate these warnings which should be ignored. So
  40. // we will turn off the warnings for this just file. However, MinGW also does
  41. // not support push and pop for diagnostics, so we have to manually turn it
  42. // back on at the end of the file.
  43. #pragma GCC diagnostic ignored "-Wformat"
  44. #pragma GCC diagnostic ignored "-Wformat-extra-args"
  45. #if !defined(__MINGW64_VERSION_MAJOR)
  46. // MinGW.org does not have updated support for the 64-bit versions of the
  47. // DebugHlp APIs. So we will have to load them manually. The structures and
  48. // method signatures were pulled from DbgHelp.h in the Windows Platform SDK,
  49. // and adjusted for brevity.
  50. typedef struct _IMAGEHLP_LINE64 {
  51. DWORD SizeOfStruct;
  52. PVOID Key;
  53. DWORD LineNumber;
  54. PCHAR FileName;
  55. DWORD64 Address;
  56. } IMAGEHLP_LINE64, *PIMAGEHLP_LINE64;
  57. typedef struct _IMAGEHLP_SYMBOL64 {
  58. DWORD SizeOfStruct;
  59. DWORD64 Address;
  60. DWORD Size;
  61. DWORD Flags;
  62. DWORD MaxNameLength;
  63. CHAR Name[1];
  64. } IMAGEHLP_SYMBOL64, *PIMAGEHLP_SYMBOL64;
  65. typedef struct _tagADDRESS64 {
  66. DWORD64 Offset;
  67. WORD Segment;
  68. ADDRESS_MODE Mode;
  69. } ADDRESS64, *LPADDRESS64;
  70. typedef struct _KDHELP64 {
  71. DWORD64 Thread;
  72. DWORD ThCallbackStack;
  73. DWORD ThCallbackBStore;
  74. DWORD NextCallback;
  75. DWORD FramePointer;
  76. DWORD64 KiCallUserMode;
  77. DWORD64 KeUserCallbackDispatcher;
  78. DWORD64 SystemRangeStart;
  79. DWORD64 KiUserExceptionDispatcher;
  80. DWORD64 StackBase;
  81. DWORD64 StackLimit;
  82. DWORD64 Reserved[5];
  83. } KDHELP64, *PKDHELP64;
  84. typedef struct _tagSTACKFRAME64 {
  85. ADDRESS64 AddrPC;
  86. ADDRESS64 AddrReturn;
  87. ADDRESS64 AddrFrame;
  88. ADDRESS64 AddrStack;
  89. ADDRESS64 AddrBStore;
  90. PVOID FuncTableEntry;
  91. DWORD64 Params[4];
  92. BOOL Far;
  93. BOOL Virtual;
  94. DWORD64 Reserved[3];
  95. KDHELP64 KdHelp;
  96. } STACKFRAME64, *LPSTACKFRAME64;
  97. #endif // !defined(__MINGW64_VERSION_MAJOR)
  98. #endif // __MINGW32__
  99. typedef BOOL (__stdcall *PREAD_PROCESS_MEMORY_ROUTINE64)(HANDLE hProcess,
  100. DWORD64 qwBaseAddress, PVOID lpBuffer, DWORD nSize,
  101. LPDWORD lpNumberOfBytesRead);
  102. typedef PVOID (__stdcall *PFUNCTION_TABLE_ACCESS_ROUTINE64)( HANDLE ahProcess,
  103. DWORD64 AddrBase);
  104. typedef DWORD64 (__stdcall *PGET_MODULE_BASE_ROUTINE64)(HANDLE hProcess,
  105. DWORD64 Address);
  106. typedef DWORD64 (__stdcall *PTRANSLATE_ADDRESS_ROUTINE64)(HANDLE hProcess,
  107. HANDLE hThread, LPADDRESS64 lpaddr);
  108. typedef BOOL (WINAPI *fpStackWalk64)(DWORD, HANDLE, HANDLE, LPSTACKFRAME64,
  109. PVOID, PREAD_PROCESS_MEMORY_ROUTINE64,
  110. PFUNCTION_TABLE_ACCESS_ROUTINE64,
  111. PGET_MODULE_BASE_ROUTINE64,
  112. PTRANSLATE_ADDRESS_ROUTINE64);
  113. static fpStackWalk64 fStackWalk64;
  114. typedef DWORD64 (WINAPI *fpSymGetModuleBase64)(HANDLE, DWORD64);
  115. static fpSymGetModuleBase64 fSymGetModuleBase64;
  116. typedef BOOL (WINAPI *fpSymGetSymFromAddr64)(HANDLE, DWORD64,
  117. PDWORD64, PIMAGEHLP_SYMBOL64);
  118. static fpSymGetSymFromAddr64 fSymGetSymFromAddr64;
  119. typedef BOOL (WINAPI *fpSymGetLineFromAddr64)(HANDLE, DWORD64,
  120. PDWORD, PIMAGEHLP_LINE64);
  121. static fpSymGetLineFromAddr64 fSymGetLineFromAddr64;
  122. typedef PVOID (WINAPI *fpSymFunctionTableAccess64)(HANDLE, DWORD64);
  123. static fpSymFunctionTableAccess64 fSymFunctionTableAccess64;
  124. typedef DWORD (WINAPI *fpSymSetOptions)(DWORD);
  125. static fpSymSetOptions fSymSetOptions;
  126. typedef BOOL (WINAPI *fpSymInitialize)(HANDLE, PCSTR, BOOL);
  127. static fpSymInitialize fSymInitialize;
  128. static bool load64BitDebugHelp(void) {
  129. HMODULE hLib = ::LoadLibraryW(L"Dbghelp.dll");
  130. if (hLib) {
  131. fStackWalk64 = (fpStackWalk64)
  132. ::GetProcAddress(hLib, "StackWalk64");
  133. fSymGetModuleBase64 = (fpSymGetModuleBase64)
  134. ::GetProcAddress(hLib, "SymGetModuleBase64");
  135. fSymGetSymFromAddr64 = (fpSymGetSymFromAddr64)
  136. ::GetProcAddress(hLib, "SymGetSymFromAddr64");
  137. fSymGetLineFromAddr64 = (fpSymGetLineFromAddr64)
  138. ::GetProcAddress(hLib, "SymGetLineFromAddr64");
  139. fSymFunctionTableAccess64 = (fpSymFunctionTableAccess64)
  140. ::GetProcAddress(hLib, "SymFunctionTableAccess64");
  141. fSymSetOptions = (fpSymSetOptions)::GetProcAddress(hLib, "SymSetOptions");
  142. fSymInitialize = (fpSymInitialize)::GetProcAddress(hLib, "SymInitialize");
  143. }
  144. return fStackWalk64 && fSymInitialize && fSymSetOptions;
  145. }
  146. // Forward declare.
  147. static LONG WINAPI LLVMUnhandledExceptionFilter(LPEXCEPTION_POINTERS ep);
  148. static BOOL WINAPI LLVMConsoleCtrlHandler(DWORD dwCtrlType);
  149. // InterruptFunction - The function to call if ctrl-c is pressed.
  150. static void (*InterruptFunction)() = 0;
  151. static std::vector<std::string> *FilesToRemove = NULL;
  152. static std::vector<std::pair<void(*)(void*), void*> > *CallBacksToRun = 0;
  153. static bool RegisteredUnhandledExceptionFilter = false;
  154. static bool CleanupExecuted = false;
  155. static PTOP_LEVEL_EXCEPTION_FILTER OldFilter = NULL;
  156. // Windows creates a new thread to execute the console handler when an event
  157. // (such as CTRL/C) occurs. This causes concurrency issues with the above
  158. // globals which this critical section addresses.
  159. static CRITICAL_SECTION CriticalSection;
  160. static bool CriticalSectionInitialized = false;
  161. static void PrintStackTraceForThread(llvm::raw_ostream &OS, HANDLE hProcess,
  162. HANDLE hThread, STACKFRAME64 &StackFrame,
  163. CONTEXT *Context) {
  164. DWORD machineType;
  165. #if defined(_M_X64)
  166. machineType = IMAGE_FILE_MACHINE_AMD64;
  167. #else
  168. machineType = IMAGE_FILE_MACHINE_I386;
  169. #endif
  170. // Initialize the symbol handler.
  171. fSymSetOptions(SYMOPT_DEFERRED_LOADS | SYMOPT_LOAD_LINES);
  172. fSymInitialize(hProcess, NULL, TRUE);
  173. while (true) {
  174. if (!fStackWalk64(machineType, hProcess, hThread, &StackFrame, Context, 0,
  175. fSymFunctionTableAccess64, fSymGetModuleBase64, 0)) {
  176. break;
  177. }
  178. if (StackFrame.AddrFrame.Offset == 0)
  179. break;
  180. using namespace llvm;
  181. // Print the PC in hexadecimal.
  182. DWORD64 PC = StackFrame.AddrPC.Offset;
  183. #if defined(_M_X64)
  184. OS << format("0x%016llX", PC);
  185. #elif defined(_M_IX86)
  186. OS << format("0x%08lX", static_cast<DWORD>(PC));
  187. #endif
  188. // Print the parameters. Assume there are four.
  189. #if defined(_M_X64)
  190. OS << format(" (0x%016llX 0x%016llX 0x%016llX 0x%016llX)",
  191. StackFrame.Params[0], StackFrame.Params[1], StackFrame.Params[2],
  192. StackFrame.Params[3]);
  193. #elif defined(_M_IX86)
  194. OS << format(" (0x%08lX 0x%08lX 0x%08lX 0x%08lX)",
  195. static_cast<DWORD>(StackFrame.Params[0]),
  196. static_cast<DWORD>(StackFrame.Params[1]),
  197. static_cast<DWORD>(StackFrame.Params[2]),
  198. static_cast<DWORD>(StackFrame.Params[3]));
  199. #endif
  200. // Verify the PC belongs to a module in this process.
  201. if (!fSymGetModuleBase64(hProcess, PC)) {
  202. OS << " <unknown module>\n";
  203. continue;
  204. }
  205. // Print the symbol name.
  206. char buffer[512];
  207. IMAGEHLP_SYMBOL64 *symbol = reinterpret_cast<IMAGEHLP_SYMBOL64 *>(buffer);
  208. memset(symbol, 0, sizeof(IMAGEHLP_SYMBOL64));
  209. symbol->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL64);
  210. symbol->MaxNameLength = 512 - sizeof(IMAGEHLP_SYMBOL64);
  211. DWORD64 dwDisp;
  212. if (!fSymGetSymFromAddr64(hProcess, PC, &dwDisp, symbol)) {
  213. OS << '\n';
  214. continue;
  215. }
  216. buffer[511] = 0;
  217. if (dwDisp > 0)
  218. OS << format(", %s() + 0x%llX bytes(s)", (const char*)symbol->Name,
  219. dwDisp);
  220. else
  221. OS << format(", %s", (const char*)symbol->Name);
  222. // Print the source file and line number information.
  223. IMAGEHLP_LINE64 line = {};
  224. DWORD dwLineDisp;
  225. line.SizeOfStruct = sizeof(line);
  226. if (fSymGetLineFromAddr64(hProcess, PC, &dwLineDisp, &line)) {
  227. OS << format(", %s, line %lu", line.FileName, line.LineNumber);
  228. if (dwLineDisp > 0)
  229. OS << format(" + 0x%lX byte(s)", dwLineDisp);
  230. }
  231. OS << '\n';
  232. }
  233. }
  234. namespace llvm {
  235. //===----------------------------------------------------------------------===//
  236. //=== WARNING: Implementation here must contain only Win32 specific code
  237. //=== and must not be UNIX code
  238. //===----------------------------------------------------------------------===//
  239. #ifdef _MSC_VER
  240. /// AvoidMessageBoxHook - Emulates hitting "retry" from an "abort, retry,
  241. /// ignore" CRT debug report dialog. "retry" raises an exception which
  242. /// ultimately triggers our stack dumper.
  243. static LLVM_ATTRIBUTE_UNUSED int
  244. __cdecl // HLSL Change
  245. AvoidMessageBoxHook(int ReportType, char *Message, int *Return) {
  246. // Set *Return to the retry code for the return value of _CrtDbgReport:
  247. // http://msdn.microsoft.com/en-us/library/8hyw4sy7(v=vs.71).aspx
  248. // This may also trigger just-in-time debugging via DebugBreak().
  249. if (Return)
  250. *Return = 1;
  251. // Don't call _CrtDbgReport.
  252. return TRUE;
  253. }
  254. #endif
  255. extern "C" void HandleAbort(int Sig) {
  256. if (Sig == SIGABRT) {
  257. LLVM_BUILTIN_TRAP;
  258. }
  259. }
  260. static void InitializeThreading() {
  261. if (CriticalSectionInitialized)
  262. return;
  263. // Now's the time to create the critical section. This is the first time
  264. // through here, and there's only one thread.
  265. InitializeCriticalSection(&CriticalSection);
  266. CriticalSectionInitialized = true;
  267. }
  268. static void RegisterHandler() {
  269. // If we cannot load up the APIs (which would be unexpected as they should
  270. // exist on every version of Windows we support), we will bail out since
  271. // there would be nothing to report.
  272. if (!load64BitDebugHelp()) {
  273. assert(false && "These APIs should always be available");
  274. return;
  275. }
  276. if (RegisteredUnhandledExceptionFilter) {
  277. EnterCriticalSection(&CriticalSection);
  278. return;
  279. }
  280. InitializeThreading();
  281. // Enter it immediately. Now if someone hits CTRL/C, the console handler
  282. // can't proceed until the globals are updated.
  283. EnterCriticalSection(&CriticalSection);
  284. RegisteredUnhandledExceptionFilter = true;
  285. OldFilter = SetUnhandledExceptionFilter(LLVMUnhandledExceptionFilter);
  286. SetConsoleCtrlHandler(LLVMConsoleCtrlHandler, TRUE);
  287. // IMPORTANT NOTE: Caller must call LeaveCriticalSection(&CriticalSection) or
  288. // else multi-threading problems will ensue.
  289. }
  290. // RemoveFileOnSignal - The public API
  291. bool sys::RemoveFileOnSignal(StringRef Filename, std::string* ErrMsg) {
  292. RegisterHandler();
  293. if (CleanupExecuted) {
  294. if (ErrMsg)
  295. *ErrMsg = "Process terminating -- cannot register for removal";
  296. return true;
  297. }
  298. if (FilesToRemove == NULL)
  299. FilesToRemove = new std::vector<std::string>;
  300. FilesToRemove->push_back(Filename);
  301. LeaveCriticalSection(&CriticalSection);
  302. return false;
  303. }
  304. // DontRemoveFileOnSignal - The public API
  305. void sys::DontRemoveFileOnSignal(StringRef Filename) {
  306. if (FilesToRemove == NULL)
  307. return;
  308. RegisterHandler();
  309. std::vector<std::string>::reverse_iterator I =
  310. std::find(FilesToRemove->rbegin(), FilesToRemove->rend(), Filename);
  311. if (I != FilesToRemove->rend())
  312. FilesToRemove->erase(I.base()-1);
  313. LeaveCriticalSection(&CriticalSection);
  314. }
  315. void sys::DisableSystemDialogsOnCrash() {
  316. // Crash to stack trace handler on abort.
  317. signal(SIGABRT, HandleAbort);
  318. // The following functions are not reliably accessible on MinGW.
  319. #ifdef _MSC_VER
  320. // We're already handling writing a "something went wrong" message.
  321. _set_abort_behavior(0, _WRITE_ABORT_MSG);
  322. // Disable Dr. Watson.
  323. _set_abort_behavior(0, _CALL_REPORTFAULT);
  324. _CrtSetReportHook(AvoidMessageBoxHook);
  325. #endif
  326. // Disable standard error dialog box.
  327. SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX |
  328. SEM_NOOPENFILEERRORBOX);
  329. _set_error_mode(_OUT_TO_STDERR);
  330. }
  331. /// PrintStackTraceOnErrorSignal - When an error signal (such as SIBABRT or
  332. /// SIGSEGV) is delivered to the process, print a stack trace and then exit.
  333. void sys::PrintStackTraceOnErrorSignal(bool DisableCrashReporting) {
  334. DisableSystemDialogsOnCrash();
  335. RegisterHandler();
  336. LeaveCriticalSection(&CriticalSection);
  337. }
  338. }
  339. #if defined(__MINGW32__) && !defined(__MINGW64_VERSION_MAJOR)
  340. // Provide a prototype for RtlCaptureContext, mingw32 from mingw.org is
  341. // missing it but mingw-w64 has it.
  342. extern "C" VOID WINAPI RtlCaptureContext(PCONTEXT ContextRecord);
  343. #endif
  344. void llvm::sys::PrintStackTrace(raw_ostream &OS) {
  345. STACKFRAME64 StackFrame = {};
  346. CONTEXT Context = {};
  347. ::RtlCaptureContext(&Context);
  348. #if defined(_M_X64)
  349. StackFrame.AddrPC.Offset = Context.Rip;
  350. StackFrame.AddrStack.Offset = Context.Rsp;
  351. StackFrame.AddrFrame.Offset = Context.Rbp;
  352. #else
  353. StackFrame.AddrPC.Offset = Context.Eip;
  354. StackFrame.AddrStack.Offset = Context.Esp;
  355. StackFrame.AddrFrame.Offset = Context.Ebp;
  356. #endif
  357. StackFrame.AddrPC.Mode = AddrModeFlat;
  358. StackFrame.AddrStack.Mode = AddrModeFlat;
  359. StackFrame.AddrFrame.Mode = AddrModeFlat;
  360. PrintStackTraceForThread(OS, GetCurrentProcess(), GetCurrentThread(),
  361. StackFrame, &Context);
  362. }
  363. void llvm::sys::SetInterruptFunction(void (*IF)()) {
  364. RegisterHandler();
  365. InterruptFunction = IF;
  366. LeaveCriticalSection(&CriticalSection);
  367. }
  368. /// AddSignalHandler - Add a function to be called when a signal is delivered
  369. /// to the process. The handler can have a cookie passed to it to identify
  370. /// what instance of the handler it is.
  371. void llvm::sys::AddSignalHandler(void (*FnPtr)(void *), void *Cookie) {
  372. if (CallBacksToRun == 0)
  373. CallBacksToRun = new std::vector<std::pair<void(*)(void*), void*> >();
  374. CallBacksToRun->push_back(std::make_pair(FnPtr, Cookie));
  375. RegisterHandler();
  376. LeaveCriticalSection(&CriticalSection);
  377. }
  378. static void Cleanup() {
  379. if (CleanupExecuted)
  380. return;
  381. EnterCriticalSection(&CriticalSection);
  382. // Prevent other thread from registering new files and directories for
  383. // removal, should we be executing because of the console handler callback.
  384. CleanupExecuted = true;
  385. // FIXME: open files cannot be deleted.
  386. if (FilesToRemove != NULL)
  387. while (!FilesToRemove->empty()) {
  388. llvm::sys::fs::remove(FilesToRemove->back());
  389. FilesToRemove->pop_back();
  390. }
  391. if (CallBacksToRun)
  392. for (auto &I : *CallBacksToRun)
  393. I.first(I.second);
  394. LeaveCriticalSection(&CriticalSection);
  395. }
  396. void llvm::sys::RunInterruptHandlers() {
  397. // The interrupt handler may be called from an interrupt, but it may also be
  398. // called manually (such as the case of report_fatal_error with no registered
  399. // error handler). We must ensure that the critical section is properly
  400. // initialized.
  401. InitializeThreading();
  402. Cleanup();
  403. }
  404. static LONG WINAPI LLVMUnhandledExceptionFilter(LPEXCEPTION_POINTERS ep) {
  405. Cleanup();
  406. // Initialize the STACKFRAME structure.
  407. STACKFRAME64 StackFrame = {};
  408. #if defined(_M_X64)
  409. StackFrame.AddrPC.Offset = ep->ContextRecord->Rip;
  410. StackFrame.AddrPC.Mode = AddrModeFlat;
  411. StackFrame.AddrStack.Offset = ep->ContextRecord->Rsp;
  412. StackFrame.AddrStack.Mode = AddrModeFlat;
  413. StackFrame.AddrFrame.Offset = ep->ContextRecord->Rbp;
  414. StackFrame.AddrFrame.Mode = AddrModeFlat;
  415. #elif defined(_M_IX86)
  416. StackFrame.AddrPC.Offset = ep->ContextRecord->Eip;
  417. StackFrame.AddrPC.Mode = AddrModeFlat;
  418. StackFrame.AddrStack.Offset = ep->ContextRecord->Esp;
  419. StackFrame.AddrStack.Mode = AddrModeFlat;
  420. StackFrame.AddrFrame.Offset = ep->ContextRecord->Ebp;
  421. StackFrame.AddrFrame.Mode = AddrModeFlat;
  422. #endif
  423. HANDLE hProcess = GetCurrentProcess();
  424. HANDLE hThread = GetCurrentThread();
  425. PrintStackTraceForThread(llvm::errs(), hProcess, hThread, StackFrame,
  426. ep->ContextRecord);
  427. _exit(ep->ExceptionRecord->ExceptionCode);
  428. }
  429. static BOOL WINAPI LLVMConsoleCtrlHandler(DWORD dwCtrlType) {
  430. // We are running in our very own thread, courtesy of Windows.
  431. EnterCriticalSection(&CriticalSection);
  432. Cleanup();
  433. // If an interrupt function has been set, go and run one it; otherwise,
  434. // the process dies.
  435. void (*IF)() = InterruptFunction;
  436. InterruptFunction = 0; // Don't run it on another CTRL-C.
  437. if (IF) {
  438. // Note: if the interrupt function throws an exception, there is nothing
  439. // to catch it in this thread so it will kill the process.
  440. IF(); // Run it now.
  441. LeaveCriticalSection(&CriticalSection);
  442. return TRUE; // Don't kill the process.
  443. }
  444. // Allow normal processing to take place; i.e., the process dies.
  445. LeaveCriticalSection(&CriticalSection);
  446. return FALSE;
  447. }
  448. #if __MINGW32__
  449. // We turned these warnings off for this file so that MinGW-g++ doesn't
  450. // complain about the ll format specifiers used. Now we are turning the
  451. // warnings back on. If MinGW starts to support diagnostic stacks, we can
  452. // replace this with a pop.
  453. #pragma GCC diagnostic warning "-Wformat"
  454. #pragma GCC diagnostic warning "-Wformat-extra-args"
  455. #endif
  456. #else
  457. namespace llvm {
  458. namespace sys {
  459. bool RemoveFileOnSignal(StringRef Filename, std::string* ErrMsg) { return false; }
  460. void DontRemoveFileOnSignal(StringRef Filename) { }
  461. void PrintStackTraceOnErrorSignal(bool) { }
  462. void PrintStackTrace(FILE *) { }
  463. void SetInterruptFunction(void (*IF)()) { }
  464. void AddSignalHandler(void (*FnPtr)(void *), void *Cookie) { }
  465. void RunInterruptHandlers() { }
  466. } }
  467. #endif // HLSL Change - disable signal processing