xref: /aosp_15_r20/external/llvm/lib/Support/PrettyStackTrace.cpp (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker //===- PrettyStackTrace.cpp - Pretty Crash Handling -----------------------===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker //                     The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker //
10*9880d681SAndroid Build Coastguard Worker // This file defines some helpful functions for dealing with the possibility of
11*9880d681SAndroid Build Coastguard Worker // Unix signals occurring while your program is running.
12*9880d681SAndroid Build Coastguard Worker //
13*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
14*9880d681SAndroid Build Coastguard Worker 
15*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/PrettyStackTrace.h"
16*9880d681SAndroid Build Coastguard Worker #include "llvm-c/ErrorHandling.h"
17*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/SmallString.h"
18*9880d681SAndroid Build Coastguard Worker #include "llvm/Config/config.h"     // Get autoconf configuration settings
19*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/Compiler.h"
20*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/Signals.h"
21*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/Watchdog.h"
22*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/raw_ostream.h"
23*9880d681SAndroid Build Coastguard Worker 
24*9880d681SAndroid Build Coastguard Worker #include <tuple>
25*9880d681SAndroid Build Coastguard Worker 
26*9880d681SAndroid Build Coastguard Worker #ifdef HAVE_CRASHREPORTERCLIENT_H
27*9880d681SAndroid Build Coastguard Worker #include <CrashReporterClient.h>
28*9880d681SAndroid Build Coastguard Worker #endif
29*9880d681SAndroid Build Coastguard Worker 
30*9880d681SAndroid Build Coastguard Worker using namespace llvm;
31*9880d681SAndroid Build Coastguard Worker 
32*9880d681SAndroid Build Coastguard Worker // If backtrace support is not enabled, compile out support for pretty stack
33*9880d681SAndroid Build Coastguard Worker // traces.  This has the secondary effect of not requiring thread local storage
34*9880d681SAndroid Build Coastguard Worker // when backtrace support is disabled.
35*9880d681SAndroid Build Coastguard Worker #if defined(HAVE_BACKTRACE) && defined(ENABLE_BACKTRACES)
36*9880d681SAndroid Build Coastguard Worker 
37*9880d681SAndroid Build Coastguard Worker // We need a thread local pointer to manage the stack of our stack trace
38*9880d681SAndroid Build Coastguard Worker // objects, but we *really* cannot tolerate destructors running and do not want
39*9880d681SAndroid Build Coastguard Worker // to pay any overhead of synchronizing. As a consequence, we use a raw
40*9880d681SAndroid Build Coastguard Worker // thread-local variable.
41*9880d681SAndroid Build Coastguard Worker static LLVM_THREAD_LOCAL PrettyStackTraceEntry *PrettyStackTraceHead = nullptr;
42*9880d681SAndroid Build Coastguard Worker 
43*9880d681SAndroid Build Coastguard Worker namespace llvm {
ReverseStackTrace(PrettyStackTraceEntry * Head)44*9880d681SAndroid Build Coastguard Worker PrettyStackTraceEntry *ReverseStackTrace(PrettyStackTraceEntry *Head) {
45*9880d681SAndroid Build Coastguard Worker   PrettyStackTraceEntry *Prev = nullptr;
46*9880d681SAndroid Build Coastguard Worker   while (Head)
47*9880d681SAndroid Build Coastguard Worker     std::tie(Prev, Head, Head->NextEntry) =
48*9880d681SAndroid Build Coastguard Worker         std::make_tuple(Head, Head->NextEntry, Prev);
49*9880d681SAndroid Build Coastguard Worker   return Prev;
50*9880d681SAndroid Build Coastguard Worker }
51*9880d681SAndroid Build Coastguard Worker }
52*9880d681SAndroid Build Coastguard Worker 
PrintStack(raw_ostream & OS)53*9880d681SAndroid Build Coastguard Worker static void PrintStack(raw_ostream &OS) {
54*9880d681SAndroid Build Coastguard Worker   // Print out the stack in reverse order. To avoid recursion (which is likely
55*9880d681SAndroid Build Coastguard Worker   // to fail if we crashed due to stack overflow), we do an up-front pass to
56*9880d681SAndroid Build Coastguard Worker   // reverse the stack, then print it, then reverse it again.
57*9880d681SAndroid Build Coastguard Worker   unsigned ID = 0;
58*9880d681SAndroid Build Coastguard Worker   PrettyStackTraceEntry *ReversedStack =
59*9880d681SAndroid Build Coastguard Worker       llvm::ReverseStackTrace(PrettyStackTraceHead);
60*9880d681SAndroid Build Coastguard Worker   for (const PrettyStackTraceEntry *Entry = ReversedStack; Entry;
61*9880d681SAndroid Build Coastguard Worker        Entry = Entry->getNextEntry()) {
62*9880d681SAndroid Build Coastguard Worker     OS << ID++ << ".\t";
63*9880d681SAndroid Build Coastguard Worker     sys::Watchdog W(5);
64*9880d681SAndroid Build Coastguard Worker     Entry->print(OS);
65*9880d681SAndroid Build Coastguard Worker   }
66*9880d681SAndroid Build Coastguard Worker   llvm::ReverseStackTrace(ReversedStack);
67*9880d681SAndroid Build Coastguard Worker }
68*9880d681SAndroid Build Coastguard Worker 
69*9880d681SAndroid Build Coastguard Worker /// PrintCurStackTrace - Print the current stack trace to the specified stream.
PrintCurStackTrace(raw_ostream & OS)70*9880d681SAndroid Build Coastguard Worker static void PrintCurStackTrace(raw_ostream &OS) {
71*9880d681SAndroid Build Coastguard Worker   // Don't print an empty trace.
72*9880d681SAndroid Build Coastguard Worker   if (!PrettyStackTraceHead) return;
73*9880d681SAndroid Build Coastguard Worker 
74*9880d681SAndroid Build Coastguard Worker   // If there are pretty stack frames registered, walk and emit them.
75*9880d681SAndroid Build Coastguard Worker   OS << "Stack dump:\n";
76*9880d681SAndroid Build Coastguard Worker 
77*9880d681SAndroid Build Coastguard Worker   PrintStack(OS);
78*9880d681SAndroid Build Coastguard Worker   OS.flush();
79*9880d681SAndroid Build Coastguard Worker }
80*9880d681SAndroid Build Coastguard Worker 
81*9880d681SAndroid Build Coastguard Worker // Integrate with crash reporter libraries.
82*9880d681SAndroid Build Coastguard Worker #if defined (__APPLE__) && HAVE_CRASHREPORTERCLIENT_H
83*9880d681SAndroid Build Coastguard Worker //  If any clients of llvm try to link to libCrashReporterClient.a themselves,
84*9880d681SAndroid Build Coastguard Worker //  only one crash info struct will be used.
85*9880d681SAndroid Build Coastguard Worker extern "C" {
86*9880d681SAndroid Build Coastguard Worker CRASH_REPORTER_CLIENT_HIDDEN
87*9880d681SAndroid Build Coastguard Worker struct crashreporter_annotations_t gCRAnnotations
88*9880d681SAndroid Build Coastguard Worker         __attribute__((section("__DATA," CRASHREPORTER_ANNOTATIONS_SECTION)))
89*9880d681SAndroid Build Coastguard Worker         = { CRASHREPORTER_ANNOTATIONS_VERSION, 0, 0, 0, 0, 0, 0 };
90*9880d681SAndroid Build Coastguard Worker }
91*9880d681SAndroid Build Coastguard Worker #elif defined (__APPLE__) && HAVE_CRASHREPORTER_INFO
92*9880d681SAndroid Build Coastguard Worker static const char *__crashreporter_info__ = 0;
93*9880d681SAndroid Build Coastguard Worker asm(".desc ___crashreporter_info__, 0x10");
94*9880d681SAndroid Build Coastguard Worker #endif
95*9880d681SAndroid Build Coastguard Worker 
96*9880d681SAndroid Build Coastguard Worker 
97*9880d681SAndroid Build Coastguard Worker /// CrashHandler - This callback is run if a fatal signal is delivered to the
98*9880d681SAndroid Build Coastguard Worker /// process, it prints the pretty stack trace.
CrashHandler(void *)99*9880d681SAndroid Build Coastguard Worker static void CrashHandler(void *) {
100*9880d681SAndroid Build Coastguard Worker #ifndef __APPLE__
101*9880d681SAndroid Build Coastguard Worker   // On non-apple systems, just emit the crash stack trace to stderr.
102*9880d681SAndroid Build Coastguard Worker   PrintCurStackTrace(errs());
103*9880d681SAndroid Build Coastguard Worker #else
104*9880d681SAndroid Build Coastguard Worker   // Otherwise, emit to a smallvector of chars, send *that* to stderr, but also
105*9880d681SAndroid Build Coastguard Worker   // put it into __crashreporter_info__.
106*9880d681SAndroid Build Coastguard Worker   SmallString<2048> TmpStr;
107*9880d681SAndroid Build Coastguard Worker   {
108*9880d681SAndroid Build Coastguard Worker     raw_svector_ostream Stream(TmpStr);
109*9880d681SAndroid Build Coastguard Worker     PrintCurStackTrace(Stream);
110*9880d681SAndroid Build Coastguard Worker   }
111*9880d681SAndroid Build Coastguard Worker 
112*9880d681SAndroid Build Coastguard Worker   if (!TmpStr.empty()) {
113*9880d681SAndroid Build Coastguard Worker #ifdef HAVE_CRASHREPORTERCLIENT_H
114*9880d681SAndroid Build Coastguard Worker     // Cast to void to avoid warning.
115*9880d681SAndroid Build Coastguard Worker     (void)CRSetCrashLogMessage(std::string(TmpStr.str()).c_str());
116*9880d681SAndroid Build Coastguard Worker #elif HAVE_CRASHREPORTER_INFO
117*9880d681SAndroid Build Coastguard Worker     __crashreporter_info__ = strdup(std::string(TmpStr.str()).c_str());
118*9880d681SAndroid Build Coastguard Worker #endif
119*9880d681SAndroid Build Coastguard Worker     errs() << TmpStr.str();
120*9880d681SAndroid Build Coastguard Worker   }
121*9880d681SAndroid Build Coastguard Worker 
122*9880d681SAndroid Build Coastguard Worker #endif
123*9880d681SAndroid Build Coastguard Worker }
124*9880d681SAndroid Build Coastguard Worker 
125*9880d681SAndroid Build Coastguard Worker // defined(HAVE_BACKTRACE) && defined(ENABLE_BACKTRACES)
126*9880d681SAndroid Build Coastguard Worker #endif
127*9880d681SAndroid Build Coastguard Worker 
PrettyStackTraceEntry()128*9880d681SAndroid Build Coastguard Worker PrettyStackTraceEntry::PrettyStackTraceEntry() {
129*9880d681SAndroid Build Coastguard Worker #if defined(HAVE_BACKTRACE) && defined(ENABLE_BACKTRACES)
130*9880d681SAndroid Build Coastguard Worker   // Link ourselves.
131*9880d681SAndroid Build Coastguard Worker   NextEntry = PrettyStackTraceHead;
132*9880d681SAndroid Build Coastguard Worker   PrettyStackTraceHead = this;
133*9880d681SAndroid Build Coastguard Worker #endif
134*9880d681SAndroid Build Coastguard Worker }
135*9880d681SAndroid Build Coastguard Worker 
~PrettyStackTraceEntry()136*9880d681SAndroid Build Coastguard Worker PrettyStackTraceEntry::~PrettyStackTraceEntry() {
137*9880d681SAndroid Build Coastguard Worker #if defined(HAVE_BACKTRACE) && defined(ENABLE_BACKTRACES)
138*9880d681SAndroid Build Coastguard Worker   assert(PrettyStackTraceHead == this &&
139*9880d681SAndroid Build Coastguard Worker          "Pretty stack trace entry destruction is out of order");
140*9880d681SAndroid Build Coastguard Worker   PrettyStackTraceHead = NextEntry;
141*9880d681SAndroid Build Coastguard Worker #endif
142*9880d681SAndroid Build Coastguard Worker }
143*9880d681SAndroid Build Coastguard Worker 
print(raw_ostream & OS) const144*9880d681SAndroid Build Coastguard Worker void PrettyStackTraceString::print(raw_ostream &OS) const {
145*9880d681SAndroid Build Coastguard Worker   OS << Str << "\n";
146*9880d681SAndroid Build Coastguard Worker }
147*9880d681SAndroid Build Coastguard Worker 
print(raw_ostream & OS) const148*9880d681SAndroid Build Coastguard Worker void PrettyStackTraceProgram::print(raw_ostream &OS) const {
149*9880d681SAndroid Build Coastguard Worker   OS << "Program arguments: ";
150*9880d681SAndroid Build Coastguard Worker   // Print the argument list.
151*9880d681SAndroid Build Coastguard Worker   for (unsigned i = 0, e = ArgC; i != e; ++i)
152*9880d681SAndroid Build Coastguard Worker     OS << ArgV[i] << ' ';
153*9880d681SAndroid Build Coastguard Worker   OS << '\n';
154*9880d681SAndroid Build Coastguard Worker }
155*9880d681SAndroid Build Coastguard Worker 
156*9880d681SAndroid Build Coastguard Worker #if defined(HAVE_BACKTRACE) && defined(ENABLE_BACKTRACES)
RegisterCrashPrinter()157*9880d681SAndroid Build Coastguard Worker static bool RegisterCrashPrinter() {
158*9880d681SAndroid Build Coastguard Worker   sys::AddSignalHandler(CrashHandler, nullptr);
159*9880d681SAndroid Build Coastguard Worker   return false;
160*9880d681SAndroid Build Coastguard Worker }
161*9880d681SAndroid Build Coastguard Worker #endif
162*9880d681SAndroid Build Coastguard Worker 
EnablePrettyStackTrace()163*9880d681SAndroid Build Coastguard Worker void llvm::EnablePrettyStackTrace() {
164*9880d681SAndroid Build Coastguard Worker #if defined(HAVE_BACKTRACE) && defined(ENABLE_BACKTRACES)
165*9880d681SAndroid Build Coastguard Worker   // The first time this is called, we register the crash printer.
166*9880d681SAndroid Build Coastguard Worker   static bool HandlerRegistered = RegisterCrashPrinter();
167*9880d681SAndroid Build Coastguard Worker   (void)HandlerRegistered;
168*9880d681SAndroid Build Coastguard Worker #endif
169*9880d681SAndroid Build Coastguard Worker }
170*9880d681SAndroid Build Coastguard Worker 
SavePrettyStackState()171*9880d681SAndroid Build Coastguard Worker const void *llvm::SavePrettyStackState() {
172*9880d681SAndroid Build Coastguard Worker #if defined(HAVE_BACKTRACE) && defined(ENABLE_BACKTRACES)
173*9880d681SAndroid Build Coastguard Worker   return PrettyStackTraceHead;
174*9880d681SAndroid Build Coastguard Worker #else
175*9880d681SAndroid Build Coastguard Worker   return nullptr;
176*9880d681SAndroid Build Coastguard Worker #endif
177*9880d681SAndroid Build Coastguard Worker }
178*9880d681SAndroid Build Coastguard Worker 
RestorePrettyStackState(const void * Top)179*9880d681SAndroid Build Coastguard Worker void llvm::RestorePrettyStackState(const void *Top) {
180*9880d681SAndroid Build Coastguard Worker #if defined(HAVE_BACKTRACE) && defined(ENABLE_BACKTRACES)
181*9880d681SAndroid Build Coastguard Worker   PrettyStackTraceHead =
182*9880d681SAndroid Build Coastguard Worker       static_cast<PrettyStackTraceEntry *>(const_cast<void *>(Top));
183*9880d681SAndroid Build Coastguard Worker #endif
184*9880d681SAndroid Build Coastguard Worker }
185*9880d681SAndroid Build Coastguard Worker 
LLVMEnablePrettyStackTrace()186*9880d681SAndroid Build Coastguard Worker void LLVMEnablePrettyStackTrace() {
187*9880d681SAndroid Build Coastguard Worker   EnablePrettyStackTrace();
188*9880d681SAndroid Build Coastguard Worker }
189