Coverage Report

Created: 2017-10-03 07:32

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