1193323Sed//===- PrettyStackTrace.cpp - Pretty Crash Handling -----------------------===// 2193323Sed// 3193323Sed// The LLVM Compiler Infrastructure 4193323Sed// 5193323Sed// This file is distributed under the University of Illinois Open Source 6193323Sed// License. See LICENSE.TXT for details. 7193323Sed// 8193323Sed//===----------------------------------------------------------------------===// 9193323Sed// 10193323Sed// This file defines some helpful functions for dealing with the possibility of 11221345Sdim// Unix signals occurring while your program is running. 12193323Sed// 13193323Sed//===----------------------------------------------------------------------===// 14193323Sed 15249423Sdim#include "llvm/Support/PrettyStackTrace.h" 16296417Sdim#include "llvm-c/ErrorHandling.h" 17249423Sdim#include "llvm/ADT/SmallString.h" 18210299Sed#include "llvm/Config/config.h" // Get autoconf configuration settings 19288943Sdim#include "llvm/Support/Compiler.h" 20218893Sdim#include "llvm/Support/Signals.h" 21249423Sdim#include "llvm/Support/Watchdog.h" 22249423Sdim#include "llvm/Support/raw_ostream.h" 23210299Sed 24210299Sed#ifdef HAVE_CRASHREPORTERCLIENT_H 25210299Sed#include <CrashReporterClient.h> 26210299Sed#endif 27210299Sed 28193323Sedusing namespace llvm; 29193323Sed 30288943Sdim// If backtrace support is not enabled, compile out support for pretty stack 31288943Sdim// traces. This has the secondary effect of not requiring thread local storage 32288943Sdim// when backtrace support is disabled. 33288943Sdim#if defined(HAVE_BACKTRACE) && defined(ENABLE_BACKTRACES) 34198090Srdivacky 35288943Sdim// We need a thread local pointer to manage the stack of our stack trace 36288943Sdim// objects, but we *really* cannot tolerate destructors running and do not want 37288943Sdim// to pay any overhead of synchronizing. As a consequence, we use a raw 38288943Sdim// thread-local variable. 39288943Sdimstatic LLVM_THREAD_LOCAL const PrettyStackTraceEntry *PrettyStackTraceHead = 40288943Sdim nullptr; 41288943Sdim 42193323Sedstatic unsigned PrintStack(const PrettyStackTraceEntry *Entry, raw_ostream &OS){ 43193323Sed unsigned NextID = 0; 44193323Sed if (Entry->getNextEntry()) 45193323Sed NextID = PrintStack(Entry->getNextEntry(), OS); 46193323Sed OS << NextID << ".\t"; 47249423Sdim { 48249423Sdim sys::Watchdog W(5); 49249423Sdim Entry->print(OS); 50249423Sdim } 51193323Sed 52193323Sed return NextID+1; 53193323Sed} 54193323Sed 55193323Sed/// PrintCurStackTrace - Print the current stack trace to the specified stream. 56193323Sedstatic void PrintCurStackTrace(raw_ostream &OS) { 57193323Sed // Don't print an empty trace. 58288943Sdim if (!PrettyStackTraceHead) return; 59193323Sed 60193323Sed // If there are pretty stack frames registered, walk and emit them. 61193323Sed OS << "Stack dump:\n"; 62193323Sed 63288943Sdim PrintStack(PrettyStackTraceHead, OS); 64193323Sed OS.flush(); 65193323Sed} 66193323Sed 67210299Sed// Integrate with crash reporter libraries. 68218893Sdim#if defined (__APPLE__) && HAVE_CRASHREPORTERCLIENT_H 69210299Sed// If any clients of llvm try to link to libCrashReporterClient.a themselves, 70210299Sed// only one crash info struct will be used. 71210299Sedextern "C" { 72210299SedCRASH_REPORTER_CLIENT_HIDDEN 73210299Sedstruct crashreporter_annotations_t gCRAnnotations 74210299Sed __attribute__((section("__DATA," CRASHREPORTER_ANNOTATIONS_SECTION))) 75226633Sdim = { CRASHREPORTER_ANNOTATIONS_VERSION, 0, 0, 0, 0, 0, 0 }; 76210299Sed} 77218893Sdim#elif defined (__APPLE__) && HAVE_CRASHREPORTER_INFO 78208599Srdivackystatic const char *__crashreporter_info__ = 0; 79208599Srdivackyasm(".desc ___crashreporter_info__, 0x10"); 80193323Sed#endif 81193323Sed 82193323Sed 83193323Sed/// CrashHandler - This callback is run if a fatal signal is delivered to the 84193323Sed/// process, it prints the pretty stack trace. 85212904Sdimstatic void CrashHandler(void *) { 86193323Sed#ifndef __APPLE__ 87193323Sed // On non-apple systems, just emit the crash stack trace to stderr. 88193323Sed PrintCurStackTrace(errs()); 89193323Sed#else 90193323Sed // Otherwise, emit to a smallvector of chars, send *that* to stderr, but also 91193323Sed // put it into __crashreporter_info__. 92193323Sed SmallString<2048> TmpStr; 93193323Sed { 94193323Sed raw_svector_ostream Stream(TmpStr); 95193323Sed PrintCurStackTrace(Stream); 96193323Sed } 97193323Sed 98193323Sed if (!TmpStr.empty()) { 99218893Sdim#ifdef HAVE_CRASHREPORTERCLIENT_H 100212904Sdim // Cast to void to avoid warning. 101212904Sdim (void)CRSetCrashLogMessage(std::string(TmpStr.str()).c_str()); 102218893Sdim#elif HAVE_CRASHREPORTER_INFO 103218893Sdim __crashreporter_info__ = strdup(std::string(TmpStr.str()).c_str()); 104210299Sed#endif 105198090Srdivacky errs() << TmpStr.str(); 106193323Sed } 107193323Sed 108193323Sed#endif 109193323Sed} 110193323Sed 111288943Sdim// defined(HAVE_BACKTRACE) && defined(ENABLE_BACKTRACES) 112288943Sdim#endif 113288943Sdim 114193323SedPrettyStackTraceEntry::PrettyStackTraceEntry() { 115288943Sdim#if defined(HAVE_BACKTRACE) && defined(ENABLE_BACKTRACES) 116193323Sed // Link ourselves. 117288943Sdim NextEntry = PrettyStackTraceHead; 118288943Sdim PrettyStackTraceHead = this; 119288943Sdim#endif 120193323Sed} 121193323Sed 122193323SedPrettyStackTraceEntry::~PrettyStackTraceEntry() { 123288943Sdim#if defined(HAVE_BACKTRACE) && defined(ENABLE_BACKTRACES) 124288943Sdim assert(PrettyStackTraceHead == this && 125193323Sed "Pretty stack trace entry destruction is out of order"); 126288943Sdim PrettyStackTraceHead = getNextEntry(); 127288943Sdim#endif 128193323Sed} 129193323Sed 130193323Sedvoid PrettyStackTraceString::print(raw_ostream &OS) const { 131193323Sed OS << Str << "\n"; 132193323Sed} 133193323Sed 134193323Sedvoid PrettyStackTraceProgram::print(raw_ostream &OS) const { 135193323Sed OS << "Program arguments: "; 136193323Sed // Print the argument list. 137193323Sed for (unsigned i = 0, e = ArgC; i != e; ++i) 138193323Sed OS << ArgV[i] << ' '; 139193323Sed OS << '\n'; 140193323Sed} 141261991Sdim 142288943Sdim#if defined(HAVE_BACKTRACE) && defined(ENABLE_BACKTRACES) 143261991Sdimstatic bool RegisterCrashPrinter() { 144276479Sdim sys::AddSignalHandler(CrashHandler, nullptr); 145261991Sdim return false; 146261991Sdim} 147288943Sdim#endif 148261991Sdim 149261991Sdimvoid llvm::EnablePrettyStackTrace() { 150288943Sdim#if defined(HAVE_BACKTRACE) && defined(ENABLE_BACKTRACES) 151261991Sdim // The first time this is called, we register the crash printer. 152261991Sdim static bool HandlerRegistered = RegisterCrashPrinter(); 153261991Sdim (void)HandlerRegistered; 154288943Sdim#endif 155261991Sdim} 156261991Sdim 157296417Sdimconst void* llvm::SavePrettyStackState() { 158296417Sdim#if defined(HAVE_BACKTRACE) && defined(ENABLE_BACKTRACES) 159296417Sdim return PrettyStackTraceHead; 160296417Sdim#else 161296417Sdim return nullptr; 162296417Sdim#endif 163296417Sdim} 164296417Sdim 165296417Sdimvoid llvm::RestorePrettyStackState(const void* Top) { 166296417Sdim#if defined(HAVE_BACKTRACE) && defined(ENABLE_BACKTRACES) 167296417Sdim PrettyStackTraceHead = (const PrettyStackTraceEntry*)Top; 168296417Sdim#endif 169296417Sdim} 170296417Sdim 171261991Sdimvoid LLVMEnablePrettyStackTrace() { 172261991Sdim EnablePrettyStackTrace(); 173261991Sdim} 174