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)
117#ifdef CRASHREPORTER_ANNOTATIONS_INITIALIZER
119CRASHREPORTER_ANNOTATIONS_INITIALIZER()
122CRASH_REPORTER_CLIENT_HIDDEN
123struct crashreporter_annotations_t gCRAnnotations
124 __attribute__((section(
"__DATA," CRASHREPORTER_ANNOTATIONS_SECTION))) = {
125 CRASHREPORTER_ANNOTATIONS_VERSION,
132#if CRASHREPORTER_ANNOTATIONS_VERSION > 4
138#elif defined(__APPLE__) && HAVE_CRASHREPORTER_INFO
139extern "C" const char *__crashreporter_info__
140 __attribute__((visibility(
"hidden"))) = 0;
141asm(
".desc ___crashreporter_info__, 0x10");
145static void setCrashLogMessage(
const char *msg) {
146#ifdef HAVE_CRASHREPORTERCLIENT_H
147 (void)CRSetCrashLogMessage(msg);
148#elif HAVE_CRASHREPORTER_INFO
149 __crashreporter_info__ = msg;
153 std::atomic_signal_fence(std::memory_order_seq_cst);
158using CrashHandlerStringStorage = std::byte[
sizeof(CrashHandlerString)];
159alignas(CrashHandlerString)
static CrashHandlerStringStorage
160 crashHandlerStringStorage;
165static void CrashHandler(
void *) {
170 PrintCurStackTrace(
errs());
182 auto &crashHandlerString =
183 *
new (&crashHandlerStringStorage) CrashHandlerString;
190 setCrashLogMessage(crashHandlerString.c_str());
194 PrintCurStackTrace(Stream);
197 if (!crashHandlerString.empty()) {
198 setCrashLogMessage(crashHandlerString.c_str());
199 errs() << crashHandlerString.str();
201 setCrashLogMessage(
"No crash information.");
206static void printForSigInfoIfNeeded() {
207 unsigned CurrentSigInfoGeneration =
208 GlobalSigInfoGenerationCounter.load(std::memory_order_relaxed);
209 if (ThreadLocalSigInfoGenerationCounter == 0 ||
210 ThreadLocalSigInfoGenerationCounter == CurrentSigInfoGeneration) {
214 PrintCurStackTrace(
errs());
215 ThreadLocalSigInfoGenerationCounter = CurrentSigInfoGeneration;
231 printForSigInfoIfNeeded();
233 NextEntry = PrettyStackTraceHead;
234 PrettyStackTraceHead =
this;
240 assert(PrettyStackTraceHead ==
this &&
241 "Pretty stack trace entry destruction is out of order");
242 PrettyStackTraceHead = NextEntry;
244 printForSigInfoIfNeeded();
253 const int SizeOrError = vsnprintf(
nullptr, 0,
Format, AP);
255 if (SizeOrError < 0) {
259 const int Size = SizeOrError + 1;
269 OS <<
"Program arguments: ";
271 for (
int I = 0;
I < ArgC; ++
I) {
272 const bool HaveSpace = ::strchr(ArgV[
I],
' ');
285static bool RegisterCrashPrinter() {
294 static bool HandlerRegistered = RegisterCrashPrinter();
295 (void)HandlerRegistered;
302 ThreadLocalSigInfoGenerationCounter = 0;
307 static bool HandlerRegistered = []{
309 GlobalSigInfoGenerationCounter.fetch_add(1, std::memory_order_relaxed);
313 (void)HandlerRegistered;
316 ThreadLocalSigInfoGenerationCounter =
317 GlobalSigInfoGenerationCounter.load(std::memory_order_relaxed);
323 return PrettyStackTraceHead;
331 PrettyStackTraceHead =
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
#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
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...
LLVM_C_ABI void LLVMEnablePrettyStackTrace(void)
Enable LLVM's built-in stack trace code.
LLVM_ABI void SetInfoSignalFunction(void(*Handler)())
Registers a function to be called when an "info" signal is delivered to the process.
LLVM_ABI void AddSignalHandler(SignalHandlerCallback FnPtr, void *Cookie)
Add a function to be called when an abort/kill signal is delivered to the process.
This is an optimization pass for GlobalISel generic memory operations.
LLVM_ABI void setBugReportMsg(const char *Msg)
Replaces the generic bug report message that is output upon a crash.
LLVM_ABI const void * SavePrettyStackState()
Returns the topmost element of the "pretty" stack state.
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
LLVM_ABI void RestorePrettyStackState(const void *State)
Restores the topmost element of the "pretty" stack state to State, which should come from a previous ...
LLVM_ABI void EnablePrettyStackTraceOnSigInfoForThisThread(bool ShouldEnable=true)
Enables (or disables) dumping a "pretty" stack trace when the user sends SIGINFO or SIGUSR1 to the cu...
LLVM_ABI void EnablePrettyStackTrace()
Enables dumping a "pretty" stack trace when the program crashes.
LLVM_ABI 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.