PrettyStackTrace.cpp revision 360784
192494Ssobomax//===- PrettyStackTrace.cpp - Pretty Crash Handling -----------------------===// 292494Ssobomax// 392494Ssobomax// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 492494Ssobomax// See https://llvm.org/LICENSE.txt for license information. 592494Ssobomax// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 692494Ssobomax// 792494Ssobomax//===----------------------------------------------------------------------===// 892494Ssobomax// 992494Ssobomax// This file defines some helpful functions for dealing with the possibility of 1092494Ssobomax// Unix signals occurring while your program is running. 1192494Ssobomax// 1292494Ssobomax//===----------------------------------------------------------------------===// 1392494Ssobomax 1492494Ssobomax#include "llvm/Support/PrettyStackTrace.h" 1592494Ssobomax#include "llvm-c/ErrorHandling.h" 1692494Ssobomax#include "llvm/ADT/SmallString.h" 1792494Ssobomax#include "llvm/Config/config.h" 1892494Ssobomax#include "llvm/Support/Compiler.h" 1992494Ssobomax#include "llvm/Support/SaveAndRestore.h" 2092494Ssobomax#include "llvm/Support/Signals.h" 2192494Ssobomax#include "llvm/Support/Watchdog.h" 2292494Ssobomax#include "llvm/Support/raw_ostream.h" 2392494Ssobomax 2492494Ssobomax#include <atomic> 2592494Ssobomax#include <cstdarg> 2692494Ssobomax#include <cstdio> 2792494Ssobomax#include <tuple> 2892494Ssobomax 2992494Ssobomax#ifdef HAVE_CRASHREPORTERCLIENT_H 3092494Ssobomax#include <CrashReporterClient.h> 3192494Ssobomax#endif 3292494Ssobomax 3392494Ssobomaxusing namespace llvm; 3492494Ssobomax 3592494Ssobomax// If backtrace support is not enabled, compile out support for pretty stack 3692494Ssobomax// traces. This has the secondary effect of not requiring thread local storage 3792494Ssobomax// when backtrace support is disabled. 3892494Ssobomax#if ENABLE_BACKTRACES 3992494Ssobomax 4092494Ssobomax// We need a thread local pointer to manage the stack of our stack trace 4192494Ssobomax// objects, but we *really* cannot tolerate destructors running and do not want 4292494Ssobomax// to pay any overhead of synchronizing. As a consequence, we use a raw 4392494Ssobomax// thread-local variable. 4492494Ssobomaxstatic LLVM_THREAD_LOCAL PrettyStackTraceEntry *PrettyStackTraceHead = nullptr; 4592494Ssobomax 4692494Ssobomax// The use of 'volatile' here is to ensure that any particular thread always 47124572Sjhb// reloads the value of the counter. The 'std::atomic' allows us to specify that 4892494Ssobomax// this variable is accessed in an unsychronized way (it's not actually 4992494Ssobomax// synchronizing). This does technically mean that the value may not appear to 5092494Ssobomax// be the same across threads running simultaneously on different CPUs, but in 5192494Ssobomax// practice the worst that will happen is that we won't print a stack trace when 5292494Ssobomax// we could have. 5392494Ssobomax// 5492494Ssobomax// This is initialized to 1 because 0 is used as a sentinel for "not enabled on 5592494Ssobomax// the current thread". If the user happens to overflow an 'unsigned' with 5692494Ssobomax// SIGINFO requests, it's possible that some threads will stop responding to it, 5792494Ssobomax// but the program won't crash. 5892494Ssobomaxstatic volatile std::atomic<unsigned> GlobalSigInfoGenerationCounter = 5992494Ssobomax ATOMIC_VAR_INIT(1); 6092494Ssobomaxstatic LLVM_THREAD_LOCAL unsigned ThreadLocalSigInfoGenerationCounter = 0; 6192494Ssobomax 6292494Ssobomaxnamespace llvm { 6392494SsobomaxPrettyStackTraceEntry *ReverseStackTrace(PrettyStackTraceEntry *Head) { 6492494Ssobomax PrettyStackTraceEntry *Prev = nullptr; 6592494Ssobomax while (Head) 6692494Ssobomax std::tie(Prev, Head, Head->NextEntry) = 6792494Ssobomax std::make_tuple(Head, Head->NextEntry, Prev); 68124571Sjhb return Prev; 6992494Ssobomax} 70124571Sjhb} 7192494Ssobomax 7292494Ssobomaxstatic void PrintStack(raw_ostream &OS) { 7392494Ssobomax // Print out the stack in reverse order. To avoid recursion (which is likely 7492494Ssobomax // to fail if we crashed due to stack overflow), we do an up-front pass to 7592494Ssobomax // reverse the stack, then print it, then reverse it again. 7692494Ssobomax unsigned ID = 0; 77124571Sjhb SaveAndRestore<PrettyStackTraceEntry *> SavedStack{PrettyStackTraceHead, 78124571Sjhb nullptr}; 7992494Ssobomax PrettyStackTraceEntry *ReversedStack = ReverseStackTrace(SavedStack.get()); 8092494Ssobomax for (const PrettyStackTraceEntry *Entry = ReversedStack; Entry; 8192494Ssobomax Entry = Entry->getNextEntry()) { 82124572Sjhb OS << ID++ << ".\t"; 83124572Sjhb sys::Watchdog W(5); 84124572Sjhb Entry->print(OS); 85124572Sjhb } 86124572Sjhb llvm::ReverseStackTrace(ReversedStack); 87124572Sjhb} 88124572Sjhb 89124572Sjhb/// Print the current stack trace to the specified stream. 90124572Sjhb/// 91124572Sjhb/// Marked NOINLINE so it can be called from debuggers. 92124572SjhbLLVM_ATTRIBUTE_NOINLINE 93124572Sjhbstatic void PrintCurStackTrace(raw_ostream &OS) { 94124572Sjhb // Don't print an empty trace. 95124572Sjhb if (!PrettyStackTraceHead) return; 96124572Sjhb 97124572Sjhb // If there are pretty stack frames registered, walk and emit them. 98124572Sjhb OS << "Stack dump:\n"; 99124572Sjhb 100124572Sjhb PrintStack(OS); 101124572Sjhb OS.flush(); 102124572Sjhb} 103124572Sjhb 10492494Ssobomax// Integrate with crash reporter libraries. 10592494Ssobomax#if defined (__APPLE__) && defined(HAVE_CRASHREPORTERCLIENT_H) 10692494Ssobomax// If any clients of llvm try to link to libCrashReporterClient.a themselves, 10792494Ssobomax// only one crash info struct will be used. 10892494Ssobomaxextern "C" { 10992494SsobomaxCRASH_REPORTER_CLIENT_HIDDEN 11092494Ssobomaxstruct crashreporter_annotations_t gCRAnnotations 11192494Ssobomax __attribute__((section("__DATA," CRASHREPORTER_ANNOTATIONS_SECTION))) 11292494Ssobomax#if CRASHREPORTER_ANNOTATIONS_VERSION < 5 11392494Ssobomax = { CRASHREPORTER_ANNOTATIONS_VERSION, 0, 0, 0, 0, 0, 0 }; 11492494Ssobomax#else 11592494Ssobomax = { CRASHREPORTER_ANNOTATIONS_VERSION, 0, 0, 0, 0, 0, 0, 0 }; 11692494Ssobomax#endif 11792494Ssobomax} 11892494Ssobomax#elif defined(__APPLE__) && HAVE_CRASHREPORTER_INFO 11992494Ssobomaxextern "C" const char *__crashreporter_info__ 12092494Ssobomax __attribute__((visibility("hidden"))) = 0; 12192494Ssobomaxasm(".desc ___crashreporter_info__, 0x10"); 12292494Ssobomax#endif 12392494Ssobomax 12492494Ssobomaxstatic void setCrashLogMessage(const char *msg) LLVM_ATTRIBUTE_UNUSED; 12592494Ssobomaxstatic void setCrashLogMessage(const char *msg) { 12692494Ssobomax#ifdef HAVE_CRASHREPORTERCLIENT_H 12792494Ssobomax (void)CRSetCrashLogMessage(msg); 12892494Ssobomax#elif HAVE_CRASHREPORTER_INFO 12992494Ssobomax __crashreporter_info__ = msg; 13092494Ssobomax#endif 13192494Ssobomax // Don't reorder subsequent operations: whatever comes after might crash and 13292494Ssobomax // we want the system crash handling to see the message we just set. 13392494Ssobomax std::atomic_signal_fence(std::memory_order_seq_cst); 13492494Ssobomax} 13592494Ssobomax 13692494Ssobomax#ifdef __APPLE__ 13792494Ssobomaxusing CrashHandlerString = SmallString<2048>; 13892494Ssobomaxusing CrashHandlerStringStorage = 13992494Ssobomax std::aligned_storage<sizeof(CrashHandlerString), 14092494Ssobomax alignof(CrashHandlerString)>::type; 14192494Ssobomaxstatic CrashHandlerStringStorage crashHandlerStringStorage; 14292494Ssobomax#endif 14392494Ssobomax 14492494Ssobomax/// This callback is run if a fatal signal is delivered to the process, it 14592494Ssobomax/// prints the pretty stack trace. 14692494Ssobomaxstatic void CrashHandler(void *) { 14792494Ssobomax#ifndef __APPLE__ 14892494Ssobomax // On non-apple systems, just emit the crash stack trace to stderr. 14992494Ssobomax PrintCurStackTrace(errs()); 15092494Ssobomax#else 15192494Ssobomax // Emit the crash stack trace to a SmallString, put it where the system crash 15292494Ssobomax // handling will find it, and also send it to stderr. 15392494Ssobomax // 15492494Ssobomax // The SmallString is fairly large in the hope that we don't allocate (we're 15592494Ssobomax // handling a fatal signal, something is already pretty wrong, allocation 15692494Ssobomax // might not work). Further, we don't use a magic static in case that's also 15792494Ssobomax // borked. We leak any allocation that does occur because the program is about 15892494Ssobomax // to die anyways. This is technically racy if we were handling two fatal 15992494Ssobomax // signals, however if we're in that situation a race is the least of our 16092494Ssobomax // worries. 16192494Ssobomax auto &crashHandlerString = 16292494Ssobomax *new (&crashHandlerStringStorage) CrashHandlerString; 16392494Ssobomax 16492494Ssobomax // If we crash while trying to print the stack trace, we still want the system 165124572Sjhb // crash handling to have some partial information. That'll work out as long 16692494Ssobomax // as the SmallString doesn't allocate. If it does allocate then the system 16792494Ssobomax // crash handling will see some garbage because the inline buffer now contains 16892494Ssobomax // a pointer. 169124572Sjhb setCrashLogMessage(crashHandlerString.c_str()); 170124572Sjhb 171124572Sjhb { 172124572Sjhb raw_svector_ostream Stream(crashHandlerString); 173124572Sjhb PrintCurStackTrace(Stream); 17492494Ssobomax } 17592494Ssobomax 17692494Ssobomax if (!crashHandlerString.empty()) { 17792494Ssobomax setCrashLogMessage(crashHandlerString.c_str()); 17892494Ssobomax errs() << crashHandlerString.str(); 17992494Ssobomax } else 18092494Ssobomax setCrashLogMessage("No crash information."); 18192494Ssobomax#endif 18292494Ssobomax} 18392494Ssobomax 18492494Ssobomaxstatic void printForSigInfoIfNeeded() { 18592494Ssobomax unsigned CurrentSigInfoGeneration = 18692494Ssobomax GlobalSigInfoGenerationCounter.load(std::memory_order_relaxed); 18792494Ssobomax if (ThreadLocalSigInfoGenerationCounter == 0 || 18892494Ssobomax ThreadLocalSigInfoGenerationCounter == CurrentSigInfoGeneration) { 18992494Ssobomax return; 19092494Ssobomax } 19192494Ssobomax 19292494Ssobomax PrintCurStackTrace(errs()); 19392494Ssobomax ThreadLocalSigInfoGenerationCounter = CurrentSigInfoGeneration; 19492494Ssobomax} 19592494Ssobomax 19692494Ssobomax#endif // ENABLE_BACKTRACES 19792494Ssobomax 19892494SsobomaxPrettyStackTraceEntry::PrettyStackTraceEntry() { 19992494Ssobomax#if ENABLE_BACKTRACES 20092494Ssobomax // Handle SIGINFO first, because we haven't finished constructing yet. 20192494Ssobomax printForSigInfoIfNeeded(); 20292494Ssobomax // Link ourselves. 20392494Ssobomax NextEntry = PrettyStackTraceHead; 20492494Ssobomax PrettyStackTraceHead = this; 20592494Ssobomax#endif 20692494Ssobomax} 20792494Ssobomax 20892494SsobomaxPrettyStackTraceEntry::~PrettyStackTraceEntry() { 20992494Ssobomax#if ENABLE_BACKTRACES 210136093Sstefanf assert(PrettyStackTraceHead == this && 21192494Ssobomax "Pretty stack trace entry destruction is out of order"); 21292494Ssobomax PrettyStackTraceHead = NextEntry; 21392494Ssobomax // Handle SIGINFO first, because we already started destructing. 21492494Ssobomax printForSigInfoIfNeeded(); 21592494Ssobomax#endif 21692494Ssobomax} 21792494Ssobomax 21892494Ssobomaxvoid PrettyStackTraceString::print(raw_ostream &OS) const { OS << Str << "\n"; } 21992494Ssobomax 22092494SsobomaxPrettyStackTraceFormat::PrettyStackTraceFormat(const char *Format, ...) { 221124572Sjhb va_list AP; 222124572Sjhb va_start(AP, Format); 22392494Ssobomax const int SizeOrError = vsnprintf(nullptr, 0, Format, AP); 22492494Ssobomax va_end(AP); 22592494Ssobomax if (SizeOrError < 0) { 22692494Ssobomax return; 22792494Ssobomax } 22892494Ssobomax 22992494Ssobomax const int Size = SizeOrError + 1; // '\0' 23092494Ssobomax Str.resize(Size); 23192494Ssobomax va_start(AP, Format); 23292494Ssobomax vsnprintf(Str.data(), Size, Format, AP); 23392494Ssobomax va_end(AP); 23492494Ssobomax} 23592494Ssobomax 23692494Ssobomaxvoid PrettyStackTraceFormat::print(raw_ostream &OS) const { OS << Str << "\n"; } 23792494Ssobomax 23892494Ssobomaxvoid PrettyStackTraceProgram::print(raw_ostream &OS) const { 23992494Ssobomax OS << "Program arguments: "; 24092494Ssobomax // Print the argument list. 24192494Ssobomax for (unsigned i = 0, e = ArgC; i != e; ++i) 24292494Ssobomax OS << ArgV[i] << ' '; 24392494Ssobomax OS << '\n'; 24492494Ssobomax} 24592494Ssobomax 24692494Ssobomax#if ENABLE_BACKTRACES 24792494Ssobomaxstatic bool RegisterCrashPrinter() { 24892494Ssobomax sys::AddSignalHandler(CrashHandler, nullptr); 24992494Ssobomax return false; 25092494Ssobomax} 25192494Ssobomax#endif 25292494Ssobomax 253124811Sjhbvoid llvm::EnablePrettyStackTrace() { 254124811Sjhb#if ENABLE_BACKTRACES 255124811Sjhb // The first time this is called, we register the crash printer. 25692494Ssobomax static bool HandlerRegistered = RegisterCrashPrinter(); 25792494Ssobomax (void)HandlerRegistered; 25892494Ssobomax#endif 25992494Ssobomax} 26092494Ssobomax 26192494Ssobomaxvoid llvm::EnablePrettyStackTraceOnSigInfoForThisThread(bool ShouldEnable) { 26292494Ssobomax#if ENABLE_BACKTRACES 26392494Ssobomax if (!ShouldEnable) { 26492494Ssobomax ThreadLocalSigInfoGenerationCounter = 0; 26592494Ssobomax return; 26692494Ssobomax } 267124811Sjhb 268124811Sjhb // The first time this is called, we register the SIGINFO handler. 26992494Ssobomax static bool HandlerRegistered = []{ 270124811Sjhb sys::SetInfoSignalFunction([]{ 27192494Ssobomax GlobalSigInfoGenerationCounter.fetch_add(1, std::memory_order_relaxed); 27292494Ssobomax }); 27392494Ssobomax return false; 27492494Ssobomax }(); 27592494Ssobomax (void)HandlerRegistered; 27692494Ssobomax 27792494Ssobomax // Next, enable it for the current thread. 27892494Ssobomax ThreadLocalSigInfoGenerationCounter = 27992494Ssobomax GlobalSigInfoGenerationCounter.load(std::memory_order_relaxed); 28092494Ssobomax#endif 28192494Ssobomax} 28292494Ssobomax 28392494Ssobomaxconst void *llvm::SavePrettyStackState() { 28492494Ssobomax#if ENABLE_BACKTRACES 28592494Ssobomax return PrettyStackTraceHead; 28692494Ssobomax#else 28792494Ssobomax return nullptr; 28892494Ssobomax#endif 28992494Ssobomax} 29092494Ssobomax 291124811Sjhbvoid llvm::RestorePrettyStackState(const void *Top) { 292124811Sjhb#if ENABLE_BACKTRACES 29392494Ssobomax PrettyStackTraceHead = 294124811Sjhb static_cast<PrettyStackTraceEntry *>(const_cast<void *>(Top)); 29592494Ssobomax#endif 29692494Ssobomax} 29792494Ssobomax 29892494Ssobomaxvoid LLVMEnablePrettyStackTrace() { 29992494Ssobomax EnablePrettyStackTrace(); 30092494Ssobomax} 30192494Ssobomax