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 = 1;
74 std::tie(Prev, Head, Head->NextEntry) =
75 std::make_tuple(Head, Head->NextEntry, Prev);
94 llvm::ReverseStackTrace(ReversedStack);
103 if (!PrettyStackTraceHead)
return;
106 OS <<
"Stack dump:\n";
113#if defined (__APPLE__) && defined(HAVE_CRASHREPORTERCLIENT_H)
117CRASH_REPORTER_CLIENT_HIDDEN
118struct crashreporter_annotations_t gCRAnnotations
119 __attribute__((section(
"__DATA," CRASHREPORTER_ANNOTATIONS_SECTION)))
120#
if CRASHREPORTER_ANNOTATIONS_VERSION < 5
121 = { CRASHREPORTER_ANNOTATIONS_VERSION, 0, 0, 0, 0, 0, 0 };
123 = { CRASHREPORTER_ANNOTATIONS_VERSION, 0, 0, 0, 0, 0, 0, 0 };
126#elif defined(__APPLE__) && HAVE_CRASHREPORTER_INFO
127extern "C" const char *__crashreporter_info__
128 __attribute__((visibility(
"hidden"))) = 0;
129asm(
".desc ___crashreporter_info__, 0x10");
133static void setCrashLogMessage(
const char *msg) {
134#ifdef HAVE_CRASHREPORTERCLIENT_H
135 (void)CRSetCrashLogMessage(msg);
136#elif HAVE_CRASHREPORTER_INFO
137 __crashreporter_info__ = msg;
141 std::atomic_signal_fence(std::memory_order_seq_cst);
146using CrashHandlerStringStorage = std::byte[
sizeof(CrashHandlerString)];
147alignas(CrashHandlerString)
static CrashHandlerStringStorage
148 crashHandlerStringStorage;
153static void CrashHandler(
void *) {
158 PrintCurStackTrace(
errs());
170 auto &crashHandlerString =
171 *
new (&crashHandlerStringStorage) CrashHandlerString;
178 setCrashLogMessage(crashHandlerString.c_str());
182 PrintCurStackTrace(Stream);
185 if (!crashHandlerString.empty()) {
186 setCrashLogMessage(crashHandlerString.c_str());
187 errs() << crashHandlerString.str();
189 setCrashLogMessage(
"No crash information.");
193static void printForSigInfoIfNeeded() {
194 unsigned CurrentSigInfoGeneration =
195 GlobalSigInfoGenerationCounter.load(std::memory_order_relaxed);
196 if (ThreadLocalSigInfoGenerationCounter == 0 ||
197 ThreadLocalSigInfoGenerationCounter == CurrentSigInfoGeneration) {
201 PrintCurStackTrace(
errs());
202 ThreadLocalSigInfoGenerationCounter = CurrentSigInfoGeneration;
218 printForSigInfoIfNeeded();
220 NextEntry = PrettyStackTraceHead;
221 PrettyStackTraceHead =
this;
227 assert(PrettyStackTraceHead ==
this &&
228 "Pretty stack trace entry destruction is out of order");
229 PrettyStackTraceHead = NextEntry;
231 printForSigInfoIfNeeded();
240 const int SizeOrError = vsnprintf(
nullptr, 0,
Format, AP);
242 if (SizeOrError < 0) {
246 const int Size = SizeOrError + 1;
256 OS <<
"Program arguments: ";
258 for (
int I = 0;
I < ArgC; ++
I) {
259 const bool HaveSpace = ::strchr(ArgV[
I],
' ');
272static bool RegisterCrashPrinter() {
281 static bool HandlerRegistered = RegisterCrashPrinter();
282 (void)HandlerRegistered;
289 ThreadLocalSigInfoGenerationCounter = 0;
294 static bool HandlerRegistered = []{
296 GlobalSigInfoGenerationCounter.fetch_add(1, std::memory_order_relaxed);
300 (void)HandlerRegistered;
303 ThreadLocalSigInfoGenerationCounter =
304 GlobalSigInfoGenerationCounter.load(std::memory_order_relaxed);
310 return PrettyStackTraceHead;
318 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.