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