1*0b57cec5SDimitry Andric //===- PrettyStackTrace.cpp - Pretty Crash Handling -----------------------===// 2*0b57cec5SDimitry Andric // 3*0b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*0b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*0b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*0b57cec5SDimitry Andric // 7*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 8*0b57cec5SDimitry Andric // 9*0b57cec5SDimitry Andric // This file defines some helpful functions for dealing with the possibility of 10*0b57cec5SDimitry Andric // Unix signals occurring while your program is running. 11*0b57cec5SDimitry Andric // 12*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 13*0b57cec5SDimitry Andric 14*0b57cec5SDimitry Andric #include "llvm/Support/PrettyStackTrace.h" 15*0b57cec5SDimitry Andric #include "llvm-c/ErrorHandling.h" 16*0b57cec5SDimitry Andric #include "llvm/ADT/SmallString.h" 17*0b57cec5SDimitry Andric #include "llvm/Config/config.h" 18*0b57cec5SDimitry Andric #include "llvm/Support/Compiler.h" 19*0b57cec5SDimitry Andric #include "llvm/Support/SaveAndRestore.h" 20*0b57cec5SDimitry Andric #include "llvm/Support/Signals.h" 21*0b57cec5SDimitry Andric #include "llvm/Support/Watchdog.h" 22*0b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h" 23*0b57cec5SDimitry Andric 24*0b57cec5SDimitry Andric #include <atomic> 255ffd83dbSDimitry Andric #include <cassert> 26*0b57cec5SDimitry Andric #include <cstdarg> 27*0b57cec5SDimitry Andric #include <cstdio> 28*0b57cec5SDimitry Andric #include <tuple> 29*0b57cec5SDimitry Andric 30*0b57cec5SDimitry Andric #ifdef HAVE_CRASHREPORTERCLIENT_H 31*0b57cec5SDimitry Andric #include <CrashReporterClient.h> 32*0b57cec5SDimitry Andric #endif 33*0b57cec5SDimitry Andric 34*0b57cec5SDimitry Andric using namespace llvm; 35*0b57cec5SDimitry Andric 365ffd83dbSDimitry Andric static const char *BugReportMsg = 375ffd83dbSDimitry Andric "PLEASE submit a bug report to " BUG_REPORT_URL 385ffd83dbSDimitry Andric " and include the crash backtrace.\n"; 395ffd83dbSDimitry Andric 40*0b57cec5SDimitry Andric // If backtrace support is not enabled, compile out support for pretty stack 41*0b57cec5SDimitry Andric // traces. This has the secondary effect of not requiring thread local storage 42*0b57cec5SDimitry Andric // when backtrace support is disabled. 43*0b57cec5SDimitry Andric #if ENABLE_BACKTRACES 44*0b57cec5SDimitry Andric 45*0b57cec5SDimitry Andric // We need a thread local pointer to manage the stack of our stack trace 46*0b57cec5SDimitry Andric // objects, but we *really* cannot tolerate destructors running and do not want 47*0b57cec5SDimitry Andric // to pay any overhead of synchronizing. As a consequence, we use a raw 48*0b57cec5SDimitry Andric // thread-local variable. 49*0b57cec5SDimitry Andric static LLVM_THREAD_LOCAL PrettyStackTraceEntry *PrettyStackTraceHead = nullptr; 50*0b57cec5SDimitry Andric 51*0b57cec5SDimitry Andric // The use of 'volatile' here is to ensure that any particular thread always 52*0b57cec5SDimitry Andric // reloads the value of the counter. The 'std::atomic' allows us to specify that 53*0b57cec5SDimitry Andric // this variable is accessed in an unsychronized way (it's not actually 54*0b57cec5SDimitry Andric // synchronizing). This does technically mean that the value may not appear to 55*0b57cec5SDimitry Andric // be the same across threads running simultaneously on different CPUs, but in 56*0b57cec5SDimitry Andric // practice the worst that will happen is that we won't print a stack trace when 57*0b57cec5SDimitry Andric // we could have. 58*0b57cec5SDimitry Andric // 59*0b57cec5SDimitry Andric // This is initialized to 1 because 0 is used as a sentinel for "not enabled on 60*0b57cec5SDimitry Andric // the current thread". If the user happens to overflow an 'unsigned' with 61*0b57cec5SDimitry Andric // SIGINFO requests, it's possible that some threads will stop responding to it, 62*0b57cec5SDimitry Andric // but the program won't crash. 63*0b57cec5SDimitry Andric static volatile std::atomic<unsigned> GlobalSigInfoGenerationCounter = 64*0b57cec5SDimitry Andric ATOMIC_VAR_INIT(1); 65*0b57cec5SDimitry Andric static LLVM_THREAD_LOCAL unsigned ThreadLocalSigInfoGenerationCounter = 0; 66*0b57cec5SDimitry Andric 67*0b57cec5SDimitry Andric namespace llvm { 68*0b57cec5SDimitry Andric PrettyStackTraceEntry *ReverseStackTrace(PrettyStackTraceEntry *Head) { 69*0b57cec5SDimitry Andric PrettyStackTraceEntry *Prev = nullptr; 70*0b57cec5SDimitry Andric while (Head) 71*0b57cec5SDimitry Andric std::tie(Prev, Head, Head->NextEntry) = 72*0b57cec5SDimitry Andric std::make_tuple(Head, Head->NextEntry, Prev); 73*0b57cec5SDimitry Andric return Prev; 74*0b57cec5SDimitry Andric } 75*0b57cec5SDimitry Andric } 76*0b57cec5SDimitry Andric 77*0b57cec5SDimitry Andric static void PrintStack(raw_ostream &OS) { 78*0b57cec5SDimitry Andric // Print out the stack in reverse order. To avoid recursion (which is likely 79*0b57cec5SDimitry Andric // to fail if we crashed due to stack overflow), we do an up-front pass to 80*0b57cec5SDimitry Andric // reverse the stack, then print it, then reverse it again. 81*0b57cec5SDimitry Andric unsigned ID = 0; 82*0b57cec5SDimitry Andric SaveAndRestore<PrettyStackTraceEntry *> SavedStack{PrettyStackTraceHead, 83*0b57cec5SDimitry Andric nullptr}; 84*0b57cec5SDimitry Andric PrettyStackTraceEntry *ReversedStack = ReverseStackTrace(SavedStack.get()); 85*0b57cec5SDimitry Andric for (const PrettyStackTraceEntry *Entry = ReversedStack; Entry; 86*0b57cec5SDimitry Andric Entry = Entry->getNextEntry()) { 87*0b57cec5SDimitry Andric OS << ID++ << ".\t"; 88*0b57cec5SDimitry Andric sys::Watchdog W(5); 89*0b57cec5SDimitry Andric Entry->print(OS); 90*0b57cec5SDimitry Andric } 91*0b57cec5SDimitry Andric llvm::ReverseStackTrace(ReversedStack); 92*0b57cec5SDimitry Andric } 93*0b57cec5SDimitry Andric 94*0b57cec5SDimitry Andric /// Print the current stack trace to the specified stream. 95*0b57cec5SDimitry Andric /// 96*0b57cec5SDimitry Andric /// Marked NOINLINE so it can be called from debuggers. 97*0b57cec5SDimitry Andric LLVM_ATTRIBUTE_NOINLINE 98*0b57cec5SDimitry Andric static void PrintCurStackTrace(raw_ostream &OS) { 99*0b57cec5SDimitry Andric // Don't print an empty trace. 100*0b57cec5SDimitry Andric if (!PrettyStackTraceHead) return; 101*0b57cec5SDimitry Andric 102*0b57cec5SDimitry Andric // If there are pretty stack frames registered, walk and emit them. 103*0b57cec5SDimitry Andric OS << "Stack dump:\n"; 104*0b57cec5SDimitry Andric 105*0b57cec5SDimitry Andric PrintStack(OS); 106*0b57cec5SDimitry Andric OS.flush(); 107*0b57cec5SDimitry Andric } 108*0b57cec5SDimitry Andric 109*0b57cec5SDimitry Andric // Integrate with crash reporter libraries. 110*0b57cec5SDimitry Andric #if defined (__APPLE__) && defined(HAVE_CRASHREPORTERCLIENT_H) 111*0b57cec5SDimitry Andric // If any clients of llvm try to link to libCrashReporterClient.a themselves, 112*0b57cec5SDimitry Andric // only one crash info struct will be used. 113*0b57cec5SDimitry Andric extern "C" { 114*0b57cec5SDimitry Andric CRASH_REPORTER_CLIENT_HIDDEN 115*0b57cec5SDimitry Andric struct crashreporter_annotations_t gCRAnnotations 116*0b57cec5SDimitry Andric __attribute__((section("__DATA," CRASHREPORTER_ANNOTATIONS_SECTION))) 117*0b57cec5SDimitry Andric #if CRASHREPORTER_ANNOTATIONS_VERSION < 5 118*0b57cec5SDimitry Andric = { CRASHREPORTER_ANNOTATIONS_VERSION, 0, 0, 0, 0, 0, 0 }; 119*0b57cec5SDimitry Andric #else 120*0b57cec5SDimitry Andric = { CRASHREPORTER_ANNOTATIONS_VERSION, 0, 0, 0, 0, 0, 0, 0 }; 121*0b57cec5SDimitry Andric #endif 122*0b57cec5SDimitry Andric } 123*0b57cec5SDimitry Andric #elif defined(__APPLE__) && HAVE_CRASHREPORTER_INFO 124*0b57cec5SDimitry Andric extern "C" const char *__crashreporter_info__ 125*0b57cec5SDimitry Andric __attribute__((visibility("hidden"))) = 0; 126*0b57cec5SDimitry Andric asm(".desc ___crashreporter_info__, 0x10"); 127*0b57cec5SDimitry Andric #endif 128*0b57cec5SDimitry Andric 1298bcb0991SDimitry Andric static void setCrashLogMessage(const char *msg) LLVM_ATTRIBUTE_UNUSED; 1308bcb0991SDimitry Andric static void setCrashLogMessage(const char *msg) { 1318bcb0991SDimitry Andric #ifdef HAVE_CRASHREPORTERCLIENT_H 1328bcb0991SDimitry Andric (void)CRSetCrashLogMessage(msg); 1338bcb0991SDimitry Andric #elif HAVE_CRASHREPORTER_INFO 1348bcb0991SDimitry Andric __crashreporter_info__ = msg; 1358bcb0991SDimitry Andric #endif 1368bcb0991SDimitry Andric // Don't reorder subsequent operations: whatever comes after might crash and 1378bcb0991SDimitry Andric // we want the system crash handling to see the message we just set. 1388bcb0991SDimitry Andric std::atomic_signal_fence(std::memory_order_seq_cst); 1398bcb0991SDimitry Andric } 1408bcb0991SDimitry Andric 1418bcb0991SDimitry Andric #ifdef __APPLE__ 1428bcb0991SDimitry Andric using CrashHandlerString = SmallString<2048>; 1438bcb0991SDimitry Andric using CrashHandlerStringStorage = 1448bcb0991SDimitry Andric std::aligned_storage<sizeof(CrashHandlerString), 1458bcb0991SDimitry Andric alignof(CrashHandlerString)>::type; 1468bcb0991SDimitry Andric static CrashHandlerStringStorage crashHandlerStringStorage; 1478bcb0991SDimitry Andric #endif 1488bcb0991SDimitry Andric 1498bcb0991SDimitry Andric /// This callback is run if a fatal signal is delivered to the process, it 1508bcb0991SDimitry Andric /// prints the pretty stack trace. 151*0b57cec5SDimitry Andric static void CrashHandler(void *) { 1525ffd83dbSDimitry Andric errs() << BugReportMsg ; 1535ffd83dbSDimitry Andric 154*0b57cec5SDimitry Andric #ifndef __APPLE__ 155*0b57cec5SDimitry Andric // On non-apple systems, just emit the crash stack trace to stderr. 156*0b57cec5SDimitry Andric PrintCurStackTrace(errs()); 157*0b57cec5SDimitry Andric #else 1588bcb0991SDimitry Andric // Emit the crash stack trace to a SmallString, put it where the system crash 1598bcb0991SDimitry Andric // handling will find it, and also send it to stderr. 1608bcb0991SDimitry Andric // 1618bcb0991SDimitry Andric // The SmallString is fairly large in the hope that we don't allocate (we're 1628bcb0991SDimitry Andric // handling a fatal signal, something is already pretty wrong, allocation 1638bcb0991SDimitry Andric // might not work). Further, we don't use a magic static in case that's also 1648bcb0991SDimitry Andric // borked. We leak any allocation that does occur because the program is about 1658bcb0991SDimitry Andric // to die anyways. This is technically racy if we were handling two fatal 1668bcb0991SDimitry Andric // signals, however if we're in that situation a race is the least of our 1678bcb0991SDimitry Andric // worries. 1688bcb0991SDimitry Andric auto &crashHandlerString = 1698bcb0991SDimitry Andric *new (&crashHandlerStringStorage) CrashHandlerString; 1708bcb0991SDimitry Andric 1718bcb0991SDimitry Andric // If we crash while trying to print the stack trace, we still want the system 1728bcb0991SDimitry Andric // crash handling to have some partial information. That'll work out as long 1738bcb0991SDimitry Andric // as the SmallString doesn't allocate. If it does allocate then the system 1748bcb0991SDimitry Andric // crash handling will see some garbage because the inline buffer now contains 1758bcb0991SDimitry Andric // a pointer. 1768bcb0991SDimitry Andric setCrashLogMessage(crashHandlerString.c_str()); 1778bcb0991SDimitry Andric 178*0b57cec5SDimitry Andric { 1798bcb0991SDimitry Andric raw_svector_ostream Stream(crashHandlerString); 180*0b57cec5SDimitry Andric PrintCurStackTrace(Stream); 181*0b57cec5SDimitry Andric } 182*0b57cec5SDimitry Andric 1838bcb0991SDimitry Andric if (!crashHandlerString.empty()) { 1848bcb0991SDimitry Andric setCrashLogMessage(crashHandlerString.c_str()); 1858bcb0991SDimitry Andric errs() << crashHandlerString.str(); 1868bcb0991SDimitry Andric } else 1878bcb0991SDimitry Andric setCrashLogMessage("No crash information."); 188*0b57cec5SDimitry Andric #endif 189*0b57cec5SDimitry Andric } 190*0b57cec5SDimitry Andric 191*0b57cec5SDimitry Andric static void printForSigInfoIfNeeded() { 192*0b57cec5SDimitry Andric unsigned CurrentSigInfoGeneration = 193*0b57cec5SDimitry Andric GlobalSigInfoGenerationCounter.load(std::memory_order_relaxed); 194*0b57cec5SDimitry Andric if (ThreadLocalSigInfoGenerationCounter == 0 || 195*0b57cec5SDimitry Andric ThreadLocalSigInfoGenerationCounter == CurrentSigInfoGeneration) { 196*0b57cec5SDimitry Andric return; 197*0b57cec5SDimitry Andric } 198*0b57cec5SDimitry Andric 199*0b57cec5SDimitry Andric PrintCurStackTrace(errs()); 200*0b57cec5SDimitry Andric ThreadLocalSigInfoGenerationCounter = CurrentSigInfoGeneration; 201*0b57cec5SDimitry Andric } 202*0b57cec5SDimitry Andric 203*0b57cec5SDimitry Andric #endif // ENABLE_BACKTRACES 204*0b57cec5SDimitry Andric 2055ffd83dbSDimitry Andric void llvm::setBugReportMsg(const char *Msg) { 2065ffd83dbSDimitry Andric BugReportMsg = Msg; 2075ffd83dbSDimitry Andric } 2085ffd83dbSDimitry Andric 2095ffd83dbSDimitry Andric const char *llvm::getBugReportMsg() { 2105ffd83dbSDimitry Andric return BugReportMsg; 2115ffd83dbSDimitry Andric } 2125ffd83dbSDimitry Andric 213*0b57cec5SDimitry Andric PrettyStackTraceEntry::PrettyStackTraceEntry() { 214*0b57cec5SDimitry Andric #if ENABLE_BACKTRACES 215*0b57cec5SDimitry Andric // Handle SIGINFO first, because we haven't finished constructing yet. 216*0b57cec5SDimitry Andric printForSigInfoIfNeeded(); 217*0b57cec5SDimitry Andric // Link ourselves. 218*0b57cec5SDimitry Andric NextEntry = PrettyStackTraceHead; 219*0b57cec5SDimitry Andric PrettyStackTraceHead = this; 220*0b57cec5SDimitry Andric #endif 221*0b57cec5SDimitry Andric } 222*0b57cec5SDimitry Andric 223*0b57cec5SDimitry Andric PrettyStackTraceEntry::~PrettyStackTraceEntry() { 224*0b57cec5SDimitry Andric #if ENABLE_BACKTRACES 225*0b57cec5SDimitry Andric assert(PrettyStackTraceHead == this && 226*0b57cec5SDimitry Andric "Pretty stack trace entry destruction is out of order"); 227*0b57cec5SDimitry Andric PrettyStackTraceHead = NextEntry; 228*0b57cec5SDimitry Andric // Handle SIGINFO first, because we already started destructing. 229*0b57cec5SDimitry Andric printForSigInfoIfNeeded(); 230*0b57cec5SDimitry Andric #endif 231*0b57cec5SDimitry Andric } 232*0b57cec5SDimitry Andric 233*0b57cec5SDimitry Andric void PrettyStackTraceString::print(raw_ostream &OS) const { OS << Str << "\n"; } 234*0b57cec5SDimitry Andric 235*0b57cec5SDimitry Andric PrettyStackTraceFormat::PrettyStackTraceFormat(const char *Format, ...) { 236*0b57cec5SDimitry Andric va_list AP; 237*0b57cec5SDimitry Andric va_start(AP, Format); 238*0b57cec5SDimitry Andric const int SizeOrError = vsnprintf(nullptr, 0, Format, AP); 239*0b57cec5SDimitry Andric va_end(AP); 240*0b57cec5SDimitry Andric if (SizeOrError < 0) { 241*0b57cec5SDimitry Andric return; 242*0b57cec5SDimitry Andric } 243*0b57cec5SDimitry Andric 244*0b57cec5SDimitry Andric const int Size = SizeOrError + 1; // '\0' 245*0b57cec5SDimitry Andric Str.resize(Size); 246*0b57cec5SDimitry Andric va_start(AP, Format); 247*0b57cec5SDimitry Andric vsnprintf(Str.data(), Size, Format, AP); 248*0b57cec5SDimitry Andric va_end(AP); 249*0b57cec5SDimitry Andric } 250*0b57cec5SDimitry Andric 251*0b57cec5SDimitry Andric void PrettyStackTraceFormat::print(raw_ostream &OS) const { OS << Str << "\n"; } 252*0b57cec5SDimitry Andric 253*0b57cec5SDimitry Andric void PrettyStackTraceProgram::print(raw_ostream &OS) const { 254*0b57cec5SDimitry Andric OS << "Program arguments: "; 255*0b57cec5SDimitry Andric // Print the argument list. 256*0b57cec5SDimitry Andric for (unsigned i = 0, e = ArgC; i != e; ++i) 257*0b57cec5SDimitry Andric OS << ArgV[i] << ' '; 258*0b57cec5SDimitry Andric OS << '\n'; 259*0b57cec5SDimitry Andric } 260*0b57cec5SDimitry Andric 261*0b57cec5SDimitry Andric #if ENABLE_BACKTRACES 262*0b57cec5SDimitry Andric static bool RegisterCrashPrinter() { 263*0b57cec5SDimitry Andric sys::AddSignalHandler(CrashHandler, nullptr); 264*0b57cec5SDimitry Andric return false; 265*0b57cec5SDimitry Andric } 266*0b57cec5SDimitry Andric #endif 267*0b57cec5SDimitry Andric 268*0b57cec5SDimitry Andric void llvm::EnablePrettyStackTrace() { 269*0b57cec5SDimitry Andric #if ENABLE_BACKTRACES 270*0b57cec5SDimitry Andric // The first time this is called, we register the crash printer. 271*0b57cec5SDimitry Andric static bool HandlerRegistered = RegisterCrashPrinter(); 272*0b57cec5SDimitry Andric (void)HandlerRegistered; 273*0b57cec5SDimitry Andric #endif 274*0b57cec5SDimitry Andric } 275*0b57cec5SDimitry Andric 276*0b57cec5SDimitry Andric void llvm::EnablePrettyStackTraceOnSigInfoForThisThread(bool ShouldEnable) { 277*0b57cec5SDimitry Andric #if ENABLE_BACKTRACES 278*0b57cec5SDimitry Andric if (!ShouldEnable) { 279*0b57cec5SDimitry Andric ThreadLocalSigInfoGenerationCounter = 0; 280*0b57cec5SDimitry Andric return; 281*0b57cec5SDimitry Andric } 282*0b57cec5SDimitry Andric 283*0b57cec5SDimitry Andric // The first time this is called, we register the SIGINFO handler. 284*0b57cec5SDimitry Andric static bool HandlerRegistered = []{ 285*0b57cec5SDimitry Andric sys::SetInfoSignalFunction([]{ 286*0b57cec5SDimitry Andric GlobalSigInfoGenerationCounter.fetch_add(1, std::memory_order_relaxed); 287*0b57cec5SDimitry Andric }); 288*0b57cec5SDimitry Andric return false; 289*0b57cec5SDimitry Andric }(); 290*0b57cec5SDimitry Andric (void)HandlerRegistered; 291*0b57cec5SDimitry Andric 292*0b57cec5SDimitry Andric // Next, enable it for the current thread. 293*0b57cec5SDimitry Andric ThreadLocalSigInfoGenerationCounter = 294*0b57cec5SDimitry Andric GlobalSigInfoGenerationCounter.load(std::memory_order_relaxed); 295*0b57cec5SDimitry Andric #endif 296*0b57cec5SDimitry Andric } 297*0b57cec5SDimitry Andric 298*0b57cec5SDimitry Andric const void *llvm::SavePrettyStackState() { 299*0b57cec5SDimitry Andric #if ENABLE_BACKTRACES 300*0b57cec5SDimitry Andric return PrettyStackTraceHead; 301*0b57cec5SDimitry Andric #else 302*0b57cec5SDimitry Andric return nullptr; 303*0b57cec5SDimitry Andric #endif 304*0b57cec5SDimitry Andric } 305*0b57cec5SDimitry Andric 306*0b57cec5SDimitry Andric void llvm::RestorePrettyStackState(const void *Top) { 307*0b57cec5SDimitry Andric #if ENABLE_BACKTRACES 308*0b57cec5SDimitry Andric PrettyStackTraceHead = 309*0b57cec5SDimitry Andric static_cast<PrettyStackTraceEntry *>(const_cast<void *>(Top)); 310*0b57cec5SDimitry Andric #endif 311*0b57cec5SDimitry Andric } 312*0b57cec5SDimitry Andric 313*0b57cec5SDimitry Andric void LLVMEnablePrettyStackTrace() { 314*0b57cec5SDimitry Andric EnablePrettyStackTrace(); 315*0b57cec5SDimitry Andric } 316