LLVM  3.7.0
PrettyStackTrace.cpp
Go to the documentation of this file.
1 //===- PrettyStackTrace.cpp - Pretty Crash Handling -----------------------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file defines some helpful functions for dealing with the possibility of
11 // Unix signals occurring while your program is running.
12 //
13 //===----------------------------------------------------------------------===//
14 
16 #include "llvm-c/Core.h"
17 #include "llvm/ADT/SmallString.h"
18 #include "llvm/Config/config.h" // Get autoconf configuration settings
19 #include "llvm/Support/Compiler.h"
20 #include "llvm/Support/Signals.h"
21 #include "llvm/Support/Watchdog.h"
23 
24 #ifdef HAVE_CRASHREPORTERCLIENT_H
25 #include <CrashReporterClient.h>
26 #endif
27 
28 using namespace llvm;
29 
30 // If backtrace support is not enabled, compile out support for pretty stack
31 // traces. This has the secondary effect of not requiring thread local storage
32 // when backtrace support is disabled.
33 #if defined(HAVE_BACKTRACE) && defined(ENABLE_BACKTRACES)
34 
35 // We need a thread local pointer to manage the stack of our stack trace
36 // objects, but we *really* cannot tolerate destructors running and do not want
37 // to pay any overhead of synchronizing. As a consequence, we use a raw
38 // thread-local variable.
40  nullptr;
41 
42 static unsigned PrintStack(const PrettyStackTraceEntry *Entry, raw_ostream &OS){
43  unsigned NextID = 0;
44  if (Entry->getNextEntry())
45  NextID = PrintStack(Entry->getNextEntry(), OS);
46  OS << NextID << ".\t";
47  {
48  sys::Watchdog W(5);
49  Entry->print(OS);
50  }
51 
52  return NextID+1;
53 }
54 
55 /// PrintCurStackTrace - Print the current stack trace to the specified stream.
56 static void PrintCurStackTrace(raw_ostream &OS) {
57  // Don't print an empty trace.
58  if (!PrettyStackTraceHead) return;
59 
60  // If there are pretty stack frames registered, walk and emit them.
61  OS << "Stack dump:\n";
62 
64  OS.flush();
65 }
66 
67 // Integrate with crash reporter libraries.
68 #if defined (__APPLE__) && HAVE_CRASHREPORTERCLIENT_H
69 // If any clients of llvm try to link to libCrashReporterClient.a themselves,
70 // only one crash info struct will be used.
71 extern "C" {
72 CRASH_REPORTER_CLIENT_HIDDEN
73 struct crashreporter_annotations_t gCRAnnotations
74  __attribute__((section("__DATA," CRASHREPORTER_ANNOTATIONS_SECTION)))
75  = { CRASHREPORTER_ANNOTATIONS_VERSION, 0, 0, 0, 0, 0, 0 };
76 }
77 #elif defined (__APPLE__) && HAVE_CRASHREPORTER_INFO
78 static const char *__crashreporter_info__ = 0;
79 asm(".desc ___crashreporter_info__, 0x10");
80 #endif
81 
82 
83 /// CrashHandler - This callback is run if a fatal signal is delivered to the
84 /// process, it prints the pretty stack trace.
85 static void CrashHandler(void *) {
86 #ifndef __APPLE__
87  // On non-apple systems, just emit the crash stack trace to stderr.
89 #else
90  // Otherwise, emit to a smallvector of chars, send *that* to stderr, but also
91  // put it into __crashreporter_info__.
92  SmallString<2048> TmpStr;
93  {
94  raw_svector_ostream Stream(TmpStr);
95  PrintCurStackTrace(Stream);
96  }
97 
98  if (!TmpStr.empty()) {
99 #ifdef HAVE_CRASHREPORTERCLIENT_H
100  // Cast to void to avoid warning.
101  (void)CRSetCrashLogMessage(std::string(TmpStr.str()).c_str());
102 #elif HAVE_CRASHREPORTER_INFO
103  __crashreporter_info__ = strdup(std::string(TmpStr.str()).c_str());
104 #endif
105  errs() << TmpStr.str();
106  }
107 
108 #endif
109 }
110 
111 // defined(HAVE_BACKTRACE) && defined(ENABLE_BACKTRACES)
112 #endif
113 
115 #if defined(HAVE_BACKTRACE) && defined(ENABLE_BACKTRACES)
116  // Link ourselves.
117  NextEntry = PrettyStackTraceHead;
118  PrettyStackTraceHead = this;
119 #endif
120 }
121 
123 #if defined(HAVE_BACKTRACE) && defined(ENABLE_BACKTRACES)
124  assert(PrettyStackTraceHead == this &&
125  "Pretty stack trace entry destruction is out of order");
127 #endif
128 }
129 
131  OS << Str << "\n";
132 }
133 
135  OS << "Program arguments: ";
136  // Print the argument list.
137  for (unsigned i = 0, e = ArgC; i != e; ++i)
138  OS << ArgV[i] << ' ';
139  OS << '\n';
140 }
141 
142 #if defined(HAVE_BACKTRACE) && defined(ENABLE_BACKTRACES)
143 static bool RegisterCrashPrinter() {
145  return false;
146 }
147 #endif
148 
150 #if defined(HAVE_BACKTRACE) && defined(ENABLE_BACKTRACES)
151  // The first time this is called, we register the crash printer.
152  static bool HandlerRegistered = RegisterCrashPrinter();
153  (void)HandlerRegistered;
154 #endif
155 }
156 
159 }
raw_ostream & errs()
This returns a reference to a raw_ostream for standard error.
A raw_ostream that writes to an SmallVector or SmallString.
Definition: raw_ostream.h:488
This class provides an abstraction for a timeout around an operation that must complete in a given am...
Definition: Watchdog.h:26
void EnablePrettyStackTrace()
const PrettyStackTraceEntry * getNextEntry() const
getNextEntry - Return the next entry in the list of frames.
bool LLVM_ATTRIBUTE_UNUSED_RESULT empty() const
Definition: SmallVector.h:57
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
Definition: SmallString.h:25
#define LLVM_THREAD_LOCAL
LLVM_THREAD_LOCAL
Definition: Compiler.h:370
static LLVM_THREAD_LOCAL const PrettyStackTraceEntry * PrettyStackTraceHead
void LLVMEnablePrettyStackTrace()
Enable LLVM's built-in stack trace code.
static void PrintCurStackTrace(raw_ostream &OS)
PrintCurStackTrace - Print the current stack trace to the specified stream.
PrettyStackTraceEntry - This class is used to represent a frame of the "pretty" stack trace that is d...
SmallVectorImpl< T >::const_pointer c_str(SmallVectorImpl< T > &str)
static unsigned PrintStack(const PrettyStackTraceEntry *Entry, raw_ostream &OS)
static bool RegisterCrashPrinter()
void print(raw_ostream &OS) const override
print - Emit information about this stack frame to OS.
StringRef str() const
Explicit conversion to StringRef.
Definition: SmallString.h:267
virtual void print(raw_ostream &OS) const =0
print - Emit information about this stack frame to OS.
static void CrashHandler(void *)
CrashHandler - This callback is run if a fatal signal is delivered to the process, it prints the pretty stack trace.
void print(raw_ostream &OS) const override
print - Emit information about this stack frame to OS.
__attribute__((weak)) dfsan_label dfsan_create_label(const char *desc
This class implements an extremely fast bulk output stream that can only output to a stream...
Definition: raw_ostream.h:38
void AddSignalHandler(void(*FnPtr)(void *), void *Cookie)
AddSignalHandler - Add a function to be called when an abort/kill signal is delivered to the process...