Signals.inc 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875
  1. //===- Win32/Signals.cpp - Win32 Signals Implementation ---------*- C++ -*-===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. //
  9. // This file provides the Win32 specific implementation of the Signals class.
  10. //
  11. //===----------------------------------------------------------------------===//
  12. #include "llvm/Support/ConvertUTF.h"
  13. #include "llvm/Support/FileSystem.h"
  14. #include "llvm/Support/Path.h"
  15. #include "llvm/Support/Process.h"
  16. #include "llvm/Support/WindowsError.h"
  17. #include <algorithm>
  18. #include <io.h>
  19. #include <signal.h>
  20. #include <stdio.h>
  21. #include "llvm/Support/Format.h"
  22. #include "llvm/Support/raw_ostream.h"
  23. // The Windows.h header must be after LLVM and standard headers.
  24. #include "llvm/Support/Windows/WindowsSupport.h"
  25. #ifdef __MINGW32__
  26. #include <imagehlp.h>
  27. #else
  28. #include <crtdbg.h>
  29. #include <dbghelp.h>
  30. #endif
  31. #include <psapi.h>
  32. #ifdef _MSC_VER
  33. #pragma comment(lib, "psapi.lib")
  34. #elif __MINGW32__
  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 *fpMiniDumpWriteDump)(HANDLE, DWORD, HANDLE, MINIDUMP_TYPE,
  109. PMINIDUMP_EXCEPTION_INFORMATION,
  110. PMINIDUMP_USER_STREAM_INFORMATION,
  111. PMINIDUMP_CALLBACK_INFORMATION);
  112. static fpMiniDumpWriteDump fMiniDumpWriteDump;
  113. typedef BOOL (WINAPI *fpStackWalk64)(DWORD, HANDLE, HANDLE, LPSTACKFRAME64,
  114. PVOID, PREAD_PROCESS_MEMORY_ROUTINE64,
  115. PFUNCTION_TABLE_ACCESS_ROUTINE64,
  116. PGET_MODULE_BASE_ROUTINE64,
  117. PTRANSLATE_ADDRESS_ROUTINE64);
  118. static fpStackWalk64 fStackWalk64;
  119. typedef DWORD64 (WINAPI *fpSymGetModuleBase64)(HANDLE, DWORD64);
  120. static fpSymGetModuleBase64 fSymGetModuleBase64;
  121. typedef BOOL (WINAPI *fpSymGetSymFromAddr64)(HANDLE, DWORD64,
  122. PDWORD64, PIMAGEHLP_SYMBOL64);
  123. static fpSymGetSymFromAddr64 fSymGetSymFromAddr64;
  124. typedef BOOL (WINAPI *fpSymGetLineFromAddr64)(HANDLE, DWORD64,
  125. PDWORD, PIMAGEHLP_LINE64);
  126. static fpSymGetLineFromAddr64 fSymGetLineFromAddr64;
  127. typedef BOOL(WINAPI *fpSymGetModuleInfo64)(HANDLE hProcess, DWORD64 dwAddr,
  128. PIMAGEHLP_MODULE64 ModuleInfo);
  129. static fpSymGetModuleInfo64 fSymGetModuleInfo64;
  130. typedef PVOID (WINAPI *fpSymFunctionTableAccess64)(HANDLE, DWORD64);
  131. static fpSymFunctionTableAccess64 fSymFunctionTableAccess64;
  132. typedef DWORD (WINAPI *fpSymSetOptions)(DWORD);
  133. static fpSymSetOptions fSymSetOptions;
  134. typedef BOOL (WINAPI *fpSymInitialize)(HANDLE, PCSTR, BOOL);
  135. static fpSymInitialize fSymInitialize;
  136. typedef BOOL (WINAPI *fpEnumerateLoadedModules)(HANDLE,PENUMLOADED_MODULES_CALLBACK64,PVOID);
  137. static fpEnumerateLoadedModules fEnumerateLoadedModules;
  138. static bool load64BitDebugHelp(void) {
  139. HMODULE hLib = ::LoadLibraryW(L"Dbghelp.dll");
  140. if (hLib) {
  141. fMiniDumpWriteDump = (fpMiniDumpWriteDump)
  142. ::GetProcAddress(hLib, "MiniDumpWriteDump");
  143. fStackWalk64 = (fpStackWalk64)
  144. ::GetProcAddress(hLib, "StackWalk64");
  145. fSymGetModuleBase64 = (fpSymGetModuleBase64)
  146. ::GetProcAddress(hLib, "SymGetModuleBase64");
  147. fSymGetSymFromAddr64 = (fpSymGetSymFromAddr64)
  148. ::GetProcAddress(hLib, "SymGetSymFromAddr64");
  149. fSymGetLineFromAddr64 = (fpSymGetLineFromAddr64)
  150. ::GetProcAddress(hLib, "SymGetLineFromAddr64");
  151. fSymGetModuleInfo64 = (fpSymGetModuleInfo64)
  152. ::GetProcAddress(hLib, "SymGetModuleInfo64");
  153. fSymFunctionTableAccess64 = (fpSymFunctionTableAccess64)
  154. ::GetProcAddress(hLib, "SymFunctionTableAccess64");
  155. fSymSetOptions = (fpSymSetOptions)::GetProcAddress(hLib, "SymSetOptions");
  156. fSymInitialize = (fpSymInitialize)::GetProcAddress(hLib, "SymInitialize");
  157. fEnumerateLoadedModules = (fpEnumerateLoadedModules)
  158. ::GetProcAddress(hLib, "EnumerateLoadedModules64");
  159. }
  160. return fStackWalk64 && fSymInitialize && fSymSetOptions && fMiniDumpWriteDump;
  161. }
  162. using namespace llvm;
  163. // Forward declare.
  164. static LONG WINAPI LLVMUnhandledExceptionFilter(LPEXCEPTION_POINTERS ep);
  165. static BOOL WINAPI LLVMConsoleCtrlHandler(DWORD dwCtrlType);
  166. // The function to call if ctrl-c is pressed.
  167. static void (*InterruptFunction)() = 0;
  168. static std::vector<std::string> *FilesToRemove = NULL;
  169. static bool RegisteredUnhandledExceptionFilter = false;
  170. static bool CleanupExecuted = false;
  171. static PTOP_LEVEL_EXCEPTION_FILTER OldFilter = NULL;
  172. // Windows creates a new thread to execute the console handler when an event
  173. // (such as CTRL/C) occurs. This causes concurrency issues with the above
  174. // globals which this critical section addresses.
  175. static CRITICAL_SECTION CriticalSection;
  176. static bool CriticalSectionInitialized = false;
  177. static StringRef Argv0;
  178. enum {
  179. #if defined(_M_X64)
  180. NativeMachineType = IMAGE_FILE_MACHINE_AMD64
  181. #elif defined(_M_ARM64)
  182. NativeMachineType = IMAGE_FILE_MACHINE_ARM64
  183. #elif defined(_M_IX86)
  184. NativeMachineType = IMAGE_FILE_MACHINE_I386
  185. #elif defined(_M_ARM)
  186. NativeMachineType = IMAGE_FILE_MACHINE_ARMNT
  187. #else
  188. NativeMachineType = IMAGE_FILE_MACHINE_UNKNOWN
  189. #endif
  190. };
  191. static bool printStackTraceWithLLVMSymbolizer(llvm::raw_ostream &OS,
  192. HANDLE hProcess, HANDLE hThread,
  193. STACKFRAME64 &StackFrameOrig,
  194. CONTEXT *ContextOrig) {
  195. // StackWalk64 modifies the incoming stack frame and context, so copy them.
  196. STACKFRAME64 StackFrame = StackFrameOrig;
  197. // Copy the register context so that we don't modify it while we unwind. We
  198. // could use InitializeContext + CopyContext, but that's only required to get
  199. // at AVX registers, which typically aren't needed by StackWalk64. Reduce the
  200. // flag set to indicate that there's less data.
  201. CONTEXT Context = *ContextOrig;
  202. Context.ContextFlags = CONTEXT_CONTROL | CONTEXT_INTEGER;
  203. static void *StackTrace[256];
  204. size_t Depth = 0;
  205. while (fStackWalk64(NativeMachineType, hProcess, hThread, &StackFrame,
  206. &Context, 0, fSymFunctionTableAccess64,
  207. fSymGetModuleBase64, 0)) {
  208. if (StackFrame.AddrFrame.Offset == 0)
  209. break;
  210. StackTrace[Depth++] = (void *)(uintptr_t)StackFrame.AddrPC.Offset;
  211. if (Depth >= array_lengthof(StackTrace))
  212. break;
  213. }
  214. return printSymbolizedStackTrace(Argv0, &StackTrace[0], Depth, OS);
  215. }
  216. namespace {
  217. struct FindModuleData {
  218. void **StackTrace;
  219. int Depth;
  220. const char **Modules;
  221. intptr_t *Offsets;
  222. StringSaver *StrPool;
  223. };
  224. }
  225. static BOOL CALLBACK findModuleCallback(PCSTR ModuleName,
  226. DWORD64 ModuleBase, ULONG ModuleSize,
  227. void *VoidData) {
  228. FindModuleData *Data = (FindModuleData*)VoidData;
  229. intptr_t Beg = ModuleBase;
  230. intptr_t End = Beg + ModuleSize;
  231. for (int I = 0; I < Data->Depth; I++) {
  232. if (Data->Modules[I])
  233. continue;
  234. intptr_t Addr = (intptr_t)Data->StackTrace[I];
  235. if (Beg <= Addr && Addr < End) {
  236. Data->Modules[I] = Data->StrPool->save(ModuleName).data();
  237. Data->Offsets[I] = Addr - Beg;
  238. }
  239. }
  240. return TRUE;
  241. }
  242. static bool findModulesAndOffsets(void **StackTrace, int Depth,
  243. const char **Modules, intptr_t *Offsets,
  244. const char *MainExecutableName,
  245. StringSaver &StrPool) {
  246. if (!fEnumerateLoadedModules)
  247. return false;
  248. FindModuleData Data;
  249. Data.StackTrace = StackTrace;
  250. Data.Depth = Depth;
  251. Data.Modules = Modules;
  252. Data.Offsets = Offsets;
  253. Data.StrPool = &StrPool;
  254. fEnumerateLoadedModules(GetCurrentProcess(), findModuleCallback, &Data);
  255. return true;
  256. }
  257. static void PrintStackTraceForThread(llvm::raw_ostream &OS, HANDLE hProcess,
  258. HANDLE hThread, STACKFRAME64 &StackFrame,
  259. CONTEXT *Context) {
  260. // Initialize the symbol handler.
  261. fSymSetOptions(SYMOPT_DEFERRED_LOADS | SYMOPT_LOAD_LINES);
  262. fSymInitialize(hProcess, NULL, TRUE);
  263. // Try llvm-symbolizer first. llvm-symbolizer knows how to deal with both PDBs
  264. // and DWARF, so it should do a good job regardless of what debug info or
  265. // linker is in use.
  266. if (printStackTraceWithLLVMSymbolizer(OS, hProcess, hThread, StackFrame,
  267. Context)) {
  268. return;
  269. }
  270. while (true) {
  271. if (!fStackWalk64(NativeMachineType, hProcess, hThread, &StackFrame,
  272. Context, 0, fSymFunctionTableAccess64,
  273. fSymGetModuleBase64, 0)) {
  274. break;
  275. }
  276. if (StackFrame.AddrFrame.Offset == 0)
  277. break;
  278. using namespace llvm;
  279. // Print the PC in hexadecimal.
  280. DWORD64 PC = StackFrame.AddrPC.Offset;
  281. #if defined(_M_X64) || defined(_M_ARM64)
  282. OS << format("0x%016llX", PC);
  283. #elif defined(_M_IX86) || defined(_M_ARM)
  284. OS << format("0x%08lX", static_cast<DWORD>(PC));
  285. #endif
  286. // Print the parameters. Assume there are four.
  287. #if defined(_M_X64) || defined(_M_ARM64)
  288. OS << format(" (0x%016llX 0x%016llX 0x%016llX 0x%016llX)",
  289. StackFrame.Params[0], StackFrame.Params[1], StackFrame.Params[2],
  290. StackFrame.Params[3]);
  291. #elif defined(_M_IX86) || defined(_M_ARM)
  292. OS << format(" (0x%08lX 0x%08lX 0x%08lX 0x%08lX)",
  293. static_cast<DWORD>(StackFrame.Params[0]),
  294. static_cast<DWORD>(StackFrame.Params[1]),
  295. static_cast<DWORD>(StackFrame.Params[2]),
  296. static_cast<DWORD>(StackFrame.Params[3]));
  297. #endif
  298. // Verify the PC belongs to a module in this process.
  299. if (!fSymGetModuleBase64(hProcess, PC)) {
  300. OS << " <unknown module>\n";
  301. continue;
  302. }
  303. // Print the symbol name.
  304. char buffer[512];
  305. IMAGEHLP_SYMBOL64 *symbol = reinterpret_cast<IMAGEHLP_SYMBOL64 *>(buffer);
  306. memset(symbol, 0, sizeof(IMAGEHLP_SYMBOL64));
  307. symbol->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL64);
  308. symbol->MaxNameLength = 512 - sizeof(IMAGEHLP_SYMBOL64);
  309. DWORD64 dwDisp;
  310. if (!fSymGetSymFromAddr64(hProcess, PC, &dwDisp, symbol)) {
  311. OS << '\n';
  312. continue;
  313. }
  314. buffer[511] = 0;
  315. if (dwDisp > 0)
  316. OS << format(", %s() + 0x%llX bytes(s)", (const char*)symbol->Name,
  317. dwDisp);
  318. else
  319. OS << format(", %s", (const char*)symbol->Name);
  320. // Print the source file and line number information.
  321. IMAGEHLP_LINE64 line = {};
  322. DWORD dwLineDisp;
  323. line.SizeOfStruct = sizeof(line);
  324. if (fSymGetLineFromAddr64(hProcess, PC, &dwLineDisp, &line)) {
  325. OS << format(", %s, line %lu", line.FileName, line.LineNumber);
  326. if (dwLineDisp > 0)
  327. OS << format(" + 0x%lX byte(s)", dwLineDisp);
  328. }
  329. OS << '\n';
  330. }
  331. }
  332. namespace llvm {
  333. //===----------------------------------------------------------------------===//
  334. //=== WARNING: Implementation here must contain only Win32 specific code
  335. //=== and must not be UNIX code
  336. //===----------------------------------------------------------------------===//
  337. #ifdef _MSC_VER
  338. /// Emulates hitting "retry" from an "abort, retry, ignore" CRT debug report
  339. /// dialog. "retry" raises an exception which ultimately triggers our stack
  340. /// dumper.
  341. static LLVM_ATTRIBUTE_UNUSED int
  342. AvoidMessageBoxHook(int ReportType, char *Message, int *Return) {
  343. // Set *Return to the retry code for the return value of _CrtDbgReport:
  344. // http://msdn.microsoft.com/en-us/library/8hyw4sy7(v=vs.71).aspx
  345. // This may also trigger just-in-time debugging via DebugBreak().
  346. if (Return)
  347. *Return = 1;
  348. // Don't call _CrtDbgReport.
  349. return TRUE;
  350. }
  351. #endif
  352. extern "C" void HandleAbort(int Sig) {
  353. if (Sig == SIGABRT) {
  354. LLVM_BUILTIN_TRAP;
  355. }
  356. }
  357. static void InitializeThreading() {
  358. if (CriticalSectionInitialized)
  359. return;
  360. // Now's the time to create the critical section. This is the first time
  361. // through here, and there's only one thread.
  362. InitializeCriticalSection(&CriticalSection);
  363. CriticalSectionInitialized = true;
  364. }
  365. static void RegisterHandler() {
  366. // If we cannot load up the APIs (which would be unexpected as they should
  367. // exist on every version of Windows we support), we will bail out since
  368. // there would be nothing to report.
  369. if (!load64BitDebugHelp()) {
  370. assert(false && "These APIs should always be available");
  371. return;
  372. }
  373. if (RegisteredUnhandledExceptionFilter) {
  374. EnterCriticalSection(&CriticalSection);
  375. return;
  376. }
  377. InitializeThreading();
  378. // Enter it immediately. Now if someone hits CTRL/C, the console handler
  379. // can't proceed until the globals are updated.
  380. EnterCriticalSection(&CriticalSection);
  381. RegisteredUnhandledExceptionFilter = true;
  382. OldFilter = SetUnhandledExceptionFilter(LLVMUnhandledExceptionFilter);
  383. SetConsoleCtrlHandler(LLVMConsoleCtrlHandler, TRUE);
  384. // IMPORTANT NOTE: Caller must call LeaveCriticalSection(&CriticalSection) or
  385. // else multi-threading problems will ensue.
  386. }
  387. // The public API
  388. bool sys::RemoveFileOnSignal(StringRef Filename, std::string* ErrMsg) {
  389. RegisterHandler();
  390. if (CleanupExecuted) {
  391. if (ErrMsg)
  392. *ErrMsg = "Process terminating -- cannot register for removal";
  393. return true;
  394. }
  395. if (FilesToRemove == NULL)
  396. FilesToRemove = new std::vector<std::string>;
  397. FilesToRemove->push_back(std::string(Filename));
  398. LeaveCriticalSection(&CriticalSection);
  399. return false;
  400. }
  401. // The public API
  402. void sys::DontRemoveFileOnSignal(StringRef Filename) {
  403. if (FilesToRemove == NULL)
  404. return;
  405. RegisterHandler();
  406. std::vector<std::string>::reverse_iterator I =
  407. find(reverse(*FilesToRemove), Filename);
  408. if (I != FilesToRemove->rend())
  409. FilesToRemove->erase(I.base()-1);
  410. LeaveCriticalSection(&CriticalSection);
  411. }
  412. void sys::DisableSystemDialogsOnCrash() {
  413. // Crash to stack trace handler on abort.
  414. signal(SIGABRT, HandleAbort);
  415. // The following functions are not reliably accessible on MinGW.
  416. #ifdef _MSC_VER
  417. // We're already handling writing a "something went wrong" message.
  418. _set_abort_behavior(0, _WRITE_ABORT_MSG);
  419. // Disable Dr. Watson.
  420. _set_abort_behavior(0, _CALL_REPORTFAULT);
  421. _CrtSetReportHook(AvoidMessageBoxHook);
  422. #endif
  423. // Disable standard error dialog box.
  424. SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX |
  425. SEM_NOOPENFILEERRORBOX);
  426. _set_error_mode(_OUT_TO_STDERR);
  427. }
  428. /// When an error signal (such as SIGABRT or SIGSEGV) is delivered to the
  429. /// process, print a stack trace and then exit.
  430. void sys::PrintStackTraceOnErrorSignal(StringRef Argv0,
  431. bool DisableCrashReporting) {
  432. ::Argv0 = Argv0;
  433. if (DisableCrashReporting || getenv("LLVM_DISABLE_CRASH_REPORT"))
  434. Process::PreventCoreFiles();
  435. DisableSystemDialogsOnCrash();
  436. RegisterHandler();
  437. LeaveCriticalSection(&CriticalSection);
  438. }
  439. }
  440. #if defined(__MINGW32__) && !defined(__MINGW64_VERSION_MAJOR)
  441. // Provide a prototype for RtlCaptureContext, mingw32 from mingw.org is
  442. // missing it but mingw-w64 has it.
  443. extern "C" VOID WINAPI RtlCaptureContext(PCONTEXT ContextRecord);
  444. #endif
  445. static void LocalPrintStackTrace(raw_ostream &OS, PCONTEXT C) {
  446. STACKFRAME64 StackFrame{};
  447. CONTEXT Context{};
  448. if (!C) {
  449. ::RtlCaptureContext(&Context);
  450. C = &Context;
  451. }
  452. #if defined(_M_X64)
  453. StackFrame.AddrPC.Offset = Context.Rip;
  454. StackFrame.AddrStack.Offset = Context.Rsp;
  455. StackFrame.AddrFrame.Offset = Context.Rbp;
  456. #elif defined(_M_IX86)
  457. StackFrame.AddrPC.Offset = Context.Eip;
  458. StackFrame.AddrStack.Offset = Context.Esp;
  459. StackFrame.AddrFrame.Offset = Context.Ebp;
  460. #elif defined(_M_ARM64)
  461. StackFrame.AddrPC.Offset = Context.Pc;
  462. StackFrame.AddrStack.Offset = Context.Sp;
  463. StackFrame.AddrFrame.Offset = Context.Fp;
  464. #elif defined(_M_ARM)
  465. StackFrame.AddrPC.Offset = Context.Pc;
  466. StackFrame.AddrStack.Offset = Context.Sp;
  467. StackFrame.AddrFrame.Offset = Context.R11;
  468. #endif
  469. StackFrame.AddrPC.Mode = AddrModeFlat;
  470. StackFrame.AddrStack.Mode = AddrModeFlat;
  471. StackFrame.AddrFrame.Mode = AddrModeFlat;
  472. PrintStackTraceForThread(OS, GetCurrentProcess(), GetCurrentThread(),
  473. StackFrame, C);
  474. }
  475. void llvm::sys::PrintStackTrace(raw_ostream &OS, int Depth) {
  476. // FIXME: Handle "Depth" parameter to print stack trace upto specified Depth
  477. LocalPrintStackTrace(OS, nullptr);
  478. }
  479. void llvm::sys::SetInterruptFunction(void (*IF)()) {
  480. RegisterHandler();
  481. InterruptFunction = IF;
  482. LeaveCriticalSection(&CriticalSection);
  483. }
  484. void llvm::sys::SetInfoSignalFunction(void (*Handler)()) {
  485. // Unimplemented.
  486. }
  487. void llvm::sys::SetOneShotPipeSignalFunction(void (*Handler)()) {
  488. // Unimplemented.
  489. }
  490. void llvm::sys::DefaultOneShotPipeSignalHandler() {
  491. // Unimplemented.
  492. }
  493. /// Add a function to be called when a signal is delivered to the process. The
  494. /// handler can have a cookie passed to it to identify what instance of the
  495. /// handler it is.
  496. void llvm::sys::AddSignalHandler(sys::SignalHandlerCallback FnPtr,
  497. void *Cookie) {
  498. insertSignalHandler(FnPtr, Cookie);
  499. RegisterHandler();
  500. LeaveCriticalSection(&CriticalSection);
  501. }
  502. static void Cleanup(bool ExecuteSignalHandlers) {
  503. if (CleanupExecuted)
  504. return;
  505. EnterCriticalSection(&CriticalSection);
  506. // Prevent other thread from registering new files and directories for
  507. // removal, should we be executing because of the console handler callback.
  508. CleanupExecuted = true;
  509. // FIXME: open files cannot be deleted.
  510. if (FilesToRemove != NULL)
  511. while (!FilesToRemove->empty()) {
  512. llvm::sys::fs::remove(FilesToRemove->back());
  513. FilesToRemove->pop_back();
  514. }
  515. if (ExecuteSignalHandlers)
  516. llvm::sys::RunSignalHandlers();
  517. LeaveCriticalSection(&CriticalSection);
  518. }
  519. void llvm::sys::RunInterruptHandlers() {
  520. // The interrupt handler may be called from an interrupt, but it may also be
  521. // called manually (such as the case of report_fatal_error with no registered
  522. // error handler). We must ensure that the critical section is properly
  523. // initialized.
  524. InitializeThreading();
  525. Cleanup(true);
  526. }
  527. /// Find the Windows Registry Key for a given location.
  528. ///
  529. /// \returns a valid HKEY if the location exists, else NULL.
  530. static HKEY FindWERKey(const llvm::Twine &RegistryLocation) {
  531. HKEY Key;
  532. if (ERROR_SUCCESS != ::RegOpenKeyExA(HKEY_LOCAL_MACHINE,
  533. RegistryLocation.str().c_str(), 0,
  534. KEY_QUERY_VALUE | KEY_READ, &Key))
  535. return NULL;
  536. return Key;
  537. }
  538. /// Populate ResultDirectory with the value for "DumpFolder" for a given
  539. /// Windows Registry key.
  540. ///
  541. /// \returns true if a valid value for DumpFolder exists, false otherwise.
  542. static bool GetDumpFolder(HKEY Key,
  543. llvm::SmallVectorImpl<char> &ResultDirectory) {
  544. using llvm::sys::windows::UTF16ToUTF8;
  545. if (!Key)
  546. return false;
  547. DWORD BufferLengthBytes = 0;
  548. if (ERROR_SUCCESS != ::RegGetValueW(Key, 0, L"DumpFolder", REG_EXPAND_SZ,
  549. NULL, NULL, &BufferLengthBytes))
  550. return false;
  551. SmallVector<wchar_t, MAX_PATH> Buffer(BufferLengthBytes);
  552. if (ERROR_SUCCESS != ::RegGetValueW(Key, 0, L"DumpFolder", REG_EXPAND_SZ,
  553. NULL, Buffer.data(), &BufferLengthBytes))
  554. return false;
  555. DWORD ExpandBufferSize = ::ExpandEnvironmentStringsW(Buffer.data(), NULL, 0);
  556. if (!ExpandBufferSize)
  557. return false;
  558. SmallVector<wchar_t, MAX_PATH> ExpandBuffer(ExpandBufferSize);
  559. if (ExpandBufferSize != ::ExpandEnvironmentStringsW(Buffer.data(),
  560. ExpandBuffer.data(),
  561. ExpandBufferSize))
  562. return false;
  563. if (UTF16ToUTF8(ExpandBuffer.data(), ExpandBufferSize - 1, ResultDirectory))
  564. return false;
  565. return true;
  566. }
  567. /// Populate ResultType with a valid MINIDUMP_TYPE based on the value of
  568. /// "DumpType" for a given Windows Registry key.
  569. ///
  570. /// According to
  571. /// https://msdn.microsoft.com/en-us/library/windows/desktop/bb787181(v=vs.85).aspx
  572. /// valid values for DumpType are:
  573. /// * 0: Custom dump
  574. /// * 1: Mini dump
  575. /// * 2: Full dump
  576. /// If "Custom dump" is specified then the "CustomDumpFlags" field is read
  577. /// containing a bitwise combination of MINIDUMP_TYPE values.
  578. ///
  579. /// \returns true if a valid value for ResultType can be set, false otherwise.
  580. static bool GetDumpType(HKEY Key, MINIDUMP_TYPE &ResultType) {
  581. if (!Key)
  582. return false;
  583. DWORD DumpType;
  584. DWORD TypeSize = sizeof(DumpType);
  585. if (ERROR_SUCCESS != ::RegGetValueW(Key, NULL, L"DumpType", RRF_RT_REG_DWORD,
  586. NULL, &DumpType,
  587. &TypeSize))
  588. return false;
  589. switch (DumpType) {
  590. case 0: {
  591. DWORD Flags = 0;
  592. if (ERROR_SUCCESS != ::RegGetValueW(Key, NULL, L"CustomDumpFlags",
  593. RRF_RT_REG_DWORD, NULL, &Flags,
  594. &TypeSize))
  595. return false;
  596. ResultType = static_cast<MINIDUMP_TYPE>(Flags);
  597. break;
  598. }
  599. case 1:
  600. ResultType = MiniDumpNormal;
  601. break;
  602. case 2:
  603. ResultType = MiniDumpWithFullMemory;
  604. break;
  605. default:
  606. return false;
  607. }
  608. return true;
  609. }
  610. /// Write a Windows dump file containing process information that can be
  611. /// used for post-mortem debugging.
  612. ///
  613. /// \returns zero error code if a mini dump created, actual error code
  614. /// otherwise.
  615. static std::error_code WINAPI
  616. WriteWindowsDumpFile(PMINIDUMP_EXCEPTION_INFORMATION ExceptionInfo) {
  617. using namespace llvm;
  618. using namespace llvm::sys;
  619. std::string MainExecutableName = fs::getMainExecutable(nullptr, nullptr);
  620. StringRef ProgramName;
  621. if (MainExecutableName.empty()) {
  622. // If we can't get the executable filename,
  623. // things are in worse shape than we realize
  624. // and we should just bail out.
  625. return mapWindowsError(::GetLastError());
  626. }
  627. ProgramName = path::filename(MainExecutableName.c_str());
  628. // The Windows Registry location as specified at
  629. // https://msdn.microsoft.com/en-us/library/windows/desktop/bb787181%28v=vs.85%29.aspx
  630. // "Collecting User-Mode Dumps" that may optionally be set to collect crash
  631. // dumps in a specified location.
  632. StringRef LocalDumpsRegistryLocation =
  633. "SOFTWARE\\Microsoft\\Windows\\Windows Error Reporting\\LocalDumps";
  634. // The key pointing to the Registry location that may contain global crash
  635. // dump settings. This will be NULL if the location can not be found.
  636. ScopedRegHandle DefaultLocalDumpsKey(FindWERKey(LocalDumpsRegistryLocation));
  637. // The key pointing to the Registry location that may contain
  638. // application-specific crash dump settings. This will be NULL if the
  639. // location can not be found.
  640. ScopedRegHandle AppSpecificKey(
  641. FindWERKey(Twine(LocalDumpsRegistryLocation) + "\\" + ProgramName));
  642. // Look to see if a dump type is specified in the registry; first with the
  643. // app-specific key and failing that with the global key. If none are found
  644. // default to a normal dump (GetDumpType will return false either if the key
  645. // is NULL or if there is no valid DumpType value at its location).
  646. MINIDUMP_TYPE DumpType;
  647. if (!GetDumpType(AppSpecificKey, DumpType))
  648. if (!GetDumpType(DefaultLocalDumpsKey, DumpType))
  649. DumpType = MiniDumpNormal;
  650. // Look to see if a dump location is specified on the command line. If not,
  651. // look to see if a dump location is specified in the registry; first with the
  652. // app-specific key and failing that with the global key. If none are found
  653. // we'll just create the dump file in the default temporary file location
  654. // (GetDumpFolder will return false either if the key is NULL or if there is
  655. // no valid DumpFolder value at its location).
  656. bool ExplicitDumpDirectorySet = true;
  657. SmallString<MAX_PATH> DumpDirectory(*CrashDiagnosticsDirectory);
  658. if (DumpDirectory.empty())
  659. if (!GetDumpFolder(AppSpecificKey, DumpDirectory))
  660. if (!GetDumpFolder(DefaultLocalDumpsKey, DumpDirectory))
  661. ExplicitDumpDirectorySet = false;
  662. int FD;
  663. SmallString<MAX_PATH> DumpPath;
  664. if (ExplicitDumpDirectorySet) {
  665. if (std::error_code EC = fs::create_directories(DumpDirectory))
  666. return EC;
  667. if (std::error_code EC = fs::createUniqueFile(
  668. Twine(DumpDirectory) + "\\" + ProgramName + ".%%%%%%.dmp", FD,
  669. DumpPath))
  670. return EC;
  671. } else if (std::error_code EC =
  672. fs::createTemporaryFile(ProgramName, "dmp", FD, DumpPath))
  673. return EC;
  674. // Our support functions return a file descriptor but Windows wants a handle.
  675. ScopedCommonHandle FileHandle(reinterpret_cast<HANDLE>(_get_osfhandle(FD)));
  676. if (!fMiniDumpWriteDump(::GetCurrentProcess(), ::GetCurrentProcessId(),
  677. FileHandle, DumpType, ExceptionInfo, NULL, NULL))
  678. return mapWindowsError(::GetLastError());
  679. llvm::errs() << "Wrote crash dump file \"" << DumpPath << "\"\n";
  680. return std::error_code();
  681. }
  682. void sys::CleanupOnSignal(uintptr_t Context) {
  683. LLVMUnhandledExceptionFilter((LPEXCEPTION_POINTERS)Context);
  684. }
  685. static LONG WINAPI LLVMUnhandledExceptionFilter(LPEXCEPTION_POINTERS ep) {
  686. Cleanup(true);
  687. // We'll automatically write a Minidump file here to help diagnose
  688. // the nasty sorts of crashes that aren't 100% reproducible from a set of
  689. // inputs (or in the event that the user is unable or unwilling to provide a
  690. // reproducible case).
  691. if (!llvm::sys::Process::AreCoreFilesPrevented()) {
  692. MINIDUMP_EXCEPTION_INFORMATION ExceptionInfo;
  693. ExceptionInfo.ThreadId = ::GetCurrentThreadId();
  694. ExceptionInfo.ExceptionPointers = ep;
  695. ExceptionInfo.ClientPointers = FALSE;
  696. if (std::error_code EC = WriteWindowsDumpFile(&ExceptionInfo))
  697. llvm::errs() << "Could not write crash dump file: " << EC.message()
  698. << "\n";
  699. }
  700. // Stack unwinding appears to modify the context. Copy it to preserve the
  701. // caller's context.
  702. CONTEXT ContextCopy;
  703. if (ep)
  704. memcpy(&ContextCopy, ep->ContextRecord, sizeof(ContextCopy));
  705. LocalPrintStackTrace(llvm::errs(), ep ? &ContextCopy : nullptr);
  706. return EXCEPTION_EXECUTE_HANDLER;
  707. }
  708. static BOOL WINAPI LLVMConsoleCtrlHandler(DWORD dwCtrlType) {
  709. // We are running in our very own thread, courtesy of Windows.
  710. EnterCriticalSection(&CriticalSection);
  711. // This function is only ever called when a CTRL-C or similar control signal
  712. // is fired. Killing a process in this way is normal, so don't trigger the
  713. // signal handlers.
  714. Cleanup(false);
  715. // If an interrupt function has been set, go and run one it; otherwise,
  716. // the process dies.
  717. void (*IF)() = InterruptFunction;
  718. InterruptFunction = 0; // Don't run it on another CTRL-C.
  719. if (IF) {
  720. // Note: if the interrupt function throws an exception, there is nothing
  721. // to catch it in this thread so it will kill the process.
  722. IF(); // Run it now.
  723. LeaveCriticalSection(&CriticalSection);
  724. return TRUE; // Don't kill the process.
  725. }
  726. // Allow normal processing to take place; i.e., the process dies.
  727. LeaveCriticalSection(&CriticalSection);
  728. return FALSE;
  729. }
  730. #if __MINGW32__
  731. // We turned these warnings off for this file so that MinGW-g++ doesn't
  732. // complain about the ll format specifiers used. Now we are turning the
  733. // warnings back on. If MinGW starts to support diagnostic stacks, we can
  734. // replace this with a pop.
  735. #pragma GCC diagnostic warning "-Wformat"
  736. #pragma GCC diagnostic warning "-Wformat-extra-args"
  737. #endif
  738. void sys::unregisterHandlers() {}