Home | History | Annotate | Line # | Download | only in Support
      1 //===- PrettyStackTrace.cpp - Pretty Crash Handling -----------------------===//
      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 defines some helpful functions for dealing with the possibility of
     10 // Unix signals occurring while your program is running.
     11 //
     12 //===----------------------------------------------------------------------===//
     13 
     14 #include "llvm/Support/PrettyStackTrace.h"
     15 #include "llvm-c/ErrorHandling.h"
     16 #include "llvm/ADT/SmallString.h"
     17 #include "llvm/Config/config.h"
     18 #include "llvm/Support/Compiler.h"
     19 #include "llvm/Support/SaveAndRestore.h"
     20 #include "llvm/Support/Signals.h"
     21 #include "llvm/Support/Watchdog.h"
     22 #include "llvm/Support/raw_ostream.h"
     23 
     24 #include <atomic>
     25 #include <cassert>
     26 #include <cstdarg>
     27 #include <cstdio>
     28 #include <cstring>
     29 #include <tuple>
     30 
     31 #ifdef HAVE_CRASHREPORTERCLIENT_H
     32 #include <CrashReporterClient.h>
     33 #endif
     34 
     35 using namespace llvm;
     36 
     37 static const char *BugReportMsg =
     38     "PLEASE submit a bug report to " BUG_REPORT_URL
     39     " and include the crash backtrace.\n";
     40 
     41 // If backtrace support is not enabled, compile out support for pretty stack
     42 // traces.  This has the secondary effect of not requiring thread local storage
     43 // when backtrace support is disabled.
     44 #if ENABLE_BACKTRACES
     45 
     46 // We need a thread local pointer to manage the stack of our stack trace
     47 // objects, but we *really* cannot tolerate destructors running and do not want
     48 // to pay any overhead of synchronizing. As a consequence, we use a raw
     49 // thread-local variable.
     50 static LLVM_THREAD_LOCAL PrettyStackTraceEntry *PrettyStackTraceHead = nullptr;
     51 
     52 // The use of 'volatile' here is to ensure that any particular thread always
     53 // reloads the value of the counter. The 'std::atomic' allows us to specify that
     54 // this variable is accessed in an unsychronized way (it's not actually
     55 // synchronizing). This does technically mean that the value may not appear to
     56 // be the same across threads running simultaneously on different CPUs, but in
     57 // practice the worst that will happen is that we won't print a stack trace when
     58 // we could have.
     59 //
     60 // This is initialized to 1 because 0 is used as a sentinel for "not enabled on
     61 // the current thread". If the user happens to overflow an 'unsigned' with
     62 // SIGINFO requests, it's possible that some threads will stop responding to it,
     63 // but the program won't crash.
     64 static volatile std::atomic<unsigned> GlobalSigInfoGenerationCounter =
     65     ATOMIC_VAR_INIT(1);
     66 static LLVM_THREAD_LOCAL unsigned ThreadLocalSigInfoGenerationCounter = 0;
     67 
     68 namespace llvm {
     69 PrettyStackTraceEntry *ReverseStackTrace(PrettyStackTraceEntry *Head) {
     70   PrettyStackTraceEntry *Prev = nullptr;
     71   while (Head)
     72     std::tie(Prev, Head, Head->NextEntry) =
     73         std::make_tuple(Head, Head->NextEntry, Prev);
     74   return Prev;
     75 }
     76 } // namespace llvm
     77 
     78 static void PrintStack(raw_ostream &OS) {
     79   // Print out the stack in reverse order. To avoid recursion (which is likely
     80   // to fail if we crashed due to stack overflow), we do an up-front pass to
     81   // reverse the stack, then print it, then reverse it again.
     82   unsigned ID = 0;
     83   SaveAndRestore<PrettyStackTraceEntry *> SavedStack{PrettyStackTraceHead,
     84                                                      nullptr};
     85   PrettyStackTraceEntry *ReversedStack = ReverseStackTrace(SavedStack.get());
     86   for (const PrettyStackTraceEntry *Entry = ReversedStack; Entry;
     87        Entry = Entry->getNextEntry()) {
     88     OS << ID++ << ".\t";
     89     sys::Watchdog W(5);
     90     Entry->print(OS);
     91   }
     92   llvm::ReverseStackTrace(ReversedStack);
     93 }
     94 
     95 /// Print the current stack trace to the specified stream.
     96 ///
     97 /// Marked NOINLINE so it can be called from debuggers.
     98 LLVM_ATTRIBUTE_NOINLINE
     99 static void PrintCurStackTrace(raw_ostream &OS) {
    100   // Don't print an empty trace.
    101   if (!PrettyStackTraceHead) return;
    102 
    103   // If there are pretty stack frames registered, walk and emit them.
    104   OS << "Stack dump:\n";
    105 
    106   PrintStack(OS);
    107   OS.flush();
    108 }
    109 
    110 // Integrate with crash reporter libraries.
    111 #if defined (__APPLE__) && defined(HAVE_CRASHREPORTERCLIENT_H)
    112 //  If any clients of llvm try to link to libCrashReporterClient.a themselves,
    113 //  only one crash info struct will be used.
    114 extern "C" {
    115 CRASH_REPORTER_CLIENT_HIDDEN
    116 struct crashreporter_annotations_t gCRAnnotations
    117         __attribute__((section("__DATA," CRASHREPORTER_ANNOTATIONS_SECTION)))
    118 #if CRASHREPORTER_ANNOTATIONS_VERSION < 5
    119         = { CRASHREPORTER_ANNOTATIONS_VERSION, 0, 0, 0, 0, 0, 0 };
    120 #else
    121         = { CRASHREPORTER_ANNOTATIONS_VERSION, 0, 0, 0, 0, 0, 0, 0 };
    122 #endif
    123 }
    124 #elif defined(__APPLE__) && HAVE_CRASHREPORTER_INFO
    125 extern "C" const char *__crashreporter_info__
    126     __attribute__((visibility("hidden"))) = 0;
    127 asm(".desc ___crashreporter_info__, 0x10");
    128 #endif
    129 
    130 static void setCrashLogMessage(const char *msg) LLVM_ATTRIBUTE_UNUSED;
    131 static void setCrashLogMessage(const char *msg) {
    132 #ifdef HAVE_CRASHREPORTERCLIENT_H
    133   (void)CRSetCrashLogMessage(msg);
    134 #elif HAVE_CRASHREPORTER_INFO
    135   __crashreporter_info__ = msg;
    136 #endif
    137   // Don't reorder subsequent operations: whatever comes after might crash and
    138   // we want the system crash handling to see the message we just set.
    139   std::atomic_signal_fence(std::memory_order_seq_cst);
    140 }
    141 
    142 #ifdef __APPLE__
    143 using CrashHandlerString = SmallString<2048>;
    144 using CrashHandlerStringStorage =
    145     std::aligned_storage<sizeof(CrashHandlerString),
    146                          alignof(CrashHandlerString)>::type;
    147 static CrashHandlerStringStorage crashHandlerStringStorage;
    148 #endif
    149 
    150 /// This callback is run if a fatal signal is delivered to the process, it
    151 /// prints the pretty stack trace.
    152 static void CrashHandler(void *) {
    153   errs() << BugReportMsg ;
    154 
    155 #ifndef __APPLE__
    156   // On non-apple systems, just emit the crash stack trace to stderr.
    157   PrintCurStackTrace(errs());
    158 #else
    159   // Emit the crash stack trace to a SmallString, put it where the system crash
    160   // handling will find it, and also send it to stderr.
    161   //
    162   // The SmallString is fairly large in the hope that we don't allocate (we're
    163   // handling a fatal signal, something is already pretty wrong, allocation
    164   // might not work). Further, we don't use a magic static in case that's also
    165   // borked. We leak any allocation that does occur because the program is about
    166   // to die anyways. This is technically racy if we were handling two fatal
    167   // signals, however if we're in that situation a race is the least of our
    168   // worries.
    169   auto &crashHandlerString =
    170       *new (&crashHandlerStringStorage) CrashHandlerString;
    171 
    172   // If we crash while trying to print the stack trace, we still want the system
    173   // crash handling to have some partial information. That'll work out as long
    174   // as the SmallString doesn't allocate. If it does allocate then the system
    175   // crash handling will see some garbage because the inline buffer now contains
    176   // a pointer.
    177   setCrashLogMessage(crashHandlerString.c_str());
    178 
    179   {
    180     raw_svector_ostream Stream(crashHandlerString);
    181     PrintCurStackTrace(Stream);
    182   }
    183 
    184   if (!crashHandlerString.empty()) {
    185     setCrashLogMessage(crashHandlerString.c_str());
    186     errs() << crashHandlerString.str();
    187   } else
    188     setCrashLogMessage("No crash information.");
    189 #endif
    190 }
    191 
    192 static void printForSigInfoIfNeeded() {
    193   unsigned CurrentSigInfoGeneration =
    194       GlobalSigInfoGenerationCounter.load(std::memory_order_relaxed);
    195   if (ThreadLocalSigInfoGenerationCounter == 0 ||
    196       ThreadLocalSigInfoGenerationCounter == CurrentSigInfoGeneration) {
    197     return;
    198   }
    199 
    200   PrintCurStackTrace(errs());
    201   ThreadLocalSigInfoGenerationCounter = CurrentSigInfoGeneration;
    202 }
    203 
    204 #endif // ENABLE_BACKTRACES
    205 
    206 void llvm::setBugReportMsg(const char *Msg) {
    207   BugReportMsg = Msg;
    208 }
    209 
    210 const char *llvm::getBugReportMsg() {
    211   return BugReportMsg;
    212 }
    213 
    214 PrettyStackTraceEntry::PrettyStackTraceEntry() {
    215 #if ENABLE_BACKTRACES
    216   // Handle SIGINFO first, because we haven't finished constructing yet.
    217   printForSigInfoIfNeeded();
    218   // Link ourselves.
    219   NextEntry = PrettyStackTraceHead;
    220   PrettyStackTraceHead = this;
    221 #endif
    222 }
    223 
    224 PrettyStackTraceEntry::~PrettyStackTraceEntry() {
    225 #if ENABLE_BACKTRACES
    226   assert(PrettyStackTraceHead == this &&
    227          "Pretty stack trace entry destruction is out of order");
    228   PrettyStackTraceHead = NextEntry;
    229   // Handle SIGINFO first, because we already started destructing.
    230   printForSigInfoIfNeeded();
    231 #endif
    232 }
    233 
    234 void PrettyStackTraceString::print(raw_ostream &OS) const { OS << Str << "\n"; }
    235 
    236 PrettyStackTraceFormat::PrettyStackTraceFormat(const char *Format, ...) {
    237   va_list AP;
    238   va_start(AP, Format);
    239   const int SizeOrError = vsnprintf(nullptr, 0, Format, AP);
    240   va_end(AP);
    241   if (SizeOrError < 0) {
    242     return;
    243   }
    244 
    245   const int Size = SizeOrError + 1; // '\0'
    246   Str.resize(Size);
    247   va_start(AP, Format);
    248   vsnprintf(Str.data(), Size, Format, AP);
    249   va_end(AP);
    250 }
    251 
    252 void PrettyStackTraceFormat::print(raw_ostream &OS) const { OS << Str << "\n"; }
    253 
    254 void PrettyStackTraceProgram::print(raw_ostream &OS) const {
    255   OS << "Program arguments: ";
    256   // Print the argument list.
    257   for (int I = 0; I < ArgC; ++I) {
    258     const bool HaveSpace = ::strchr(ArgV[I], ' ');
    259     if (I)
    260       OS << ' ';
    261     if (HaveSpace)
    262       OS << '"';
    263     OS.write_escaped(ArgV[I]);
    264     if (HaveSpace)
    265       OS << '"';
    266   }
    267   OS << '\n';
    268 }
    269 
    270 #if ENABLE_BACKTRACES
    271 static bool RegisterCrashPrinter() {
    272   sys::AddSignalHandler(CrashHandler, nullptr);
    273   return false;
    274 }
    275 #endif
    276 
    277 void llvm::EnablePrettyStackTrace() {
    278 #if ENABLE_BACKTRACES
    279   // The first time this is called, we register the crash printer.
    280   static bool HandlerRegistered = RegisterCrashPrinter();
    281   (void)HandlerRegistered;
    282 #endif
    283 }
    284 
    285 void llvm::EnablePrettyStackTraceOnSigInfoForThisThread(bool ShouldEnable) {
    286 #if ENABLE_BACKTRACES
    287   if (!ShouldEnable) {
    288     ThreadLocalSigInfoGenerationCounter = 0;
    289     return;
    290   }
    291 
    292   // The first time this is called, we register the SIGINFO handler.
    293   static bool HandlerRegistered = []{
    294     sys::SetInfoSignalFunction([]{
    295       GlobalSigInfoGenerationCounter.fetch_add(1, std::memory_order_relaxed);
    296     });
    297     return false;
    298   }();
    299   (void)HandlerRegistered;
    300 
    301   // Next, enable it for the current thread.
    302   ThreadLocalSigInfoGenerationCounter =
    303       GlobalSigInfoGenerationCounter.load(std::memory_order_relaxed);
    304 #endif
    305 }
    306 
    307 const void *llvm::SavePrettyStackState() {
    308 #if ENABLE_BACKTRACES
    309   return PrettyStackTraceHead;
    310 #else
    311   return nullptr;
    312 #endif
    313 }
    314 
    315 void llvm::RestorePrettyStackState(const void *Top) {
    316 #if ENABLE_BACKTRACES
    317   PrettyStackTraceHead =
    318       static_cast<PrettyStackTraceEntry *>(const_cast<void *>(Top));
    319 #endif
    320 }
    321 
    322 void LLVMEnablePrettyStackTrace() {
    323   EnablePrettyStackTrace();
    324 }
    325