LLVM: lib/Support/PrettyStackTrace.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

16#include "llvm/Config/config.h"

22

23#ifdef __APPLE__

25#endif

26

27#include

28#include

29#include

30#include

31#include

32#include

33

34#ifdef HAVE_CRASHREPORTERCLIENT_H

35#include <CrashReporterClient.h>

36#endif

37

38using namespace llvm;

39

41 "PLEASE submit a bug report to " BUG_REPORT_URL

42 " and include the crash backtrace and instructions to reproduce the bug.\n";

43

44

45

46

47#if ENABLE_BACKTRACES

48

49

50

51

52

54

55

56

57

58

59

60

61

62

63

64

65

66

67static volatile std::atomic GlobalSigInfoGenerationCounter = 1;

68static LLVM_THREAD_LOCAL unsigned ThreadLocalSigInfoGenerationCounter = 0;

69

70namespace llvm {

73 while (Head)

74 std::tie(Prev, Head, Head->NextEntry) =

75 std::make_tuple(Head, Head->NextEntry, Prev);

76 return Prev;

77}

78}

79

81

82

83

84 unsigned ID = 0;

86 nullptr};

90 OS << ID++ << ".\t";

92 Entry->print(OS);

93 }

94 llvm::ReverseStackTrace(ReversedStack);

95}

96

97

98

99

101static void PrintCurStackTrace(raw_ostream &OS) {

102

103 if (!PrettyStackTraceHead) return;

104

105

106 OS << "Stack dump:\n";

107

108 PrintStack(OS);

110}

111

112

113#if defined (__APPLE__) && defined(HAVE_CRASHREPORTERCLIENT_H)

114

115

116extern "C" {

117#ifdef CRASHREPORTER_ANNOTATIONS_INITIALIZER

118

119CRASHREPORTER_ANNOTATIONS_INITIALIZER()

120#else

121

122CRASH_REPORTER_CLIENT_HIDDEN

123struct crashreporter_annotations_t gCRAnnotations

124 __attribute__((section("__DATA," CRASHREPORTER_ANNOTATIONS_SECTION))) = {

125 CRASHREPORTER_ANNOTATIONS_VERSION,

126 0,

127 0,

128 0,

129 0,

130 0,

131 0,

132#if CRASHREPORTER_ANNOTATIONS_VERSION > 4

133 0

134#endif

135};

136#endif

137}

138#elif defined(__APPLE__) && HAVE_CRASHREPORTER_INFO

139extern "C" const char *__crashreporter_info__

140 __attribute__((visibility("hidden"))) = 0;

141asm(".desc ___crashreporter_info__, 0x10");

142#endif

143

144[[maybe_unused]] static void setCrashLogMessage(const char *msg);

145static void setCrashLogMessage(const char *msg) {

146#ifdef HAVE_CRASHREPORTERCLIENT_H

147 (void)CRSetCrashLogMessage(msg);

148#elif HAVE_CRASHREPORTER_INFO

149 __crashreporter_info__ = msg;

150#endif

151

152

153 std::atomic_signal_fence(std::memory_order_seq_cst);

154}

155

156#ifdef __APPLE__

158using CrashHandlerStringStorage = std::byte[sizeof(CrashHandlerString)];

159alignas(CrashHandlerString) static CrashHandlerStringStorage

160 crashHandlerStringStorage;

161#endif

162

163

164

165static void CrashHandler(void *) {

167

168#ifndef __APPLE__

169

170 PrintCurStackTrace(errs());

171#else

172

173

174

175

176

177

178

179

180

181

182 auto &crashHandlerString =

183 *new (&crashHandlerStringStorage) CrashHandlerString;

184

185

186

187

188

189

190 setCrashLogMessage(crashHandlerString.c_str());

191

192 {

194 PrintCurStackTrace(Stream);

195 }

196

197 if (!crashHandlerString.empty()) {

198 setCrashLogMessage(crashHandlerString.c_str());

199 errs() << crashHandlerString.str();

200 } else {

201 setCrashLogMessage("No crash information.");

202 }

203#endif

204}

205

206static void printForSigInfoIfNeeded() {

207 unsigned CurrentSigInfoGeneration =

208 GlobalSigInfoGenerationCounter.load(std::memory_order_relaxed);

209 if (ThreadLocalSigInfoGenerationCounter == 0 ||

210 ThreadLocalSigInfoGenerationCounter == CurrentSigInfoGeneration) {

211 return;

212 }

213

214 PrintCurStackTrace(errs());

215 ThreadLocalSigInfoGenerationCounter = CurrentSigInfoGeneration;

216}

217

218#endif

219

223

227

229#if ENABLE_BACKTRACES

230

231 printForSigInfoIfNeeded();

232

233 NextEntry = PrettyStackTraceHead;

234 PrettyStackTraceHead = this;

235#endif

236}

237

239#if ENABLE_BACKTRACES

240 assert(PrettyStackTraceHead == this &&

241 "Pretty stack trace entry destruction is out of order");

242 PrettyStackTraceHead = NextEntry;

243

244 printForSigInfoIfNeeded();

245#endif

246}

247

249

251 va_list AP;

252 va_start(AP, Format);

253 const int SizeOrError = vsnprintf(nullptr, 0, Format, AP);

254 va_end(AP);

255 if (SizeOrError < 0) {

256 return;

257 }

258

259 const int Size = SizeOrError + 1;

260 Str.resize(Size);

261 va_start(AP, Format);

262 vsnprintf(Str.data(), Size, Format, AP);

263 va_end(AP);

264}

265

267

269 OS << "Program arguments: ";

270

271 for (int I = 0; I < ArgC; ++I) {

272 const bool HaveSpace = ::strchr(ArgV[I], ' ');

273 if (I)

274 OS << ' ';

275 if (HaveSpace)

276 OS << '"';

278 if (HaveSpace)

279 OS << '"';

280 }

281 OS << '\n';

282}

283

284#if ENABLE_BACKTRACES

285static bool RegisterCrashPrinter() {

287 return false;

288}

289#endif

290

292#if ENABLE_BACKTRACES

293

294 static bool HandlerRegistered = RegisterCrashPrinter();

295 (void)HandlerRegistered;

296#endif

297}

298

300#if ENABLE_BACKTRACES

301 if (!ShouldEnable) {

302 ThreadLocalSigInfoGenerationCounter = 0;

303 return;

304 }

305

306

307 static bool HandlerRegistered = []{

309 GlobalSigInfoGenerationCounter.fetch_add(1, std::memory_order_relaxed);

310 });

311 return false;

312 }();

313 (void)HandlerRegistered;

314

315

316 ThreadLocalSigInfoGenerationCounter =

317 GlobalSigInfoGenerationCounter.load(std::memory_order_relaxed);

318#endif

319}

320

322#if ENABLE_BACKTRACES

323 return PrettyStackTraceHead;

324#else

325 return nullptr;

326#endif

327}

328

330#if ENABLE_BACKTRACES

331 PrettyStackTraceHead =

333#endif

334}

335

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...

static const char * BugReportMsg

Definition PrettyStackTrace.cpp:40

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()

Definition PrettyStackTrace.cpp:238

const PrettyStackTraceEntry * getNextEntry() const

getNextEntry - Return the next entry in the list of frames.

PrettyStackTraceEntry()

Definition PrettyStackTrace.cpp:228

void print(raw_ostream &OS) const override

print - Emit information about this stack frame to OS.

Definition PrettyStackTrace.cpp:266

PrettyStackTraceFormat(const char *Format,...)

Definition PrettyStackTrace.cpp:250

void print(raw_ostream &OS) const override

print - Emit information about this stack frame to OS.

Definition PrettyStackTrace.cpp:268

void print(raw_ostream &OS) const override

print - Emit information about this stack frame to OS.

Definition PrettyStackTrace.cpp:248

SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...

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.

Definition PrettyStackTrace.cpp:336

unsigned ID

LLVM IR allows to use arbitrary numbers as calling convention identifiers.

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.

Definition PrettyStackTrace.cpp:220

LLVM_ABI const void * SavePrettyStackState()

Returns the topmost element of the "pretty" stack state.

Definition PrettyStackTrace.cpp:321

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 ...

Definition PrettyStackTrace.cpp:329

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...

Definition PrettyStackTrace.cpp:299

LLVM_ABI void EnablePrettyStackTrace()

Enables dumping a "pretty" stack trace when the program crashes.

Definition PrettyStackTrace.cpp:291

LLVM_ABI const char * getBugReportMsg()

Get the bug report message that will be output upon a crash.

Definition PrettyStackTrace.cpp:224

A utility class that uses RAII to save and restore the value of a variable.