PrettyStackTrace.cpp 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  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. #include "llvm/Support/PrettyStackTrace.h"
  14. #include "llvm-c/ErrorHandling.h"
  15. #include "llvm/ADT/SmallString.h"
  16. #include "llvm/Config/config.h"
  17. #include "llvm/Support/Compiler.h"
  18. #include "llvm/Support/Signals.h"
  19. #include "llvm/Support/Watchdog.h"
  20. #include "llvm/Support/raw_ostream.h"
  21. #include <cstdarg>
  22. #include <cstdio>
  23. #include <tuple>
  24. #ifdef HAVE_CRASHREPORTERCLIENT_H
  25. #include <CrashReporterClient.h>
  26. #endif
  27. using namespace llvm;
  28. // If backtrace support is not enabled, compile out support for pretty stack
  29. // traces. This has the secondary effect of not requiring thread local storage
  30. // when backtrace support is disabled.
  31. #if ENABLE_BACKTRACES
  32. // We need a thread local pointer to manage the stack of our stack trace
  33. // objects, but we *really* cannot tolerate destructors running and do not want
  34. // to pay any overhead of synchronizing. As a consequence, we use a raw
  35. // thread-local variable.
  36. static LLVM_THREAD_LOCAL PrettyStackTraceEntry *PrettyStackTraceHead = nullptr;
  37. namespace llvm {
  38. PrettyStackTraceEntry *ReverseStackTrace(PrettyStackTraceEntry *Head) {
  39. PrettyStackTraceEntry *Prev = nullptr;
  40. while (Head)
  41. std::tie(Prev, Head, Head->NextEntry) =
  42. std::make_tuple(Head, Head->NextEntry, Prev);
  43. return Prev;
  44. }
  45. }
  46. static void PrintStack(raw_ostream &OS) {
  47. // Print out the stack in reverse order. To avoid recursion (which is likely
  48. // to fail if we crashed due to stack overflow), we do an up-front pass to
  49. // reverse the stack, then print it, then reverse it again.
  50. unsigned ID = 0;
  51. PrettyStackTraceEntry *ReversedStack =
  52. llvm::ReverseStackTrace(PrettyStackTraceHead);
  53. for (const PrettyStackTraceEntry *Entry = ReversedStack; Entry;
  54. Entry = Entry->getNextEntry()) {
  55. OS << ID++ << ".\t";
  56. sys::Watchdog W(5);
  57. Entry->print(OS);
  58. }
  59. llvm::ReverseStackTrace(ReversedStack);
  60. }
  61. /// PrintCurStackTrace - Print the current stack trace to the specified stream.
  62. static void PrintCurStackTrace(raw_ostream &OS) {
  63. // Don't print an empty trace.
  64. if (!PrettyStackTraceHead) return;
  65. // If there are pretty stack frames registered, walk and emit them.
  66. OS << "Stack dump:\n";
  67. PrintStack(OS);
  68. OS.flush();
  69. }
  70. // Integrate with crash reporter libraries.
  71. #if defined (__APPLE__) && defined(HAVE_CRASHREPORTERCLIENT_H)
  72. // If any clients of llvm try to link to libCrashReporterClient.a themselves,
  73. // only one crash info struct will be used.
  74. extern "C" {
  75. CRASH_REPORTER_CLIENT_HIDDEN
  76. struct crashreporter_annotations_t gCRAnnotations
  77. __attribute__((section("__DATA," CRASHREPORTER_ANNOTATIONS_SECTION)))
  78. #if CRASHREPORTER_ANNOTATIONS_VERSION < 5
  79. = { CRASHREPORTER_ANNOTATIONS_VERSION, 0, 0, 0, 0, 0, 0 };
  80. #else
  81. = { CRASHREPORTER_ANNOTATIONS_VERSION, 0, 0, 0, 0, 0, 0, 0 };
  82. #endif
  83. }
  84. #elif defined(__APPLE__) && HAVE_CRASHREPORTER_INFO
  85. extern "C" const char *__crashreporter_info__
  86. __attribute__((visibility("hidden"))) = 0;
  87. asm(".desc ___crashreporter_info__, 0x10");
  88. #endif
  89. /// CrashHandler - This callback is run if a fatal signal is delivered to the
  90. /// process, it prints the pretty stack trace.
  91. static void CrashHandler(void *) {
  92. #ifndef __APPLE__
  93. // On non-apple systems, just emit the crash stack trace to stderr.
  94. PrintCurStackTrace(errs());
  95. #else
  96. // Otherwise, emit to a smallvector of chars, send *that* to stderr, but also
  97. // put it into __crashreporter_info__.
  98. SmallString<2048> TmpStr;
  99. {
  100. raw_svector_ostream Stream(TmpStr);
  101. PrintCurStackTrace(Stream);
  102. }
  103. if (!TmpStr.empty()) {
  104. #ifdef HAVE_CRASHREPORTERCLIENT_H
  105. // Cast to void to avoid warning.
  106. (void)CRSetCrashLogMessage(TmpStr.c_str());
  107. #elif HAVE_CRASHREPORTER_INFO
  108. __crashreporter_info__ = strdup(TmpStr.c_str());
  109. #endif
  110. errs() << TmpStr.str();
  111. }
  112. #endif
  113. }
  114. #endif // ENABLE_BACKTRACES
  115. PrettyStackTraceEntry::PrettyStackTraceEntry() {
  116. #if ENABLE_BACKTRACES
  117. // Link ourselves.
  118. NextEntry = PrettyStackTraceHead;
  119. PrettyStackTraceHead = this;
  120. #endif
  121. }
  122. PrettyStackTraceEntry::~PrettyStackTraceEntry() {
  123. #if ENABLE_BACKTRACES
  124. assert(PrettyStackTraceHead == this &&
  125. "Pretty stack trace entry destruction is out of order");
  126. PrettyStackTraceHead = NextEntry;
  127. #endif
  128. }
  129. void PrettyStackTraceString::print(raw_ostream &OS) const { OS << Str << "\n"; }
  130. PrettyStackTraceFormat::PrettyStackTraceFormat(const char *Format, ...) {
  131. va_list AP;
  132. va_start(AP, Format);
  133. const int SizeOrError = vsnprintf(nullptr, 0, Format, AP);
  134. va_end(AP);
  135. if (SizeOrError < 0) {
  136. return;
  137. }
  138. const int Size = SizeOrError + 1; // '\0'
  139. Str.resize(Size);
  140. va_start(AP, Format);
  141. vsnprintf(Str.data(), Size, Format, AP);
  142. va_end(AP);
  143. }
  144. void PrettyStackTraceFormat::print(raw_ostream &OS) const { OS << Str << "\n"; }
  145. void PrettyStackTraceProgram::print(raw_ostream &OS) const {
  146. OS << "Program arguments: ";
  147. // Print the argument list.
  148. for (unsigned i = 0, e = ArgC; i != e; ++i)
  149. OS << ArgV[i] << ' ';
  150. OS << '\n';
  151. }
  152. #if ENABLE_BACKTRACES
  153. static bool RegisterCrashPrinter() {
  154. sys::AddSignalHandler(CrashHandler, nullptr);
  155. return false;
  156. }
  157. #endif
  158. void llvm::EnablePrettyStackTrace() {
  159. #if ENABLE_BACKTRACES
  160. // The first time this is called, we register the crash printer.
  161. static bool HandlerRegistered = RegisterCrashPrinter();
  162. (void)HandlerRegistered;
  163. #endif
  164. }
  165. const void *llvm::SavePrettyStackState() {
  166. #if ENABLE_BACKTRACES
  167. return PrettyStackTraceHead;
  168. #else
  169. return nullptr;
  170. #endif
  171. }
  172. void llvm::RestorePrettyStackState(const void *Top) {
  173. #if ENABLE_BACKTRACES
  174. PrettyStackTraceHead =
  175. static_cast<PrettyStackTraceEntry *>(const_cast<void *>(Top));
  176. #endif
  177. }
  178. void LLVMEnablePrettyStackTrace() {
  179. EnablePrettyStackTrace();
  180. }