PrettyStackTrace.cpp 5.8 KB

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