2
0

PrettyStackTrace.cpp 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  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/Core.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. #ifdef HAVE_CRASHREPORTERCLIENT_H
  23. #include <CrashReporterClient.h>
  24. #endif
  25. using namespace llvm;
  26. // If backtrace support is not enabled, compile out support for pretty stack
  27. // traces. This has the secondary effect of not requiring thread local storage
  28. // when backtrace support is disabled.
  29. #if defined(HAVE_BACKTRACE) && defined(ENABLE_BACKTRACES)
  30. // We need a thread local pointer to manage the stack of our stack trace
  31. // objects, but we *really* cannot tolerate destructors running and do not want
  32. // to pay any overhead of synchronizing. As a consequence, we use a raw
  33. // thread-local variable.
  34. static LLVM_THREAD_LOCAL const PrettyStackTraceEntry *PrettyStackTraceHead =
  35. nullptr;
  36. static unsigned PrintStack(const PrettyStackTraceEntry *Entry, raw_ostream &OS){
  37. unsigned NextID = 0;
  38. if (Entry->getNextEntry())
  39. NextID = PrintStack(Entry->getNextEntry(), OS);
  40. OS << NextID << ".\t";
  41. {
  42. sys::Watchdog W(5);
  43. Entry->print(OS);
  44. }
  45. return NextID+1;
  46. }
  47. /// PrintCurStackTrace - Print the current stack trace to the specified stream.
  48. static void PrintCurStackTrace(raw_ostream &OS) {
  49. // Don't print an empty trace.
  50. if (!PrettyStackTraceHead) return;
  51. // If there are pretty stack frames registered, walk and emit them.
  52. OS << "Stack dump:\n";
  53. PrintStack(PrettyStackTraceHead, OS);
  54. OS.flush();
  55. }
  56. // Integrate with crash reporter libraries.
  57. #if defined (__APPLE__) && HAVE_CRASHREPORTERCLIENT_H
  58. // If any clients of llvm try to link to libCrashReporterClient.a themselves,
  59. // only one crash info struct will be used.
  60. extern "C" {
  61. CRASH_REPORTER_CLIENT_HIDDEN
  62. struct crashreporter_annotations_t gCRAnnotations
  63. __attribute__((section("__DATA," CRASHREPORTER_ANNOTATIONS_SECTION)))
  64. = { CRASHREPORTER_ANNOTATIONS_VERSION, 0, 0, 0, 0, 0, 0 };
  65. }
  66. #elif defined (__APPLE__) && HAVE_CRASHREPORTER_INFO
  67. static const char *__crashreporter_info__ = 0;
  68. asm(".desc ___crashreporter_info__, 0x10");
  69. #endif
  70. /// CrashHandler - This callback is run if a fatal signal is delivered to the
  71. /// process, it prints the pretty stack trace.
  72. static void CrashHandler(void *) {
  73. #ifndef __APPLE__
  74. // On non-apple systems, just emit the crash stack trace to stderr.
  75. PrintCurStackTrace(errs());
  76. #else
  77. // Otherwise, emit to a smallvector of chars, send *that* to stderr, but also
  78. // put it into __crashreporter_info__.
  79. SmallString<2048> TmpStr;
  80. {
  81. raw_svector_ostream Stream(TmpStr);
  82. PrintCurStackTrace(Stream);
  83. }
  84. if (!TmpStr.empty()) {
  85. #ifdef HAVE_CRASHREPORTERCLIENT_H
  86. // Cast to void to avoid warning.
  87. (void)CRSetCrashLogMessage(std::string(TmpStr.str()).c_str());
  88. #elif HAVE_CRASHREPORTER_INFO
  89. __crashreporter_info__ = strdup(std::string(TmpStr.str()).c_str());
  90. #endif
  91. errs() << TmpStr.str();
  92. }
  93. #endif
  94. }
  95. // defined(HAVE_BACKTRACE) && defined(ENABLE_BACKTRACES)
  96. #endif
  97. PrettyStackTraceEntry::PrettyStackTraceEntry() {
  98. #if defined(HAVE_BACKTRACE) && defined(ENABLE_BACKTRACES)
  99. // Link ourselves.
  100. NextEntry = PrettyStackTraceHead;
  101. PrettyStackTraceHead = this;
  102. #endif
  103. }
  104. PrettyStackTraceEntry::~PrettyStackTraceEntry() {
  105. #if defined(HAVE_BACKTRACE) && defined(ENABLE_BACKTRACES)
  106. assert(PrettyStackTraceHead == this &&
  107. "Pretty stack trace entry destruction is out of order");
  108. PrettyStackTraceHead = getNextEntry();
  109. #endif
  110. }
  111. void PrettyStackTraceString::print(raw_ostream &OS) const {
  112. OS << Str << "\n";
  113. }
  114. void PrettyStackTraceProgram::print(raw_ostream &OS) const {
  115. OS << "Program arguments: ";
  116. // Print the argument list.
  117. for (unsigned i = 0, e = ArgC; i != e; ++i)
  118. OS << ArgV[i] << ' ';
  119. OS << '\n';
  120. }
  121. #if defined(HAVE_BACKTRACE) && defined(ENABLE_BACKTRACES)
  122. static bool RegisterCrashPrinter() {
  123. sys::AddSignalHandler(CrashHandler, nullptr);
  124. return false;
  125. }
  126. #endif
  127. void llvm::EnablePrettyStackTrace() {
  128. #if defined(HAVE_BACKTRACE) && defined(ENABLE_BACKTRACES)
  129. // The first time this is called, we register the crash printer.
  130. static bool HandlerRegistered = RegisterCrashPrinter();
  131. (void)HandlerRegistered;
  132. #endif
  133. }
  134. void LLVMEnablePrettyStackTrace() {
  135. EnablePrettyStackTrace();
  136. }