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> 25*0b57cec5SDimitry Andric #include <cstdarg> 26*0b57cec5SDimitry Andric #include <cstdio> 27*0b57cec5SDimitry Andric #include <tuple> 28*0b57cec5SDimitry Andric 29*0b57cec5SDimitry Andric #ifdef HAVE_CRASHREPORTERCLIENT_H 30*0b57cec5SDimitry Andric #include <CrashReporterClient.h> 31*0b57cec5SDimitry Andric #endif 32*0b57cec5SDimitry Andric 33*0b57cec5SDimitry Andric using namespace llvm; 34*0b57cec5SDimitry Andric 35*0b57cec5SDimitry Andric // If backtrace support is not enabled, compile out support for pretty stack 36*0b57cec5SDimitry Andric // traces. This has the secondary effect of not requiring thread local storage 37*0b57cec5SDimitry Andric // when backtrace support is disabled. 38*0b57cec5SDimitry Andric #if ENABLE_BACKTRACES 39*0b57cec5SDimitry Andric 40*0b57cec5SDimitry Andric // We need a thread local pointer to manage the stack of our stack trace 41*0b57cec5SDimitry Andric // objects, but we *really* cannot tolerate destructors running and do not want 42*0b57cec5SDimitry Andric // to pay any overhead of synchronizing. As a consequence, we use a raw 43*0b57cec5SDimitry Andric // thread-local variable. 44*0b57cec5SDimitry Andric static LLVM_THREAD_LOCAL PrettyStackTraceEntry *PrettyStackTraceHead = nullptr; 45*0b57cec5SDimitry Andric 46*0b57cec5SDimitry Andric // The use of 'volatile' here is to ensure that any particular thread always 47*0b57cec5SDimitry Andric // reloads the value of the counter. The 'std::atomic' allows us to specify that 48*0b57cec5SDimitry Andric // this variable is accessed in an unsychronized way (it's not actually 49*0b57cec5SDimitry Andric // synchronizing). This does technically mean that the value may not appear to 50*0b57cec5SDimitry Andric // be the same across threads running simultaneously on different CPUs, but in 51*0b57cec5SDimitry Andric // practice the worst that will happen is that we won't print a stack trace when 52*0b57cec5SDimitry Andric // we could have. 53*0b57cec5SDimitry Andric // 54*0b57cec5SDimitry Andric // This is initialized to 1 because 0 is used as a sentinel for "not enabled on 55*0b57cec5SDimitry Andric // the current thread". If the user happens to overflow an 'unsigned' with 56*0b57cec5SDimitry Andric // SIGINFO requests, it's possible that some threads will stop responding to it, 57*0b57cec5SDimitry Andric // but the program won't crash. 58*0b57cec5SDimitry Andric static volatile std::atomic<unsigned> GlobalSigInfoGenerationCounter = 59*0b57cec5SDimitry Andric ATOMIC_VAR_INIT(1); 60*0b57cec5SDimitry Andric static LLVM_THREAD_LOCAL unsigned ThreadLocalSigInfoGenerationCounter = 0; 61*0b57cec5SDimitry Andric 62*0b57cec5SDimitry Andric namespace llvm { 63*0b57cec5SDimitry Andric PrettyStackTraceEntry *ReverseStackTrace(PrettyStackTraceEntry *Head) { 64*0b57cec5SDimitry Andric PrettyStackTraceEntry *Prev = nullptr; 65*0b57cec5SDimitry Andric while (Head) 66*0b57cec5SDimitry Andric std::tie(Prev, Head, Head->NextEntry) = 67*0b57cec5SDimitry Andric std::make_tuple(Head, Head->NextEntry, Prev); 68*0b57cec5SDimitry Andric return Prev; 69*0b57cec5SDimitry Andric } 70*0b57cec5SDimitry Andric } 71*0b57cec5SDimitry Andric 72*0b57cec5SDimitry Andric static void PrintStack(raw_ostream &OS) { 73*0b57cec5SDimitry Andric // Print out the stack in reverse order. To avoid recursion (which is likely 74*0b57cec5SDimitry Andric // to fail if we crashed due to stack overflow), we do an up-front pass to 75*0b57cec5SDimitry Andric // reverse the stack, then print it, then reverse it again. 76*0b57cec5SDimitry Andric unsigned ID = 0; 77*0b57cec5SDimitry Andric SaveAndRestore<PrettyStackTraceEntry *> SavedStack{PrettyStackTraceHead, 78*0b57cec5SDimitry Andric nullptr}; 79*0b57cec5SDimitry Andric PrettyStackTraceEntry *ReversedStack = ReverseStackTrace(SavedStack.get()); 80*0b57cec5SDimitry Andric for (const PrettyStackTraceEntry *Entry = ReversedStack; Entry; 81*0b57cec5SDimitry Andric Entry = Entry->getNextEntry()) { 82*0b57cec5SDimitry Andric OS << ID++ << ".\t"; 83*0b57cec5SDimitry Andric sys::Watchdog W(5); 84*0b57cec5SDimitry Andric Entry->print(OS); 85*0b57cec5SDimitry Andric } 86*0b57cec5SDimitry Andric llvm::ReverseStackTrace(ReversedStack); 87*0b57cec5SDimitry Andric } 88*0b57cec5SDimitry Andric 89*0b57cec5SDimitry Andric /// Print the current stack trace to the specified stream. 90*0b57cec5SDimitry Andric /// 91*0b57cec5SDimitry Andric /// Marked NOINLINE so it can be called from debuggers. 92*0b57cec5SDimitry Andric LLVM_ATTRIBUTE_NOINLINE 93*0b57cec5SDimitry Andric static void PrintCurStackTrace(raw_ostream &OS) { 94*0b57cec5SDimitry Andric // Don't print an empty trace. 95*0b57cec5SDimitry Andric if (!PrettyStackTraceHead) return; 96*0b57cec5SDimitry Andric 97*0b57cec5SDimitry Andric // If there are pretty stack frames registered, walk and emit them. 98*0b57cec5SDimitry Andric OS << "Stack dump:\n"; 99*0b57cec5SDimitry Andric 100*0b57cec5SDimitry Andric PrintStack(OS); 101*0b57cec5SDimitry Andric OS.flush(); 102*0b57cec5SDimitry Andric } 103*0b57cec5SDimitry Andric 104*0b57cec5SDimitry Andric // Integrate with crash reporter libraries. 105*0b57cec5SDimitry Andric #if defined (__APPLE__) && defined(HAVE_CRASHREPORTERCLIENT_H) 106*0b57cec5SDimitry Andric // If any clients of llvm try to link to libCrashReporterClient.a themselves, 107*0b57cec5SDimitry Andric // only one crash info struct will be used. 108*0b57cec5SDimitry Andric extern "C" { 109*0b57cec5SDimitry Andric CRASH_REPORTER_CLIENT_HIDDEN 110*0b57cec5SDimitry Andric struct crashreporter_annotations_t gCRAnnotations 111*0b57cec5SDimitry Andric __attribute__((section("__DATA," CRASHREPORTER_ANNOTATIONS_SECTION))) 112*0b57cec5SDimitry Andric #if CRASHREPORTER_ANNOTATIONS_VERSION < 5 113*0b57cec5SDimitry Andric = { CRASHREPORTER_ANNOTATIONS_VERSION, 0, 0, 0, 0, 0, 0 }; 114*0b57cec5SDimitry Andric #else 115*0b57cec5SDimitry Andric = { CRASHREPORTER_ANNOTATIONS_VERSION, 0, 0, 0, 0, 0, 0, 0 }; 116*0b57cec5SDimitry Andric #endif 117*0b57cec5SDimitry Andric } 118*0b57cec5SDimitry Andric #elif defined(__APPLE__) && HAVE_CRASHREPORTER_INFO 119*0b57cec5SDimitry Andric extern "C" const char *__crashreporter_info__ 120*0b57cec5SDimitry Andric __attribute__((visibility("hidden"))) = 0; 121*0b57cec5SDimitry Andric asm(".desc ___crashreporter_info__, 0x10"); 122*0b57cec5SDimitry Andric #endif 123*0b57cec5SDimitry Andric 1248bcb0991SDimitry Andric static void setCrashLogMessage(const char *msg) LLVM_ATTRIBUTE_UNUSED; 1258bcb0991SDimitry Andric static void setCrashLogMessage(const char *msg) { 1268bcb0991SDimitry Andric #ifdef HAVE_CRASHREPORTERCLIENT_H 1278bcb0991SDimitry Andric (void)CRSetCrashLogMessage(msg); 1288bcb0991SDimitry Andric #elif HAVE_CRASHREPORTER_INFO 1298bcb0991SDimitry Andric __crashreporter_info__ = msg; 1308bcb0991SDimitry Andric #endif 1318bcb0991SDimitry Andric // Don't reorder subsequent operations: whatever comes after might crash and 1328bcb0991SDimitry Andric // we want the system crash handling to see the message we just set. 1338bcb0991SDimitry Andric std::atomic_signal_fence(std::memory_order_seq_cst); 1348bcb0991SDimitry Andric } 1358bcb0991SDimitry Andric 1368bcb0991SDimitry Andric #ifdef __APPLE__ 1378bcb0991SDimitry Andric using CrashHandlerString = SmallString<2048>; 1388bcb0991SDimitry Andric using CrashHandlerStringStorage = 1398bcb0991SDimitry Andric std::aligned_storage<sizeof(CrashHandlerString), 1408bcb0991SDimitry Andric alignof(CrashHandlerString)>::type; 1418bcb0991SDimitry Andric static CrashHandlerStringStorage crashHandlerStringStorage; 1428bcb0991SDimitry Andric #endif 1438bcb0991SDimitry Andric 1448bcb0991SDimitry Andric /// This callback is run if a fatal signal is delivered to the process, it 1458bcb0991SDimitry Andric /// prints the pretty stack trace. 146*0b57cec5SDimitry Andric static void CrashHandler(void *) { 147*0b57cec5SDimitry Andric #ifndef __APPLE__ 148*0b57cec5SDimitry Andric // On non-apple systems, just emit the crash stack trace to stderr. 149*0b57cec5SDimitry Andric PrintCurStackTrace(errs()); 150*0b57cec5SDimitry Andric #else 1518bcb0991SDimitry Andric // Emit the crash stack trace to a SmallString, put it where the system crash 1528bcb0991SDimitry Andric // handling will find it, and also send it to stderr. 1538bcb0991SDimitry Andric // 1548bcb0991SDimitry Andric // The SmallString is fairly large in the hope that we don't allocate (we're 1558bcb0991SDimitry Andric // handling a fatal signal, something is already pretty wrong, allocation 1568bcb0991SDimitry Andric // might not work). Further, we don't use a magic static in case that's also 1578bcb0991SDimitry Andric // borked. We leak any allocation that does occur because the program is about 1588bcb0991SDimitry Andric // to die anyways. This is technically racy if we were handling two fatal 1598bcb0991SDimitry Andric // signals, however if we're in that situation a race is the least of our 1608bcb0991SDimitry Andric // worries. 1618bcb0991SDimitry Andric auto &crashHandlerString = 1628bcb0991SDimitry Andric *new (&crashHandlerStringStorage) CrashHandlerString; 1638bcb0991SDimitry Andric 1648bcb0991SDimitry Andric // If we crash while trying to print the stack trace, we still want the system 1658bcb0991SDimitry Andric // crash handling to have some partial information. That'll work out as long 1668bcb0991SDimitry Andric // as the SmallString doesn't allocate. If it does allocate then the system 1678bcb0991SDimitry Andric // crash handling will see some garbage because the inline buffer now contains 1688bcb0991SDimitry Andric // a pointer. 1698bcb0991SDimitry Andric setCrashLogMessage(crashHandlerString.c_str()); 1708bcb0991SDimitry Andric 171*0b57cec5SDimitry Andric { 1728bcb0991SDimitry Andric raw_svector_ostream Stream(crashHandlerString); 173*0b57cec5SDimitry Andric PrintCurStackTrace(Stream); 174*0b57cec5SDimitry Andric } 175*0b57cec5SDimitry Andric 1768bcb0991SDimitry Andric if (!crashHandlerString.empty()) { 1778bcb0991SDimitry Andric setCrashLogMessage(crashHandlerString.c_str()); 1788bcb0991SDimitry Andric errs() << crashHandlerString.str(); 1798bcb0991SDimitry Andric } else 1808bcb0991SDimitry Andric setCrashLogMessage("No crash information."); 181*0b57cec5SDimitry Andric #endif 182*0b57cec5SDimitry Andric } 183*0b57cec5SDimitry Andric 184*0b57cec5SDimitry Andric static void printForSigInfoIfNeeded() { 185*0b57cec5SDimitry Andric unsigned CurrentSigInfoGeneration = 186*0b57cec5SDimitry Andric GlobalSigInfoGenerationCounter.load(std::memory_order_relaxed); 187*0b57cec5SDimitry Andric if (ThreadLocalSigInfoGenerationCounter == 0 || 188*0b57cec5SDimitry Andric ThreadLocalSigInfoGenerationCounter == CurrentSigInfoGeneration) { 189*0b57cec5SDimitry Andric return; 190*0b57cec5SDimitry Andric } 191*0b57cec5SDimitry Andric 192*0b57cec5SDimitry Andric PrintCurStackTrace(errs()); 193*0b57cec5SDimitry Andric ThreadLocalSigInfoGenerationCounter = CurrentSigInfoGeneration; 194*0b57cec5SDimitry Andric } 195*0b57cec5SDimitry Andric 196*0b57cec5SDimitry Andric #endif // ENABLE_BACKTRACES 197*0b57cec5SDimitry Andric 198*0b57cec5SDimitry Andric PrettyStackTraceEntry::PrettyStackTraceEntry() { 199*0b57cec5SDimitry Andric #if ENABLE_BACKTRACES 200*0b57cec5SDimitry Andric // Handle SIGINFO first, because we haven't finished constructing yet. 201*0b57cec5SDimitry Andric printForSigInfoIfNeeded(); 202*0b57cec5SDimitry Andric // Link ourselves. 203*0b57cec5SDimitry Andric NextEntry = PrettyStackTraceHead; 204*0b57cec5SDimitry Andric PrettyStackTraceHead = this; 205*0b57cec5SDimitry Andric #endif 206*0b57cec5SDimitry Andric } 207*0b57cec5SDimitry Andric 208*0b57cec5SDimitry Andric PrettyStackTraceEntry::~PrettyStackTraceEntry() { 209*0b57cec5SDimitry Andric #if ENABLE_BACKTRACES 210*0b57cec5SDimitry Andric assert(PrettyStackTraceHead == this && 211*0b57cec5SDimitry Andric "Pretty stack trace entry destruction is out of order"); 212*0b57cec5SDimitry Andric PrettyStackTraceHead = NextEntry; 213*0b57cec5SDimitry Andric // Handle SIGINFO first, because we already started destructing. 214*0b57cec5SDimitry Andric printForSigInfoIfNeeded(); 215*0b57cec5SDimitry Andric #endif 216*0b57cec5SDimitry Andric } 217*0b57cec5SDimitry Andric 218*0b57cec5SDimitry Andric void PrettyStackTraceString::print(raw_ostream &OS) const { OS << Str << "\n"; } 219*0b57cec5SDimitry Andric 220*0b57cec5SDimitry Andric PrettyStackTraceFormat::PrettyStackTraceFormat(const char *Format, ...) { 221*0b57cec5SDimitry Andric va_list AP; 222*0b57cec5SDimitry Andric va_start(AP, Format); 223*0b57cec5SDimitry Andric const int SizeOrError = vsnprintf(nullptr, 0, Format, AP); 224*0b57cec5SDimitry Andric va_end(AP); 225*0b57cec5SDimitry Andric if (SizeOrError < 0) { 226*0b57cec5SDimitry Andric return; 227*0b57cec5SDimitry Andric } 228*0b57cec5SDimitry Andric 229*0b57cec5SDimitry Andric const int Size = SizeOrError + 1; // '\0' 230*0b57cec5SDimitry Andric Str.resize(Size); 231*0b57cec5SDimitry Andric va_start(AP, Format); 232*0b57cec5SDimitry Andric vsnprintf(Str.data(), Size, Format, AP); 233*0b57cec5SDimitry Andric va_end(AP); 234*0b57cec5SDimitry Andric } 235*0b57cec5SDimitry Andric 236*0b57cec5SDimitry Andric void PrettyStackTraceFormat::print(raw_ostream &OS) const { OS << Str << "\n"; } 237*0b57cec5SDimitry Andric 238*0b57cec5SDimitry Andric void PrettyStackTraceProgram::print(raw_ostream &OS) const { 239*0b57cec5SDimitry Andric OS << "Program arguments: "; 240*0b57cec5SDimitry Andric // Print the argument list. 241*0b57cec5SDimitry Andric for (unsigned i = 0, e = ArgC; i != e; ++i) 242*0b57cec5SDimitry Andric OS << ArgV[i] << ' '; 243*0b57cec5SDimitry Andric OS << '\n'; 244*0b57cec5SDimitry Andric } 245*0b57cec5SDimitry Andric 246*0b57cec5SDimitry Andric #if ENABLE_BACKTRACES 247*0b57cec5SDimitry Andric static bool RegisterCrashPrinter() { 248*0b57cec5SDimitry Andric sys::AddSignalHandler(CrashHandler, nullptr); 249*0b57cec5SDimitry Andric return false; 250*0b57cec5SDimitry Andric } 251*0b57cec5SDimitry Andric #endif 252*0b57cec5SDimitry Andric 253*0b57cec5SDimitry Andric void llvm::EnablePrettyStackTrace() { 254*0b57cec5SDimitry Andric #if ENABLE_BACKTRACES 255*0b57cec5SDimitry Andric // The first time this is called, we register the crash printer. 256*0b57cec5SDimitry Andric static bool HandlerRegistered = RegisterCrashPrinter(); 257*0b57cec5SDimitry Andric (void)HandlerRegistered; 258*0b57cec5SDimitry Andric #endif 259*0b57cec5SDimitry Andric } 260*0b57cec5SDimitry Andric 261*0b57cec5SDimitry Andric void llvm::EnablePrettyStackTraceOnSigInfoForThisThread(bool ShouldEnable) { 262*0b57cec5SDimitry Andric #if ENABLE_BACKTRACES 263*0b57cec5SDimitry Andric if (!ShouldEnable) { 264*0b57cec5SDimitry Andric ThreadLocalSigInfoGenerationCounter = 0; 265*0b57cec5SDimitry Andric return; 266*0b57cec5SDimitry Andric } 267*0b57cec5SDimitry Andric 268*0b57cec5SDimitry Andric // The first time this is called, we register the SIGINFO handler. 269*0b57cec5SDimitry Andric static bool HandlerRegistered = []{ 270*0b57cec5SDimitry Andric sys::SetInfoSignalFunction([]{ 271*0b57cec5SDimitry Andric GlobalSigInfoGenerationCounter.fetch_add(1, std::memory_order_relaxed); 272*0b57cec5SDimitry Andric }); 273*0b57cec5SDimitry Andric return false; 274*0b57cec5SDimitry Andric }(); 275*0b57cec5SDimitry Andric (void)HandlerRegistered; 276*0b57cec5SDimitry Andric 277*0b57cec5SDimitry Andric // Next, enable it for the current thread. 278*0b57cec5SDimitry Andric ThreadLocalSigInfoGenerationCounter = 279*0b57cec5SDimitry Andric GlobalSigInfoGenerationCounter.load(std::memory_order_relaxed); 280*0b57cec5SDimitry Andric #endif 281*0b57cec5SDimitry Andric } 282*0b57cec5SDimitry Andric 283*0b57cec5SDimitry Andric const void *llvm::SavePrettyStackState() { 284*0b57cec5SDimitry Andric #if ENABLE_BACKTRACES 285*0b57cec5SDimitry Andric return PrettyStackTraceHead; 286*0b57cec5SDimitry Andric #else 287*0b57cec5SDimitry Andric return nullptr; 288*0b57cec5SDimitry Andric #endif 289*0b57cec5SDimitry Andric } 290*0b57cec5SDimitry Andric 291*0b57cec5SDimitry Andric void llvm::RestorePrettyStackState(const void *Top) { 292*0b57cec5SDimitry Andric #if ENABLE_BACKTRACES 293*0b57cec5SDimitry Andric PrettyStackTraceHead = 294*0b57cec5SDimitry Andric static_cast<PrettyStackTraceEntry *>(const_cast<void *>(Top)); 295*0b57cec5SDimitry Andric #endif 296*0b57cec5SDimitry Andric } 297*0b57cec5SDimitry Andric 298*0b57cec5SDimitry Andric void LLVMEnablePrettyStackTrace() { 299*0b57cec5SDimitry Andric EnablePrettyStackTrace(); 300*0b57cec5SDimitry Andric } 301