From 7cd1c01c8e855704ffa963778e51e8cd3030c6bf Mon Sep 17 00:00:00 2001 From: Ben Dunbobbin Date: Mon, 20 Jun 2022 11:43:38 +0100 Subject: [PATCH] [windows][support] Improve backtrace emitted in crash report without llvm-symbolizer Currently the backtrace emitted on windows when llvm-symbolizer is not available includes addresses which cannot be easily decoded because the addresses have the containing module's run-time base address added into them, but we don't know what those base addresses are. This change emits a module offset rather than an address. There are a couple of related changes which were included as a result of the review discussion for this patch: - I have also removed the parameter printing as it adds noise to the dump and doesn't seem useful. - I have added the exception code to the backtrace. Differential Review: https://reviews.llvm.org/D127915 --- llvm/lib/Support/Windows/Signals.inc | 42 +++++++++++++++++++----------------- 1 file changed, 22 insertions(+), 20 deletions(-) diff --git a/llvm/lib/Support/Windows/Signals.inc b/llvm/lib/Support/Windows/Signals.inc index fab3886..32477de 100644 --- a/llvm/lib/Support/Windows/Signals.inc +++ b/llvm/lib/Support/Windows/Signals.inc @@ -337,24 +337,24 @@ static void PrintStackTraceForThread(llvm::raw_ostream &OS, HANDLE hProcess, OS << format("0x%08lX", static_cast(PC)); #endif -// Print the parameters. Assume there are four. -#if defined(_M_X64) || defined(_M_ARM64) - OS << format(" (0x%016llX 0x%016llX 0x%016llX 0x%016llX)", - StackFrame.Params[0], StackFrame.Params[1], StackFrame.Params[2], - StackFrame.Params[3]); -#elif defined(_M_IX86) || defined(_M_ARM) - OS << format(" (0x%08lX 0x%08lX 0x%08lX 0x%08lX)", - static_cast(StackFrame.Params[0]), - static_cast(StackFrame.Params[1]), - static_cast(StackFrame.Params[2]), - static_cast(StackFrame.Params[3])); -#endif // Verify the PC belongs to a module in this process. if (!fSymGetModuleBase64(hProcess, PC)) { OS << " \n"; continue; } + IMAGEHLP_MODULE64 M; + memset(&M, 0, sizeof(IMAGEHLP_MODULE64)); + M.SizeOfStruct = sizeof(IMAGEHLP_MODULE64); + if (fSymGetModuleInfo64(hProcess, fSymGetModuleBase64(hProcess, PC), &M)) { + DWORD64 const disp = PC - M.BaseOfImage; + OS << format(", %s(0x%016llX) + 0x%llX byte(s)", + static_cast(M.ImageName), M.BaseOfImage, + static_cast(disp)); + } else { + OS << ", "; + } + // Print the symbol name. char buffer[512]; IMAGEHLP_SYMBOL64 *symbol = reinterpret_cast(buffer); @@ -369,20 +369,16 @@ static void PrintStackTraceForThread(llvm::raw_ostream &OS, HANDLE hProcess, } buffer[511] = 0; - if (dwDisp > 0) - OS << format(", %s() + 0x%llX bytes(s)", (const char*)symbol->Name, - dwDisp); - else - OS << format(", %s", (const char*)symbol->Name); + OS << format(", %s() + 0x%llX byte(s)", static_cast(symbol->Name), + static_cast(dwDisp)); // Print the source file and line number information. IMAGEHLP_LINE64 line = {}; DWORD dwLineDisp; line.SizeOfStruct = sizeof(line); if (fSymGetLineFromAddr64(hProcess, PC, &dwLineDisp, &line)) { - OS << format(", %s, line %lu", line.FileName, line.LineNumber); - if (dwLineDisp > 0) - OS << format(" + 0x%lX byte(s)", dwLineDisp); + OS << format(", %s, line %lu + 0x%lX byte(s)", line.FileName, + line.LineNumber, dwLineDisp); } OS << '\n'; @@ -821,6 +817,12 @@ void sys::CleanupOnSignal(uintptr_t Context) { static LONG WINAPI LLVMUnhandledExceptionFilter(LPEXCEPTION_POINTERS ep) { Cleanup(true); + // Write out the exception code. + if (ep && ep->ExceptionRecord) + llvm::errs() << format("Exception Code: 0x%08X", + ep->ExceptionRecord->ExceptionCode) + << "\n"; + // We'll automatically write a Minidump file here to help diagnose // the nasty sorts of crashes that aren't 100% reproducible from a set of // inputs (or in the event that the user is unable or unwilling to provide a -- 2.7.4