10b57cec5SDimitry Andric //===- PrettyStackTrace.cpp - Pretty Crash Handling -----------------------===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric // This file defines some helpful functions for dealing with the possibility of 100b57cec5SDimitry Andric // Unix signals occurring while your program is running. 110b57cec5SDimitry Andric // 120b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 130b57cec5SDimitry Andric 140b57cec5SDimitry Andric #include "llvm/Support/PrettyStackTrace.h" 150b57cec5SDimitry Andric #include "llvm-c/ErrorHandling.h" 160b57cec5SDimitry Andric #include "llvm/Config/config.h" 170b57cec5SDimitry Andric #include "llvm/Support/Compiler.h" 180b57cec5SDimitry Andric #include "llvm/Support/SaveAndRestore.h" 190b57cec5SDimitry Andric #include "llvm/Support/Signals.h" 200b57cec5SDimitry Andric #include "llvm/Support/Watchdog.h" 210b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h" 220b57cec5SDimitry Andric 2304eeddc0SDimitry Andric #ifdef __APPLE__ 2404eeddc0SDimitry Andric #include "llvm/ADT/SmallString.h" 2504eeddc0SDimitry Andric #endif 2604eeddc0SDimitry Andric 270b57cec5SDimitry Andric #include <atomic> 285ffd83dbSDimitry Andric #include <cassert> 290b57cec5SDimitry Andric #include <cstdarg> 300b57cec5SDimitry Andric #include <cstdio> 31e8d8bef9SDimitry Andric #include <cstring> 320b57cec5SDimitry Andric #include <tuple> 330b57cec5SDimitry Andric 340b57cec5SDimitry Andric #ifdef HAVE_CRASHREPORTERCLIENT_H 350b57cec5SDimitry Andric #include <CrashReporterClient.h> 360b57cec5SDimitry Andric #endif 370b57cec5SDimitry Andric 380b57cec5SDimitry Andric using namespace llvm; 390b57cec5SDimitry Andric 405ffd83dbSDimitry Andric static const char *BugReportMsg = 415ffd83dbSDimitry Andric "PLEASE submit a bug report to " BUG_REPORT_URL 425ffd83dbSDimitry Andric " and include the crash backtrace.\n"; 435ffd83dbSDimitry Andric 440b57cec5SDimitry Andric // If backtrace support is not enabled, compile out support for pretty stack 450b57cec5SDimitry Andric // traces. This has the secondary effect of not requiring thread local storage 460b57cec5SDimitry Andric // when backtrace support is disabled. 470b57cec5SDimitry Andric #if ENABLE_BACKTRACES 480b57cec5SDimitry Andric 490b57cec5SDimitry Andric // We need a thread local pointer to manage the stack of our stack trace 500b57cec5SDimitry Andric // objects, but we *really* cannot tolerate destructors running and do not want 510b57cec5SDimitry Andric // to pay any overhead of synchronizing. As a consequence, we use a raw 520b57cec5SDimitry Andric // thread-local variable. 530b57cec5SDimitry Andric static LLVM_THREAD_LOCAL PrettyStackTraceEntry *PrettyStackTraceHead = nullptr; 540b57cec5SDimitry Andric 550b57cec5SDimitry Andric // The use of 'volatile' here is to ensure that any particular thread always 560b57cec5SDimitry Andric // reloads the value of the counter. The 'std::atomic' allows us to specify that 570b57cec5SDimitry Andric // this variable is accessed in an unsychronized way (it's not actually 580b57cec5SDimitry Andric // synchronizing). This does technically mean that the value may not appear to 590b57cec5SDimitry Andric // be the same across threads running simultaneously on different CPUs, but in 600b57cec5SDimitry Andric // practice the worst that will happen is that we won't print a stack trace when 610b57cec5SDimitry Andric // we could have. 620b57cec5SDimitry Andric // 630b57cec5SDimitry Andric // This is initialized to 1 because 0 is used as a sentinel for "not enabled on 640b57cec5SDimitry Andric // the current thread". If the user happens to overflow an 'unsigned' with 650b57cec5SDimitry Andric // SIGINFO requests, it's possible that some threads will stop responding to it, 660b57cec5SDimitry Andric // but the program won't crash. 6706c3fb27SDimitry Andric static volatile std::atomic<unsigned> GlobalSigInfoGenerationCounter = 1; 680b57cec5SDimitry Andric static LLVM_THREAD_LOCAL unsigned ThreadLocalSigInfoGenerationCounter = 0; 690b57cec5SDimitry Andric 700b57cec5SDimitry Andric namespace llvm { 710b57cec5SDimitry Andric PrettyStackTraceEntry *ReverseStackTrace(PrettyStackTraceEntry *Head) { 720b57cec5SDimitry Andric PrettyStackTraceEntry *Prev = nullptr; 730b57cec5SDimitry Andric while (Head) 740b57cec5SDimitry Andric std::tie(Prev, Head, Head->NextEntry) = 750b57cec5SDimitry Andric std::make_tuple(Head, Head->NextEntry, Prev); 760b57cec5SDimitry Andric return Prev; 770b57cec5SDimitry Andric } 78fe6060f1SDimitry Andric } // namespace llvm 790b57cec5SDimitry Andric 800b57cec5SDimitry Andric static void PrintStack(raw_ostream &OS) { 810b57cec5SDimitry Andric // Print out the stack in reverse order. To avoid recursion (which is likely 820b57cec5SDimitry Andric // to fail if we crashed due to stack overflow), we do an up-front pass to 830b57cec5SDimitry Andric // reverse the stack, then print it, then reverse it again. 840b57cec5SDimitry Andric unsigned ID = 0; 850b57cec5SDimitry Andric SaveAndRestore<PrettyStackTraceEntry *> SavedStack{PrettyStackTraceHead, 860b57cec5SDimitry Andric nullptr}; 870b57cec5SDimitry Andric PrettyStackTraceEntry *ReversedStack = ReverseStackTrace(SavedStack.get()); 880b57cec5SDimitry Andric for (const PrettyStackTraceEntry *Entry = ReversedStack; Entry; 890b57cec5SDimitry Andric Entry = Entry->getNextEntry()) { 900b57cec5SDimitry Andric OS << ID++ << ".\t"; 910b57cec5SDimitry Andric sys::Watchdog W(5); 920b57cec5SDimitry Andric Entry->print(OS); 930b57cec5SDimitry Andric } 940b57cec5SDimitry Andric llvm::ReverseStackTrace(ReversedStack); 950b57cec5SDimitry Andric } 960b57cec5SDimitry Andric 970b57cec5SDimitry Andric /// Print the current stack trace to the specified stream. 980b57cec5SDimitry Andric /// 990b57cec5SDimitry Andric /// Marked NOINLINE so it can be called from debuggers. 1000b57cec5SDimitry Andric LLVM_ATTRIBUTE_NOINLINE 1010b57cec5SDimitry Andric static void PrintCurStackTrace(raw_ostream &OS) { 1020b57cec5SDimitry Andric // Don't print an empty trace. 1030b57cec5SDimitry Andric if (!PrettyStackTraceHead) return; 1040b57cec5SDimitry Andric 1050b57cec5SDimitry Andric // If there are pretty stack frames registered, walk and emit them. 1060b57cec5SDimitry Andric OS << "Stack dump:\n"; 1070b57cec5SDimitry Andric 1080b57cec5SDimitry Andric PrintStack(OS); 1090b57cec5SDimitry Andric OS.flush(); 1100b57cec5SDimitry Andric } 1110b57cec5SDimitry Andric 1120b57cec5SDimitry Andric // Integrate with crash reporter libraries. 1130b57cec5SDimitry Andric #if defined (__APPLE__) && defined(HAVE_CRASHREPORTERCLIENT_H) 1140b57cec5SDimitry Andric // If any clients of llvm try to link to libCrashReporterClient.a themselves, 1150b57cec5SDimitry Andric // only one crash info struct will be used. 1160b57cec5SDimitry Andric extern "C" { 1170b57cec5SDimitry Andric CRASH_REPORTER_CLIENT_HIDDEN 1180b57cec5SDimitry Andric struct crashreporter_annotations_t gCRAnnotations 1190b57cec5SDimitry Andric __attribute__((section("__DATA," CRASHREPORTER_ANNOTATIONS_SECTION))) 1200b57cec5SDimitry Andric #if CRASHREPORTER_ANNOTATIONS_VERSION < 5 1210b57cec5SDimitry Andric = { CRASHREPORTER_ANNOTATIONS_VERSION, 0, 0, 0, 0, 0, 0 }; 1220b57cec5SDimitry Andric #else 1230b57cec5SDimitry Andric = { CRASHREPORTER_ANNOTATIONS_VERSION, 0, 0, 0, 0, 0, 0, 0 }; 1240b57cec5SDimitry Andric #endif 1250b57cec5SDimitry Andric } 1260b57cec5SDimitry Andric #elif defined(__APPLE__) && HAVE_CRASHREPORTER_INFO 1270b57cec5SDimitry Andric extern "C" const char *__crashreporter_info__ 1280b57cec5SDimitry Andric __attribute__((visibility("hidden"))) = 0; 1290b57cec5SDimitry Andric asm(".desc ___crashreporter_info__, 0x10"); 1300b57cec5SDimitry Andric #endif 1310b57cec5SDimitry Andric 1328bcb0991SDimitry Andric static void setCrashLogMessage(const char *msg) LLVM_ATTRIBUTE_UNUSED; 1338bcb0991SDimitry Andric static void setCrashLogMessage(const char *msg) { 1348bcb0991SDimitry Andric #ifdef HAVE_CRASHREPORTERCLIENT_H 1358bcb0991SDimitry Andric (void)CRSetCrashLogMessage(msg); 1368bcb0991SDimitry Andric #elif HAVE_CRASHREPORTER_INFO 1378bcb0991SDimitry Andric __crashreporter_info__ = msg; 1388bcb0991SDimitry Andric #endif 1398bcb0991SDimitry Andric // Don't reorder subsequent operations: whatever comes after might crash and 1408bcb0991SDimitry Andric // we want the system crash handling to see the message we just set. 1418bcb0991SDimitry Andric std::atomic_signal_fence(std::memory_order_seq_cst); 1428bcb0991SDimitry Andric } 1438bcb0991SDimitry Andric 1448bcb0991SDimitry Andric #ifdef __APPLE__ 1458bcb0991SDimitry Andric using CrashHandlerString = SmallString<2048>; 146*0fca6ea1SDimitry Andric using CrashHandlerStringStorage = std::byte[sizeof(CrashHandlerString)]; 147*0fca6ea1SDimitry Andric alignas(CrashHandlerString) static CrashHandlerStringStorage 148*0fca6ea1SDimitry Andric crashHandlerStringStorage; 1498bcb0991SDimitry Andric #endif 1508bcb0991SDimitry Andric 1518bcb0991SDimitry Andric /// This callback is run if a fatal signal is delivered to the process, it 1528bcb0991SDimitry Andric /// prints the pretty stack trace. 1530b57cec5SDimitry Andric static void CrashHandler(void *) { 1545ffd83dbSDimitry Andric errs() << BugReportMsg ; 1555ffd83dbSDimitry Andric 1560b57cec5SDimitry Andric #ifndef __APPLE__ 1570b57cec5SDimitry Andric // On non-apple systems, just emit the crash stack trace to stderr. 1580b57cec5SDimitry Andric PrintCurStackTrace(errs()); 1590b57cec5SDimitry Andric #else 1608bcb0991SDimitry Andric // Emit the crash stack trace to a SmallString, put it where the system crash 1618bcb0991SDimitry Andric // handling will find it, and also send it to stderr. 1628bcb0991SDimitry Andric // 1638bcb0991SDimitry Andric // The SmallString is fairly large in the hope that we don't allocate (we're 1648bcb0991SDimitry Andric // handling a fatal signal, something is already pretty wrong, allocation 1658bcb0991SDimitry Andric // might not work). Further, we don't use a magic static in case that's also 1668bcb0991SDimitry Andric // borked. We leak any allocation that does occur because the program is about 1678bcb0991SDimitry Andric // to die anyways. This is technically racy if we were handling two fatal 1688bcb0991SDimitry Andric // signals, however if we're in that situation a race is the least of our 1698bcb0991SDimitry Andric // worries. 1708bcb0991SDimitry Andric auto &crashHandlerString = 1718bcb0991SDimitry Andric *new (&crashHandlerStringStorage) CrashHandlerString; 1728bcb0991SDimitry Andric 1738bcb0991SDimitry Andric // If we crash while trying to print the stack trace, we still want the system 1748bcb0991SDimitry Andric // crash handling to have some partial information. That'll work out as long 1758bcb0991SDimitry Andric // as the SmallString doesn't allocate. If it does allocate then the system 1768bcb0991SDimitry Andric // crash handling will see some garbage because the inline buffer now contains 1778bcb0991SDimitry Andric // a pointer. 1788bcb0991SDimitry Andric setCrashLogMessage(crashHandlerString.c_str()); 1798bcb0991SDimitry Andric 1800b57cec5SDimitry Andric { 1818bcb0991SDimitry Andric raw_svector_ostream Stream(crashHandlerString); 1820b57cec5SDimitry Andric PrintCurStackTrace(Stream); 1830b57cec5SDimitry Andric } 1840b57cec5SDimitry Andric 1858bcb0991SDimitry Andric if (!crashHandlerString.empty()) { 1868bcb0991SDimitry Andric setCrashLogMessage(crashHandlerString.c_str()); 1878bcb0991SDimitry Andric errs() << crashHandlerString.str(); 1888bcb0991SDimitry Andric } else 1898bcb0991SDimitry Andric setCrashLogMessage("No crash information."); 1900b57cec5SDimitry Andric #endif 1910b57cec5SDimitry Andric } 1920b57cec5SDimitry Andric 1930b57cec5SDimitry Andric static void printForSigInfoIfNeeded() { 1940b57cec5SDimitry Andric unsigned CurrentSigInfoGeneration = 1950b57cec5SDimitry Andric GlobalSigInfoGenerationCounter.load(std::memory_order_relaxed); 1960b57cec5SDimitry Andric if (ThreadLocalSigInfoGenerationCounter == 0 || 1970b57cec5SDimitry Andric ThreadLocalSigInfoGenerationCounter == CurrentSigInfoGeneration) { 1980b57cec5SDimitry Andric return; 1990b57cec5SDimitry Andric } 2000b57cec5SDimitry Andric 2010b57cec5SDimitry Andric PrintCurStackTrace(errs()); 2020b57cec5SDimitry Andric ThreadLocalSigInfoGenerationCounter = CurrentSigInfoGeneration; 2030b57cec5SDimitry Andric } 2040b57cec5SDimitry Andric 2050b57cec5SDimitry Andric #endif // ENABLE_BACKTRACES 2060b57cec5SDimitry Andric 2075ffd83dbSDimitry Andric void llvm::setBugReportMsg(const char *Msg) { 2085ffd83dbSDimitry Andric BugReportMsg = Msg; 2095ffd83dbSDimitry Andric } 2105ffd83dbSDimitry Andric 2115ffd83dbSDimitry Andric const char *llvm::getBugReportMsg() { 2125ffd83dbSDimitry Andric return BugReportMsg; 2135ffd83dbSDimitry Andric } 2145ffd83dbSDimitry Andric 2150b57cec5SDimitry Andric PrettyStackTraceEntry::PrettyStackTraceEntry() { 2160b57cec5SDimitry Andric #if ENABLE_BACKTRACES 2170b57cec5SDimitry Andric // Handle SIGINFO first, because we haven't finished constructing yet. 2180b57cec5SDimitry Andric printForSigInfoIfNeeded(); 2190b57cec5SDimitry Andric // Link ourselves. 2200b57cec5SDimitry Andric NextEntry = PrettyStackTraceHead; 2210b57cec5SDimitry Andric PrettyStackTraceHead = this; 2220b57cec5SDimitry Andric #endif 2230b57cec5SDimitry Andric } 2240b57cec5SDimitry Andric 2250b57cec5SDimitry Andric PrettyStackTraceEntry::~PrettyStackTraceEntry() { 2260b57cec5SDimitry Andric #if ENABLE_BACKTRACES 2270b57cec5SDimitry Andric assert(PrettyStackTraceHead == this && 2280b57cec5SDimitry Andric "Pretty stack trace entry destruction is out of order"); 2290b57cec5SDimitry Andric PrettyStackTraceHead = NextEntry; 2300b57cec5SDimitry Andric // Handle SIGINFO first, because we already started destructing. 2310b57cec5SDimitry Andric printForSigInfoIfNeeded(); 2320b57cec5SDimitry Andric #endif 2330b57cec5SDimitry Andric } 2340b57cec5SDimitry Andric 2350b57cec5SDimitry Andric void PrettyStackTraceString::print(raw_ostream &OS) const { OS << Str << "\n"; } 2360b57cec5SDimitry Andric 2370b57cec5SDimitry Andric PrettyStackTraceFormat::PrettyStackTraceFormat(const char *Format, ...) { 2380b57cec5SDimitry Andric va_list AP; 2390b57cec5SDimitry Andric va_start(AP, Format); 2400b57cec5SDimitry Andric const int SizeOrError = vsnprintf(nullptr, 0, Format, AP); 2410b57cec5SDimitry Andric va_end(AP); 2420b57cec5SDimitry Andric if (SizeOrError < 0) { 2430b57cec5SDimitry Andric return; 2440b57cec5SDimitry Andric } 2450b57cec5SDimitry Andric 2460b57cec5SDimitry Andric const int Size = SizeOrError + 1; // '\0' 2470b57cec5SDimitry Andric Str.resize(Size); 2480b57cec5SDimitry Andric va_start(AP, Format); 2490b57cec5SDimitry Andric vsnprintf(Str.data(), Size, Format, AP); 2500b57cec5SDimitry Andric va_end(AP); 2510b57cec5SDimitry Andric } 2520b57cec5SDimitry Andric 2530b57cec5SDimitry Andric void PrettyStackTraceFormat::print(raw_ostream &OS) const { OS << Str << "\n"; } 2540b57cec5SDimitry Andric 2550b57cec5SDimitry Andric void PrettyStackTraceProgram::print(raw_ostream &OS) const { 2560b57cec5SDimitry Andric OS << "Program arguments: "; 2570b57cec5SDimitry Andric // Print the argument list. 258e8d8bef9SDimitry Andric for (int I = 0; I < ArgC; ++I) { 259e8d8bef9SDimitry Andric const bool HaveSpace = ::strchr(ArgV[I], ' '); 260e8d8bef9SDimitry Andric if (I) 261e8d8bef9SDimitry Andric OS << ' '; 262e8d8bef9SDimitry Andric if (HaveSpace) 263e8d8bef9SDimitry Andric OS << '"'; 264e8d8bef9SDimitry Andric OS.write_escaped(ArgV[I]); 265e8d8bef9SDimitry Andric if (HaveSpace) 266e8d8bef9SDimitry Andric OS << '"'; 267e8d8bef9SDimitry Andric } 2680b57cec5SDimitry Andric OS << '\n'; 2690b57cec5SDimitry Andric } 2700b57cec5SDimitry Andric 2710b57cec5SDimitry Andric #if ENABLE_BACKTRACES 2720b57cec5SDimitry Andric static bool RegisterCrashPrinter() { 2730b57cec5SDimitry Andric sys::AddSignalHandler(CrashHandler, nullptr); 2740b57cec5SDimitry Andric return false; 2750b57cec5SDimitry Andric } 2760b57cec5SDimitry Andric #endif 2770b57cec5SDimitry Andric 2780b57cec5SDimitry Andric void llvm::EnablePrettyStackTrace() { 2790b57cec5SDimitry Andric #if ENABLE_BACKTRACES 2800b57cec5SDimitry Andric // The first time this is called, we register the crash printer. 2810b57cec5SDimitry Andric static bool HandlerRegistered = RegisterCrashPrinter(); 2820b57cec5SDimitry Andric (void)HandlerRegistered; 2830b57cec5SDimitry Andric #endif 2840b57cec5SDimitry Andric } 2850b57cec5SDimitry Andric 2860b57cec5SDimitry Andric void llvm::EnablePrettyStackTraceOnSigInfoForThisThread(bool ShouldEnable) { 2870b57cec5SDimitry Andric #if ENABLE_BACKTRACES 2880b57cec5SDimitry Andric if (!ShouldEnable) { 2890b57cec5SDimitry Andric ThreadLocalSigInfoGenerationCounter = 0; 2900b57cec5SDimitry Andric return; 2910b57cec5SDimitry Andric } 2920b57cec5SDimitry Andric 2930b57cec5SDimitry Andric // The first time this is called, we register the SIGINFO handler. 2940b57cec5SDimitry Andric static bool HandlerRegistered = []{ 2950b57cec5SDimitry Andric sys::SetInfoSignalFunction([]{ 2960b57cec5SDimitry Andric GlobalSigInfoGenerationCounter.fetch_add(1, std::memory_order_relaxed); 2970b57cec5SDimitry Andric }); 2980b57cec5SDimitry Andric return false; 2990b57cec5SDimitry Andric }(); 3000b57cec5SDimitry Andric (void)HandlerRegistered; 3010b57cec5SDimitry Andric 3020b57cec5SDimitry Andric // Next, enable it for the current thread. 3030b57cec5SDimitry Andric ThreadLocalSigInfoGenerationCounter = 3040b57cec5SDimitry Andric GlobalSigInfoGenerationCounter.load(std::memory_order_relaxed); 3050b57cec5SDimitry Andric #endif 3060b57cec5SDimitry Andric } 3070b57cec5SDimitry Andric 3080b57cec5SDimitry Andric const void *llvm::SavePrettyStackState() { 3090b57cec5SDimitry Andric #if ENABLE_BACKTRACES 3100b57cec5SDimitry Andric return PrettyStackTraceHead; 3110b57cec5SDimitry Andric #else 3120b57cec5SDimitry Andric return nullptr; 3130b57cec5SDimitry Andric #endif 3140b57cec5SDimitry Andric } 3150b57cec5SDimitry Andric 3160b57cec5SDimitry Andric void llvm::RestorePrettyStackState(const void *Top) { 3170b57cec5SDimitry Andric #if ENABLE_BACKTRACES 3180b57cec5SDimitry Andric PrettyStackTraceHead = 3190b57cec5SDimitry Andric static_cast<PrettyStackTraceEntry *>(const_cast<void *>(Top)); 3200b57cec5SDimitry Andric #endif 3210b57cec5SDimitry Andric } 3220b57cec5SDimitry Andric 3230b57cec5SDimitry Andric void LLVMEnablePrettyStackTrace() { 3240b57cec5SDimitry Andric EnablePrettyStackTrace(); 3250b57cec5SDimitry Andric } 326