LLVM  14.0.0git
PrettyStackTrace.cpp
Go to the documentation of this file.
1 //===- PrettyStackTrace.cpp - Pretty Crash Handling -----------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file defines some helpful functions for dealing with the possibility of
10 // Unix signals occurring while your program is running.
11 //
12 //===----------------------------------------------------------------------===//
13 
15 #include "llvm-c/ErrorHandling.h"
16 #include "llvm/ADT/SmallString.h"
17 #include "llvm/Config/config.h"
18 #include "llvm/Support/Compiler.h"
20 #include "llvm/Support/Signals.h"
21 #include "llvm/Support/Watchdog.h"
23 
24 #include <atomic>
25 #include <cassert>
26 #include <cstdarg>
27 #include <cstdio>
28 #include <cstring>
29 #include <tuple>
30 
31 #ifdef HAVE_CRASHREPORTERCLIENT_H
32 #include <CrashReporterClient.h>
33 #endif
34 
35 using namespace llvm;
36 
37 static const char *BugReportMsg =
38  "PLEASE submit a bug report to " BUG_REPORT_URL
39  " and include the crash backtrace.\n";
40 
41 // If backtrace support is not enabled, compile out support for pretty stack
42 // traces. This has the secondary effect of not requiring thread local storage
43 // when backtrace support is disabled.
44 #if ENABLE_BACKTRACES
45 
46 // We need a thread local pointer to manage the stack of our stack trace
47 // objects, but we *really* cannot tolerate destructors running and do not want
48 // to pay any overhead of synchronizing. As a consequence, we use a raw
49 // thread-local variable.
51 
52 // The use of 'volatile' here is to ensure that any particular thread always
53 // reloads the value of the counter. The 'std::atomic' allows us to specify that
54 // this variable is accessed in an unsychronized way (it's not actually
55 // synchronizing). This does technically mean that the value may not appear to
56 // be the same across threads running simultaneously on different CPUs, but in
57 // practice the worst that will happen is that we won't print a stack trace when
58 // we could have.
59 //
60 // This is initialized to 1 because 0 is used as a sentinel for "not enabled on
61 // the current thread". If the user happens to overflow an 'unsigned' with
62 // SIGINFO requests, it's possible that some threads will stop responding to it,
63 // but the program won't crash.
64 static volatile std::atomic<unsigned> GlobalSigInfoGenerationCounter =
65  ATOMIC_VAR_INIT(1);
67 
68 namespace llvm {
70  PrettyStackTraceEntry *Prev = nullptr;
71  while (Head)
72  std::tie(Prev, Head, Head->NextEntry) =
73  std::make_tuple(Head, Head->NextEntry, Prev);
74  return Prev;
75 }
76 } // namespace llvm
77 
78 static void PrintStack(raw_ostream &OS) {
79  // Print out the stack in reverse order. To avoid recursion (which is likely
80  // to fail if we crashed due to stack overflow), we do an up-front pass to
81  // reverse the stack, then print it, then reverse it again.
82  unsigned ID = 0;
84  nullptr};
85  PrettyStackTraceEntry *ReversedStack = ReverseStackTrace(SavedStack.get());
86  for (const PrettyStackTraceEntry *Entry = ReversedStack; Entry;
87  Entry = Entry->getNextEntry()) {
88  OS << ID++ << ".\t";
89  sys::Watchdog W(5);
90  Entry->print(OS);
91  }
92  llvm::ReverseStackTrace(ReversedStack);
93 }
94 
95 /// Print the current stack trace to the specified stream.
96 ///
97 /// Marked NOINLINE so it can be called from debuggers.
99 static void PrintCurStackTrace(raw_ostream &OS) {
100  // Don't print an empty trace.
101  if (!PrettyStackTraceHead) return;
102 
103  // If there are pretty stack frames registered, walk and emit them.
104  OS << "Stack dump:\n";
105 
106  PrintStack(OS);
107  OS.flush();
108 }
109 
110 // Integrate with crash reporter libraries.
111 #if defined (__APPLE__) && defined(HAVE_CRASHREPORTERCLIENT_H)
112 // If any clients of llvm try to link to libCrashReporterClient.a themselves,
113 // only one crash info struct will be used.
114 extern "C" {
115 CRASH_REPORTER_CLIENT_HIDDEN
116 struct crashreporter_annotations_t gCRAnnotations
117  __attribute__((section("__DATA," CRASHREPORTER_ANNOTATIONS_SECTION)))
118 #if CRASHREPORTER_ANNOTATIONS_VERSION < 5
119  = { CRASHREPORTER_ANNOTATIONS_VERSION, 0, 0, 0, 0, 0, 0 };
120 #else
121  = { CRASHREPORTER_ANNOTATIONS_VERSION, 0, 0, 0, 0, 0, 0, 0 };
122 #endif
123 }
124 #elif defined(__APPLE__) && HAVE_CRASHREPORTER_INFO
125 extern "C" const char *__crashreporter_info__
126  __attribute__((visibility("hidden"))) = 0;
127 asm(".desc ___crashreporter_info__, 0x10");
128 #endif
129 
130 static void setCrashLogMessage(const char *msg) LLVM_ATTRIBUTE_UNUSED;
131 static void setCrashLogMessage(const char *msg) {
132 #ifdef HAVE_CRASHREPORTERCLIENT_H
133  (void)CRSetCrashLogMessage(msg);
134 #elif HAVE_CRASHREPORTER_INFO
135  __crashreporter_info__ = msg;
136 #endif
137  // Don't reorder subsequent operations: whatever comes after might crash and
138  // we want the system crash handling to see the message we just set.
139  std::atomic_signal_fence(std::memory_order_seq_cst);
140 }
141 
142 #ifdef __APPLE__
143 using CrashHandlerString = SmallString<2048>;
144 using CrashHandlerStringStorage =
145  std::aligned_storage<sizeof(CrashHandlerString),
146  alignof(CrashHandlerString)>::type;
147 static CrashHandlerStringStorage crashHandlerStringStorage;
148 #endif
149 
150 /// This callback is run if a fatal signal is delivered to the process, it
151 /// prints the pretty stack trace.
152 static void CrashHandler(void *) {
153  errs() << BugReportMsg ;
154 
155 #ifndef __APPLE__
156  // On non-apple systems, just emit the crash stack trace to stderr.
158 #else
159  // Emit the crash stack trace to a SmallString, put it where the system crash
160  // handling will find it, and also send it to stderr.
161  //
162  // The SmallString is fairly large in the hope that we don't allocate (we're
163  // handling a fatal signal, something is already pretty wrong, allocation
164  // might not work). Further, we don't use a magic static in case that's also
165  // borked. We leak any allocation that does occur because the program is about
166  // to die anyways. This is technically racy if we were handling two fatal
167  // signals, however if we're in that situation a race is the least of our
168  // worries.
169  auto &crashHandlerString =
170  *new (&crashHandlerStringStorage) CrashHandlerString;
171 
172  // If we crash while trying to print the stack trace, we still want the system
173  // crash handling to have some partial information. That'll work out as long
174  // as the SmallString doesn't allocate. If it does allocate then the system
175  // crash handling will see some garbage because the inline buffer now contains
176  // a pointer.
177  setCrashLogMessage(crashHandlerString.c_str());
178 
179  {
180  raw_svector_ostream Stream(crashHandlerString);
181  PrintCurStackTrace(Stream);
182  }
183 
184  if (!crashHandlerString.empty()) {
185  setCrashLogMessage(crashHandlerString.c_str());
186  errs() << crashHandlerString.str();
187  } else
188  setCrashLogMessage("No crash information.");
189 #endif
190 }
191 
192 static void printForSigInfoIfNeeded() {
193  unsigned CurrentSigInfoGeneration =
194  GlobalSigInfoGenerationCounter.load(std::memory_order_relaxed);
196  ThreadLocalSigInfoGenerationCounter == CurrentSigInfoGeneration) {
197  return;
198  }
199 
201  ThreadLocalSigInfoGenerationCounter = CurrentSigInfoGeneration;
202 }
203 
204 #endif // ENABLE_BACKTRACES
205 
206 void llvm::setBugReportMsg(const char *Msg) {
207  BugReportMsg = Msg;
208 }
209 
210 const char *llvm::getBugReportMsg() {
211  return BugReportMsg;
212 }
213 
215 #if ENABLE_BACKTRACES
216  // Handle SIGINFO first, because we haven't finished constructing yet.
218  // Link ourselves.
219  NextEntry = PrettyStackTraceHead;
220  PrettyStackTraceHead = this;
221 #endif
222 }
223 
225 #if ENABLE_BACKTRACES
226  assert(PrettyStackTraceHead == this &&
227  "Pretty stack trace entry destruction is out of order");
228  PrettyStackTraceHead = NextEntry;
229  // Handle SIGINFO first, because we already started destructing.
231 #endif
232 }
233 
234 void PrettyStackTraceString::print(raw_ostream &OS) const { OS << Str << "\n"; }
235 
237  va_list AP;
238  va_start(AP, Format);
239  const int SizeOrError = vsnprintf(nullptr, 0, Format, AP);
240  va_end(AP);
241  if (SizeOrError < 0) {
242  return;
243  }
244 
245  const int Size = SizeOrError + 1; // '\0'
246  Str.resize(Size);
247  va_start(AP, Format);
248  vsnprintf(Str.data(), Size, Format, AP);
249  va_end(AP);
250 }
251 
252 void PrettyStackTraceFormat::print(raw_ostream &OS) const { OS << Str << "\n"; }
253 
255  OS << "Program arguments: ";
256  // Print the argument list.
257  for (int I = 0; I < ArgC; ++I) {
258  const bool HaveSpace = ::strchr(ArgV[I], ' ');
259  if (I)
260  OS << ' ';
261  if (HaveSpace)
262  OS << '"';
263  OS.write_escaped(ArgV[I]);
264  if (HaveSpace)
265  OS << '"';
266  }
267  OS << '\n';
268 }
269 
270 #if ENABLE_BACKTRACES
271 static bool RegisterCrashPrinter() {
273  return false;
274 }
275 #endif
276 
278 #if ENABLE_BACKTRACES
279  // The first time this is called, we register the crash printer.
280  static bool HandlerRegistered = RegisterCrashPrinter();
281  (void)HandlerRegistered;
282 #endif
283 }
284 
286 #if ENABLE_BACKTRACES
287  if (!ShouldEnable) {
289  return;
290  }
291 
292  // The first time this is called, we register the SIGINFO handler.
293  static bool HandlerRegistered = []{
295  GlobalSigInfoGenerationCounter.fetch_add(1, std::memory_order_relaxed);
296  });
297  return false;
298  }();
299  (void)HandlerRegistered;
300 
301  // Next, enable it for the current thread.
303  GlobalSigInfoGenerationCounter.load(std::memory_order_relaxed);
304 #endif
305 }
306 
308 #if ENABLE_BACKTRACES
309  return PrettyStackTraceHead;
310 #else
311  return nullptr;
312 #endif
313 }
314 
315 void llvm::RestorePrettyStackState(const void *Top) {
316 #if ENABLE_BACKTRACES
318  static_cast<PrettyStackTraceEntry *>(const_cast<void *>(Top));
319 #endif
320 }
321 
324 }
llvm::Check::Size
@ Size
Definition: FileCheck.h:73
llvm::EnablePrettyStackTraceOnSigInfoForThisThread
void EnablePrettyStackTraceOnSigInfoForThisThread(bool ShouldEnable=true)
Enables (or disables) dumping a "pretty" stack trace when the user sends SIGINFO or SIGUSR1 to the cu...
Definition: PrettyStackTrace.cpp:285
Signals.h
llvm
---------------------— PointerInfo ------------------------------------—
Definition: AllocatorList.h:23
BugReportMsg
static const char * BugReportMsg
Definition: PrettyStackTrace.cpp:37
llvm::RISCVFenceField::W
@ W
Definition: RISCVBaseInfo.h:199
llvm::raw_ostream::write_escaped
raw_ostream & write_escaped(StringRef Str, bool UseHexEscapes=false)
Output Str, turning '\', '\t', ' ', '"', and anything that doesn't satisfy llvm::isPrint into an esca...
Definition: raw_ostream.cpp:163
CrashHandler
static void CrashHandler(void *)
This callback is run if a fatal signal is delivered to the process, it prints the pretty stack trace.
Definition: PrettyStackTrace.cpp:152
llvm::errs
raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
Definition: raw_ostream.cpp:892
Watchdog.h
LLVM_ATTRIBUTE_UNUSED
#define LLVM_ATTRIBUTE_UNUSED
Definition: Compiler.h:188
llvm::RestorePrettyStackState
void RestorePrettyStackState(const void *State)
Restores the topmost element of the "pretty" stack state to State, which should come from a previous ...
Definition: PrettyStackTrace.cpp:315
llvm::PrettyStackTraceEntry
PrettyStackTraceEntry - This class is used to represent a frame of the "pretty" stack trace that is d...
Definition: PrettyStackTrace.h:52
LLVM_THREAD_LOCAL
#define LLVM_THREAD_LOCAL
\macro LLVM_THREAD_LOCAL A thread-local storage specifier which can be used with globals,...
Definition: Compiler.h:526
SmallString.h
llvm::sys::SetInfoSignalFunction
void SetInfoSignalFunction(void(*Handler)())
Registers a function to be called when an "info" signal is delivered to the process.
llvm::PrettyStackTraceProgram::print
void print(raw_ostream &OS) const override
print - Emit information about this stack frame to OS.
Definition: PrettyStackTrace.cpp:254
llvm::ReverseStackTrace
PrettyStackTraceEntry * ReverseStackTrace(PrettyStackTraceEntry *Head)
Definition: PrettyStackTrace.cpp:69
llvm::PrettyStackTraceFormat::print
void print(raw_ostream &OS) const override
print - Emit information about this stack frame to OS.
Definition: PrettyStackTrace.cpp:252
PrintStack
static void PrintStack(raw_ostream &OS)
Definition: PrettyStackTrace.cpp:78
llvm::raw_ostream
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:53
llvm::SmallVectorImpl::resize
void resize(size_type N)
Definition: SmallVector.h:606
llvm::raw_ostream::flush
void flush()
Definition: raw_ostream.h:186
GlobalSigInfoGenerationCounter
static volatile std::atomic< unsigned > GlobalSigInfoGenerationCounter
Definition: PrettyStackTrace.cpp:64
llvm::SmallString
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
Definition: SmallString.h:25
llvm::PrettyStackTraceEntry::~PrettyStackTraceEntry
virtual ~PrettyStackTraceEntry()
Definition: PrettyStackTrace.cpp:224
ThreadLocalSigInfoGenerationCounter
static LLVM_THREAD_LOCAL unsigned ThreadLocalSigInfoGenerationCounter
Definition: PrettyStackTrace.cpp:66
type
AMD64 Optimization Manual has some nice information about optimizing integer multiplication by a constant How much of it applies to Intel s X86 implementation There are definite trade offs to xmm0 cvttss2siq rdx jb L3 subss xmm0 rax cvttss2siq rdx xorq rdx rax ret instead of xmm1 cvttss2siq rcx movaps xmm2 subss xmm2 cvttss2siq rax rdx xorq rax ucomiss xmm0 cmovb rax ret Seems like the jb branch has high likelihood of being taken It would have saved a few instructions It s not possible to reference and DH registers in an instruction requiring REX prefix divb and mulb both produce results in AH If isel emits a CopyFromReg which gets turned into a movb and that can be allocated a r8b r15b To get around isel emits a CopyFromReg from AX and then right shift it down by and truncate it It s not pretty but it works We need some register allocation magic to make the hack go which would often require a callee saved register Callees usually need to keep this value live for most of their body so it doesn t add a significant burden on them We currently implement this in however this is suboptimal because it means that it would be quite awkward to implement the optimization for callers A better implementation would be to relax the LLVM IR rules for sret arguments to allow a function with an sret argument to have a non void return type
Definition: README-X86-64.txt:70
llvm::SavePrettyStackState
const void * SavePrettyStackState()
Returns the topmost element of the "pretty" stack state.
Definition: PrettyStackTrace.cpp:307
llvm::PrettyStackTraceString::print
void print(raw_ostream &OS) const override
print - Emit information about this stack frame to OS.
Definition: PrettyStackTrace.cpp:234
SaveAndRestore.h
__DATA
the multiplication has a latency of four as opposed to two cycles for the movl lea variant It appears gcc place string data with linkonce linkage in section coalesced instead of section __DATA
Definition: README.txt:260
PrettyStackTrace.h
I
#define I(x, y, z)
Definition: MD5.cpp:59
llvm::sys::AddSignalHandler
void AddSignalHandler(SignalHandlerCallback FnPtr, void *Cookie)
Add a function to be called when an abort/kill signal is delivered to the process.
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
LLVMEnablePrettyStackTrace
void LLVMEnablePrettyStackTrace()
Enable LLVM's built-in stack trace code.
Definition: PrettyStackTrace.cpp:322
RegisterCrashPrinter
static bool RegisterCrashPrinter()
Definition: PrettyStackTrace.cpp:271
if
if(llvm_vc STREQUAL "") set(fake_version_inc "$
Definition: CMakeLists.txt:14
Compiler.h
llvm::SaveAndRestore
A utility class that uses RAII to save and restore the value of a variable.
Definition: SaveAndRestore.h:21
setCrashLogMessage
static void setCrashLogMessage(const char *msg) LLVM_ATTRIBUTE_UNUSED
Definition: PrettyStackTrace.cpp:131
llvm::setBugReportMsg
void setBugReportMsg(const char *Msg)
Replaces the generic bug report message that is output upon a crash.
Definition: PrettyStackTrace.cpp:206
ErrorHandling.h
PrintCurStackTrace
static LLVM_ATTRIBUTE_NOINLINE void PrintCurStackTrace(raw_ostream &OS)
Print the current stack trace to the specified stream.
Definition: PrettyStackTrace.cpp:99
llvm::getBugReportMsg
const char * getBugReportMsg()
Get the bug report message that will be output upon a crash.
Definition: PrettyStackTrace.cpp:210
LLVM_ATTRIBUTE_NOINLINE
#define LLVM_ATTRIBUTE_NOINLINE
LLVM_ATTRIBUTE_NOINLINE - On compilers where we have a directive to do so, mark a method "not for inl...
Definition: Compiler.h:230
printForSigInfoIfNeeded
static void printForSigInfoIfNeeded()
Definition: PrettyStackTrace.cpp:192
llvm::raw_svector_ostream
A raw_ostream that writes to an SmallVector or SmallString.
Definition: raw_ostream.h:658
llvm::sys::Watchdog
This class provides an abstraction for a timeout around an operation that must complete in a given am...
Definition: Watchdog.h:25
llvm::PrettyStackTraceEntry::PrettyStackTraceEntry
PrettyStackTraceEntry()
Definition: PrettyStackTrace.cpp:214
raw_ostream.h
PrettyStackTraceHead
static LLVM_THREAD_LOCAL PrettyStackTraceEntry * PrettyStackTraceHead
Definition: PrettyStackTrace.cpp:50
llvm::PrettyStackTraceFormat::PrettyStackTraceFormat
PrettyStackTraceFormat(const char *Format,...)
Definition: PrettyStackTrace.cpp:236
llvm::EnablePrettyStackTrace
void EnablePrettyStackTrace()
Enables dumping a "pretty" stack trace when the program crashes.
Definition: PrettyStackTrace.cpp:277
llvm::Intrinsic::ID
unsigned ID
Definition: TargetTransformInfo.h:37
llvm::remarks::Format
Format
The format used for serializing/deserializing remarks.
Definition: RemarkFormat.h:25