1 //===- PrettyStackTrace.cpp - Pretty Crash Handling -----------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file defines some helpful functions for dealing with the possibility of 11 // Unix signals occurring while your program is running. 12 // 13 //===----------------------------------------------------------------------===// 14 15 #include "llvm/Support/PrettyStackTrace.h" 16 #include "llvm-c/ErrorHandling.h" 17 #include "llvm/ADT/SmallString.h" 18 #include "llvm/Config/config.h" // Get autoconf configuration settings 19 #include "llvm/Support/Compiler.h" 20 #include "llvm/Support/Signals.h" 21 #include "llvm/Support/Watchdog.h" 22 #include "llvm/Support/raw_ostream.h" 23 24 #include <cstdarg> 25 #include <cstdio> 26 #include <tuple> 27 28 #ifdef HAVE_CRASHREPORTERCLIENT_H 29 #include <CrashReporterClient.h> 30 #endif 31 32 using namespace llvm; 33 34 // If backtrace support is not enabled, compile out support for pretty stack 35 // traces. This has the secondary effect of not requiring thread local storage 36 // when backtrace support is disabled. 37 #if defined(HAVE_BACKTRACE) && ENABLE_BACKTRACES 38 39 // We need a thread local pointer to manage the stack of our stack trace 40 // objects, but we *really* cannot tolerate destructors running and do not want 41 // to pay any overhead of synchronizing. As a consequence, we use a raw 42 // thread-local variable. 43 static LLVM_THREAD_LOCAL PrettyStackTraceEntry *PrettyStackTraceHead = nullptr; 44 45 namespace llvm { 46 PrettyStackTraceEntry *ReverseStackTrace(PrettyStackTraceEntry *Head) { 47 PrettyStackTraceEntry *Prev = nullptr; 48 while (Head) 49 std::tie(Prev, Head, Head->NextEntry) = 50 std::make_tuple(Head, Head->NextEntry, Prev); 51 return Prev; 52 } 53 } 54 55 static void PrintStack(raw_ostream &OS) { 56 // Print out the stack in reverse order. To avoid recursion (which is likely 57 // to fail if we crashed due to stack overflow), we do an up-front pass to 58 // reverse the stack, then print it, then reverse it again. 59 unsigned ID = 0; 60 PrettyStackTraceEntry *ReversedStack = 61 llvm::ReverseStackTrace(PrettyStackTraceHead); 62 for (const PrettyStackTraceEntry *Entry = ReversedStack; Entry; 63 Entry = Entry->getNextEntry()) { 64 OS << ID++ << ".\t"; 65 sys::Watchdog W(5); 66 Entry->print(OS); 67 } 68 llvm::ReverseStackTrace(ReversedStack); 69 } 70 71 /// PrintCurStackTrace - Print the current stack trace to the specified stream. 72 static void PrintCurStackTrace(raw_ostream &OS) { 73 // Don't print an empty trace. 74 if (!PrettyStackTraceHead) return; 75 76 // If there are pretty stack frames registered, walk and emit them. 77 OS << "Stack dump:\n"; 78 79 PrintStack(OS); 80 OS.flush(); 81 } 82 83 // Integrate with crash reporter libraries. 84 #if defined (__APPLE__) && defined(HAVE_CRASHREPORTERCLIENT_H) 85 // If any clients of llvm try to link to libCrashReporterClient.a themselves, 86 // only one crash info struct will be used. 87 extern "C" { 88 CRASH_REPORTER_CLIENT_HIDDEN 89 struct crashreporter_annotations_t gCRAnnotations 90 __attribute__((section("__DATA," CRASHREPORTER_ANNOTATIONS_SECTION))) 91 = { CRASHREPORTER_ANNOTATIONS_VERSION, 0, 0, 0, 0, 0, 0 }; 92 } 93 #elif defined(__APPLE__) && HAVE_CRASHREPORTER_INFO 94 extern "C" const char *__crashreporter_info__ 95 __attribute__((visibility("hidden"))) = 0; 96 asm(".desc ___crashreporter_info__, 0x10"); 97 #endif 98 99 /// CrashHandler - This callback is run if a fatal signal is delivered to the 100 /// process, it prints the pretty stack trace. 101 static void CrashHandler(void *) { 102 #ifndef __APPLE__ 103 // On non-apple systems, just emit the crash stack trace to stderr. 104 PrintCurStackTrace(errs()); 105 #else 106 // Otherwise, emit to a smallvector of chars, send *that* to stderr, but also 107 // put it into __crashreporter_info__. 108 SmallString<2048> TmpStr; 109 { 110 raw_svector_ostream Stream(TmpStr); 111 PrintCurStackTrace(Stream); 112 } 113 114 if (!TmpStr.empty()) { 115 #ifdef HAVE_CRASHREPORTERCLIENT_H 116 // Cast to void to avoid warning. 117 (void)CRSetCrashLogMessage(std::string(TmpStr.str()).c_str()); 118 #elif HAVE_CRASHREPORTER_INFO 119 __crashreporter_info__ = strdup(std::string(TmpStr.str()).c_str()); 120 #endif 121 errs() << TmpStr.str(); 122 } 123 124 #endif 125 } 126 127 // defined(HAVE_BACKTRACE) && ENABLE_BACKTRACES 128 #endif 129 130 PrettyStackTraceEntry::PrettyStackTraceEntry() { 131 #if defined(HAVE_BACKTRACE) && ENABLE_BACKTRACES 132 // Link ourselves. 133 NextEntry = PrettyStackTraceHead; 134 PrettyStackTraceHead = this; 135 #endif 136 } 137 138 PrettyStackTraceEntry::~PrettyStackTraceEntry() { 139 #if defined(HAVE_BACKTRACE) && ENABLE_BACKTRACES 140 assert(PrettyStackTraceHead == this && 141 "Pretty stack trace entry destruction is out of order"); 142 PrettyStackTraceHead = NextEntry; 143 #endif 144 } 145 146 void PrettyStackTraceString::print(raw_ostream &OS) const { OS << Str << "\n"; } 147 148 PrettyStackTraceFormat::PrettyStackTraceFormat(const char *Format, ...) { 149 va_list AP; 150 va_start(AP, Format); 151 const int SizeOrError = vsnprintf(nullptr, 0, Format, AP); 152 va_end(AP); 153 if (SizeOrError < 0) { 154 return; 155 } 156 157 const int Size = SizeOrError + 1; // '\0' 158 Str.resize(Size); 159 va_start(AP, Format); 160 vsnprintf(Str.data(), Size, Format, AP); 161 va_end(AP); 162 } 163 164 void PrettyStackTraceFormat::print(raw_ostream &OS) const { OS << Str << "\n"; } 165 166 void PrettyStackTraceProgram::print(raw_ostream &OS) const { 167 OS << "Program arguments: "; 168 // Print the argument list. 169 for (unsigned i = 0, e = ArgC; i != e; ++i) 170 OS << ArgV[i] << ' '; 171 OS << '\n'; 172 } 173 174 #if defined(HAVE_BACKTRACE) && ENABLE_BACKTRACES 175 static bool RegisterCrashPrinter() { 176 sys::AddSignalHandler(CrashHandler, nullptr); 177 return false; 178 } 179 #endif 180 181 void llvm::EnablePrettyStackTrace() { 182 #if defined(HAVE_BACKTRACE) && ENABLE_BACKTRACES 183 // The first time this is called, we register the crash printer. 184 static bool HandlerRegistered = RegisterCrashPrinter(); 185 (void)HandlerRegistered; 186 #endif 187 } 188 189 const void *llvm::SavePrettyStackState() { 190 #if defined(HAVE_BACKTRACE) && ENABLE_BACKTRACES 191 return PrettyStackTraceHead; 192 #else 193 return nullptr; 194 #endif 195 } 196 197 void llvm::RestorePrettyStackState(const void *Top) { 198 #if defined(HAVE_BACKTRACE) && ENABLE_BACKTRACES 199 PrettyStackTraceHead = 200 static_cast<PrettyStackTraceEntry *>(const_cast<void *>(Top)); 201 #endif 202 } 203 204 void LLVMEnablePrettyStackTrace() { 205 EnablePrettyStackTrace(); 206 } 207