16#include "llvm/Config/config.h"
34#ifdef HAVE_CRASHREPORTERCLIENT_H
35#include <CrashReporterClient.h>
41 "PLEASE submit a bug report to " BUG_REPORT_URL
42 " and include the crash backtrace.\n";
67static volatile std::atomic<unsigned> GlobalSigInfoGenerationCounter =
75 std::tie(Prev, Head, Head->NextEntry) =
76 std::make_tuple(Head, Head->NextEntry, Prev);
90 Entry = Entry->getNextEntry()) {
95 llvm::ReverseStackTrace(ReversedStack);
104 if (!PrettyStackTraceHead)
return;
107 OS <<
"Stack dump:\n";
114#if defined (__APPLE__) && defined(HAVE_CRASHREPORTERCLIENT_H)
118CRASH_REPORTER_CLIENT_HIDDEN
119struct crashreporter_annotations_t gCRAnnotations
120 __attribute__((section(
"__DATA," CRASHREPORTER_ANNOTATIONS_SECTION)))
121#
if CRASHREPORTER_ANNOTATIONS_VERSION < 5
122 = { CRASHREPORTER_ANNOTATIONS_VERSION, 0, 0, 0, 0, 0, 0 };
124 = { CRASHREPORTER_ANNOTATIONS_VERSION, 0, 0, 0, 0, 0, 0, 0 };
127#elif defined(__APPLE__) && HAVE_CRASHREPORTER_INFO
128extern "C" const char *__crashreporter_info__
129 __attribute__((visibility(
"hidden"))) = 0;
130asm(
".desc ___crashreporter_info__, 0x10");
134static void setCrashLogMessage(
const char *msg) {
135#ifdef HAVE_CRASHREPORTERCLIENT_H
136 (void)CRSetCrashLogMessage(msg);
137#elif HAVE_CRASHREPORTER_INFO
138 __crashreporter_info__ = msg;
142 std::atomic_signal_fence(std::memory_order_seq_cst);
147using CrashHandlerStringStorage =
148 std::aligned_storage<
sizeof(CrashHandlerString),
149 alignof(CrashHandlerString)>::type;
150static CrashHandlerStringStorage crashHandlerStringStorage;
155static void CrashHandler(
void *) {
160 PrintCurStackTrace(
errs());
172 auto &crashHandlerString =
173 *
new (&crashHandlerStringStorage) CrashHandlerString;
180 setCrashLogMessage(crashHandlerString.c_str());
184 PrintCurStackTrace(Stream);
187 if (!crashHandlerString.empty()) {
188 setCrashLogMessage(crashHandlerString.c_str());
189 errs() << crashHandlerString.str();
191 setCrashLogMessage(
"No crash information.");
195static void printForSigInfoIfNeeded() {
196 unsigned CurrentSigInfoGeneration =
197 GlobalSigInfoGenerationCounter.load(std::memory_order_relaxed);
198 if (ThreadLocalSigInfoGenerationCounter == 0 ||
199 ThreadLocalSigInfoGenerationCounter == CurrentSigInfoGeneration) {
203 PrintCurStackTrace(
errs());
204 ThreadLocalSigInfoGenerationCounter = CurrentSigInfoGeneration;
220 printForSigInfoIfNeeded();
222 NextEntry = PrettyStackTraceHead;
223 PrettyStackTraceHead =
this;
229 assert(PrettyStackTraceHead ==
this &&
230 "Pretty stack trace entry destruction is out of order");
231 PrettyStackTraceHead = NextEntry;
233 printForSigInfoIfNeeded();
242 const int SizeOrError = vsnprintf(
nullptr, 0,
Format, AP);
244 if (SizeOrError < 0) {
248 const int Size = SizeOrError + 1;
258 OS <<
"Program arguments: ";
260 for (
int I = 0;
I < ArgC; ++
I) {
261 const bool HaveSpace = ::strchr(ArgV[
I],
' ');
274static bool RegisterCrashPrinter() {
283 static bool HandlerRegistered = RegisterCrashPrinter();
284 (void)HandlerRegistered;
291 ThreadLocalSigInfoGenerationCounter = 0;
296 static bool HandlerRegistered = []{
298 GlobalSigInfoGenerationCounter.fetch_add(1, std::memory_order_relaxed);
302 (void)HandlerRegistered;
305 ThreadLocalSigInfoGenerationCounter =
306 GlobalSigInfoGenerationCounter.load(std::memory_order_relaxed);
312 return PrettyStackTraceHead;
320 PrettyStackTraceHead =
#define LLVM_THREAD_LOCAL
\macro LLVM_THREAD_LOCAL A thread-local storage specifier which can be used with globals,...
#define LLVM_ATTRIBUTE_NOINLINE
LLVM_ATTRIBUTE_NOINLINE - On compilers where we have a directive to do so, mark a method "not for inl...
#define LLVM_ATTRIBUTE_UNUSED
static const char * BugReportMsg
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file provides utility classes that use RAII to save and restore values.
This file defines the SmallString class.
PrettyStackTraceEntry - This class is used to represent a frame of the "pretty" stack trace that is d...
virtual ~PrettyStackTraceEntry()
void print(raw_ostream &OS) const override
print - Emit information about this stack frame to OS.
void print(raw_ostream &OS) const override
print - Emit information about this stack frame to OS.
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
pointer data()
Return a pointer to the vector's buffer, even if empty().
This class implements an extremely fast bulk output stream that can only output to a stream.
raw_ostream & write_escaped(StringRef Str, bool UseHexEscapes=false)
Output Str, turning '\', '\t', ' ', '"', and anything that doesn't satisfy llvm::isPrint into an esca...
A raw_ostream that writes to an SmallVector or SmallString.
This class provides an abstraction for a timeout around an operation that must complete in a given am...
void LLVMEnablePrettyStackTrace(void)
Enable LLVM's built-in stack trace code.
void AddSignalHandler(SignalHandlerCallback FnPtr, void *Cookie)
Add a function to be called when an abort/kill signal is delivered to the process.
void SetInfoSignalFunction(void(*Handler)())
Registers a function to be called when an "info" signal is delivered to the process.
This is an optimization pass for GlobalISel generic memory operations.
void setBugReportMsg(const char *Msg)
Replaces the generic bug report message that is output upon a crash.
const void * SavePrettyStackState()
Returns the topmost element of the "pretty" stack state.
raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
void RestorePrettyStackState(const void *State)
Restores the topmost element of the "pretty" stack state to State, which should come from a previous ...
void EnablePrettyStackTraceOnSigInfoForThisThread(bool ShouldEnable=true)
Enables (or disables) dumping a "pretty" stack trace when the user sends SIGINFO or SIGUSR1 to the cu...
void EnablePrettyStackTrace()
Enables dumping a "pretty" stack trace when the program crashes.
const char * getBugReportMsg()
Get the bug report message that will be output upon a crash.
A utility class that uses RAII to save and restore the value of a variable.