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.
67*fe013be4SDimitry Andric static volatile std::atomic<unsigned> GlobalSigInfoGenerationCounter = 1;
680b57cec5SDimitry Andric static LLVM_THREAD_LOCAL unsigned ThreadLocalSigInfoGenerationCounter = 0;
690b57cec5SDimitry Andric 
700b57cec5SDimitry Andric namespace llvm {
ReverseStackTrace(PrettyStackTraceEntry * Head)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 
PrintStack(raw_ostream & OS)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
PrintCurStackTrace(raw_ostream & OS)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;
setCrashLogMessage(const char * msg)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>;
1468bcb0991SDimitry Andric using CrashHandlerStringStorage =
1478bcb0991SDimitry Andric     std::aligned_storage<sizeof(CrashHandlerString),
1488bcb0991SDimitry Andric                          alignof(CrashHandlerString)>::type;
1498bcb0991SDimitry Andric static CrashHandlerStringStorage crashHandlerStringStorage;
1508bcb0991SDimitry Andric #endif
1518bcb0991SDimitry Andric 
1528bcb0991SDimitry Andric /// This callback is run if a fatal signal is delivered to the process, it
1538bcb0991SDimitry Andric /// prints the pretty stack trace.
CrashHandler(void *)1540b57cec5SDimitry Andric static void CrashHandler(void *) {
1555ffd83dbSDimitry Andric   errs() << BugReportMsg ;
1565ffd83dbSDimitry Andric 
1570b57cec5SDimitry Andric #ifndef __APPLE__
1580b57cec5SDimitry Andric   // On non-apple systems, just emit the crash stack trace to stderr.
1590b57cec5SDimitry Andric   PrintCurStackTrace(errs());
1600b57cec5SDimitry Andric #else
1618bcb0991SDimitry Andric   // Emit the crash stack trace to a SmallString, put it where the system crash
1628bcb0991SDimitry Andric   // handling will find it, and also send it to stderr.
1638bcb0991SDimitry Andric   //
1648bcb0991SDimitry Andric   // The SmallString is fairly large in the hope that we don't allocate (we're
1658bcb0991SDimitry Andric   // handling a fatal signal, something is already pretty wrong, allocation
1668bcb0991SDimitry Andric   // might not work). Further, we don't use a magic static in case that's also
1678bcb0991SDimitry Andric   // borked. We leak any allocation that does occur because the program is about
1688bcb0991SDimitry Andric   // to die anyways. This is technically racy if we were handling two fatal
1698bcb0991SDimitry Andric   // signals, however if we're in that situation a race is the least of our
1708bcb0991SDimitry Andric   // worries.
1718bcb0991SDimitry Andric   auto &crashHandlerString =
1728bcb0991SDimitry Andric       *new (&crashHandlerStringStorage) CrashHandlerString;
1738bcb0991SDimitry Andric 
1748bcb0991SDimitry Andric   // If we crash while trying to print the stack trace, we still want the system
1758bcb0991SDimitry Andric   // crash handling to have some partial information. That'll work out as long
1768bcb0991SDimitry Andric   // as the SmallString doesn't allocate. If it does allocate then the system
1778bcb0991SDimitry Andric   // crash handling will see some garbage because the inline buffer now contains
1788bcb0991SDimitry Andric   // a pointer.
1798bcb0991SDimitry Andric   setCrashLogMessage(crashHandlerString.c_str());
1808bcb0991SDimitry Andric 
1810b57cec5SDimitry Andric   {
1828bcb0991SDimitry Andric     raw_svector_ostream Stream(crashHandlerString);
1830b57cec5SDimitry Andric     PrintCurStackTrace(Stream);
1840b57cec5SDimitry Andric   }
1850b57cec5SDimitry Andric 
1868bcb0991SDimitry Andric   if (!crashHandlerString.empty()) {
1878bcb0991SDimitry Andric     setCrashLogMessage(crashHandlerString.c_str());
1888bcb0991SDimitry Andric     errs() << crashHandlerString.str();
1898bcb0991SDimitry Andric   } else
1908bcb0991SDimitry Andric     setCrashLogMessage("No crash information.");
1910b57cec5SDimitry Andric #endif
1920b57cec5SDimitry Andric }
1930b57cec5SDimitry Andric 
printForSigInfoIfNeeded()1940b57cec5SDimitry Andric static void printForSigInfoIfNeeded() {
1950b57cec5SDimitry Andric   unsigned CurrentSigInfoGeneration =
1960b57cec5SDimitry Andric       GlobalSigInfoGenerationCounter.load(std::memory_order_relaxed);
1970b57cec5SDimitry Andric   if (ThreadLocalSigInfoGenerationCounter == 0 ||
1980b57cec5SDimitry Andric       ThreadLocalSigInfoGenerationCounter == CurrentSigInfoGeneration) {
1990b57cec5SDimitry Andric     return;
2000b57cec5SDimitry Andric   }
2010b57cec5SDimitry Andric 
2020b57cec5SDimitry Andric   PrintCurStackTrace(errs());
2030b57cec5SDimitry Andric   ThreadLocalSigInfoGenerationCounter = CurrentSigInfoGeneration;
2040b57cec5SDimitry Andric }
2050b57cec5SDimitry Andric 
2060b57cec5SDimitry Andric #endif // ENABLE_BACKTRACES
2070b57cec5SDimitry Andric 
setBugReportMsg(const char * Msg)2085ffd83dbSDimitry Andric void llvm::setBugReportMsg(const char *Msg) {
2095ffd83dbSDimitry Andric   BugReportMsg = Msg;
2105ffd83dbSDimitry Andric }
2115ffd83dbSDimitry Andric 
getBugReportMsg()2125ffd83dbSDimitry Andric const char *llvm::getBugReportMsg() {
2135ffd83dbSDimitry Andric   return BugReportMsg;
2145ffd83dbSDimitry Andric }
2155ffd83dbSDimitry Andric 
PrettyStackTraceEntry()2160b57cec5SDimitry Andric PrettyStackTraceEntry::PrettyStackTraceEntry() {
2170b57cec5SDimitry Andric #if ENABLE_BACKTRACES
2180b57cec5SDimitry Andric   // Handle SIGINFO first, because we haven't finished constructing yet.
2190b57cec5SDimitry Andric   printForSigInfoIfNeeded();
2200b57cec5SDimitry Andric   // Link ourselves.
2210b57cec5SDimitry Andric   NextEntry = PrettyStackTraceHead;
2220b57cec5SDimitry Andric   PrettyStackTraceHead = this;
2230b57cec5SDimitry Andric #endif
2240b57cec5SDimitry Andric }
2250b57cec5SDimitry Andric 
~PrettyStackTraceEntry()2260b57cec5SDimitry Andric PrettyStackTraceEntry::~PrettyStackTraceEntry() {
2270b57cec5SDimitry Andric #if ENABLE_BACKTRACES
2280b57cec5SDimitry Andric   assert(PrettyStackTraceHead == this &&
2290b57cec5SDimitry Andric          "Pretty stack trace entry destruction is out of order");
2300b57cec5SDimitry Andric   PrettyStackTraceHead = NextEntry;
2310b57cec5SDimitry Andric   // Handle SIGINFO first, because we already started destructing.
2320b57cec5SDimitry Andric   printForSigInfoIfNeeded();
2330b57cec5SDimitry Andric #endif
2340b57cec5SDimitry Andric }
2350b57cec5SDimitry Andric 
print(raw_ostream & OS) const2360b57cec5SDimitry Andric void PrettyStackTraceString::print(raw_ostream &OS) const { OS << Str << "\n"; }
2370b57cec5SDimitry Andric 
PrettyStackTraceFormat(const char * Format,...)2380b57cec5SDimitry Andric PrettyStackTraceFormat::PrettyStackTraceFormat(const char *Format, ...) {
2390b57cec5SDimitry Andric   va_list AP;
2400b57cec5SDimitry Andric   va_start(AP, Format);
2410b57cec5SDimitry Andric   const int SizeOrError = vsnprintf(nullptr, 0, Format, AP);
2420b57cec5SDimitry Andric   va_end(AP);
2430b57cec5SDimitry Andric   if (SizeOrError < 0) {
2440b57cec5SDimitry Andric     return;
2450b57cec5SDimitry Andric   }
2460b57cec5SDimitry Andric 
2470b57cec5SDimitry Andric   const int Size = SizeOrError + 1; // '\0'
2480b57cec5SDimitry Andric   Str.resize(Size);
2490b57cec5SDimitry Andric   va_start(AP, Format);
2500b57cec5SDimitry Andric   vsnprintf(Str.data(), Size, Format, AP);
2510b57cec5SDimitry Andric   va_end(AP);
2520b57cec5SDimitry Andric }
2530b57cec5SDimitry Andric 
print(raw_ostream & OS) const2540b57cec5SDimitry Andric void PrettyStackTraceFormat::print(raw_ostream &OS) const { OS << Str << "\n"; }
2550b57cec5SDimitry Andric 
print(raw_ostream & OS) const2560b57cec5SDimitry Andric void PrettyStackTraceProgram::print(raw_ostream &OS) const {
2570b57cec5SDimitry Andric   OS << "Program arguments: ";
2580b57cec5SDimitry Andric   // Print the argument list.
259e8d8bef9SDimitry Andric   for (int I = 0; I < ArgC; ++I) {
260e8d8bef9SDimitry Andric     const bool HaveSpace = ::strchr(ArgV[I], ' ');
261e8d8bef9SDimitry Andric     if (I)
262e8d8bef9SDimitry Andric       OS << ' ';
263e8d8bef9SDimitry Andric     if (HaveSpace)
264e8d8bef9SDimitry Andric       OS << '"';
265e8d8bef9SDimitry Andric     OS.write_escaped(ArgV[I]);
266e8d8bef9SDimitry Andric     if (HaveSpace)
267e8d8bef9SDimitry Andric       OS << '"';
268e8d8bef9SDimitry Andric   }
2690b57cec5SDimitry Andric   OS << '\n';
2700b57cec5SDimitry Andric }
2710b57cec5SDimitry Andric 
2720b57cec5SDimitry Andric #if ENABLE_BACKTRACES
RegisterCrashPrinter()2730b57cec5SDimitry Andric static bool RegisterCrashPrinter() {
2740b57cec5SDimitry Andric   sys::AddSignalHandler(CrashHandler, nullptr);
2750b57cec5SDimitry Andric   return false;
2760b57cec5SDimitry Andric }
2770b57cec5SDimitry Andric #endif
2780b57cec5SDimitry Andric 
EnablePrettyStackTrace()2790b57cec5SDimitry Andric void llvm::EnablePrettyStackTrace() {
2800b57cec5SDimitry Andric #if ENABLE_BACKTRACES
2810b57cec5SDimitry Andric   // The first time this is called, we register the crash printer.
2820b57cec5SDimitry Andric   static bool HandlerRegistered = RegisterCrashPrinter();
2830b57cec5SDimitry Andric   (void)HandlerRegistered;
2840b57cec5SDimitry Andric #endif
2850b57cec5SDimitry Andric }
2860b57cec5SDimitry Andric 
EnablePrettyStackTraceOnSigInfoForThisThread(bool ShouldEnable)2870b57cec5SDimitry Andric void llvm::EnablePrettyStackTraceOnSigInfoForThisThread(bool ShouldEnable) {
2880b57cec5SDimitry Andric #if ENABLE_BACKTRACES
2890b57cec5SDimitry Andric   if (!ShouldEnable) {
2900b57cec5SDimitry Andric     ThreadLocalSigInfoGenerationCounter = 0;
2910b57cec5SDimitry Andric     return;
2920b57cec5SDimitry Andric   }
2930b57cec5SDimitry Andric 
2940b57cec5SDimitry Andric   // The first time this is called, we register the SIGINFO handler.
2950b57cec5SDimitry Andric   static bool HandlerRegistered = []{
2960b57cec5SDimitry Andric     sys::SetInfoSignalFunction([]{
2970b57cec5SDimitry Andric       GlobalSigInfoGenerationCounter.fetch_add(1, std::memory_order_relaxed);
2980b57cec5SDimitry Andric     });
2990b57cec5SDimitry Andric     return false;
3000b57cec5SDimitry Andric   }();
3010b57cec5SDimitry Andric   (void)HandlerRegistered;
3020b57cec5SDimitry Andric 
3030b57cec5SDimitry Andric   // Next, enable it for the current thread.
3040b57cec5SDimitry Andric   ThreadLocalSigInfoGenerationCounter =
3050b57cec5SDimitry Andric       GlobalSigInfoGenerationCounter.load(std::memory_order_relaxed);
3060b57cec5SDimitry Andric #endif
3070b57cec5SDimitry Andric }
3080b57cec5SDimitry Andric 
SavePrettyStackState()3090b57cec5SDimitry Andric const void *llvm::SavePrettyStackState() {
3100b57cec5SDimitry Andric #if ENABLE_BACKTRACES
3110b57cec5SDimitry Andric   return PrettyStackTraceHead;
3120b57cec5SDimitry Andric #else
3130b57cec5SDimitry Andric   return nullptr;
3140b57cec5SDimitry Andric #endif
3150b57cec5SDimitry Andric }
3160b57cec5SDimitry Andric 
RestorePrettyStackState(const void * Top)3170b57cec5SDimitry Andric void llvm::RestorePrettyStackState(const void *Top) {
3180b57cec5SDimitry Andric #if ENABLE_BACKTRACES
3190b57cec5SDimitry Andric   PrettyStackTraceHead =
3200b57cec5SDimitry Andric       static_cast<PrettyStackTraceEntry *>(const_cast<void *>(Top));
3210b57cec5SDimitry Andric #endif
3220b57cec5SDimitry Andric }
3230b57cec5SDimitry Andric 
LLVMEnablePrettyStackTrace()3240b57cec5SDimitry Andric void LLVMEnablePrettyStackTrace() {
3250b57cec5SDimitry Andric   EnablePrettyStackTrace();
3260b57cec5SDimitry Andric }
327