1
//===- PrettyStackTrace.cpp - Pretty Crash Handling -----------------------===//
3
// The LLVM Compiler Infrastructure
5
// This file is distributed under the University of Illinois Open Source
6
// License. See LICENSE.TXT for details.
8
//===----------------------------------------------------------------------===//
10
// This file defines some helpful functions for dealing with the possibility of
11
// Unix signals occuring while your program is running.
13
//===----------------------------------------------------------------------===//
15
#include "llvm/Support/PrettyStackTrace.h"
16
#include "llvm/Support/raw_ostream.h"
17
#include "llvm/System/Signals.h"
18
#include "llvm/System/ThreadLocal.h"
19
#include "llvm/ADT/SmallString.h"
23
bool DisablePrettyStackTrace = false;
26
// FIXME: This should be thread local when llvm supports threads.
27
static sys::ThreadLocal<const PrettyStackTraceEntry> PrettyStackTraceHead;
29
static unsigned PrintStack(const PrettyStackTraceEntry *Entry, raw_ostream &OS){
31
if (Entry->getNextEntry())
32
NextID = PrintStack(Entry->getNextEntry(), OS);
33
OS << NextID << ".\t";
39
/// PrintCurStackTrace - Print the current stack trace to the specified stream.
40
static void PrintCurStackTrace(raw_ostream &OS) {
41
// Don't print an empty trace.
42
if (PrettyStackTraceHead.get() == 0) return;
44
// If there are pretty stack frames registered, walk and emit them.
45
OS << "Stack dump:\n";
47
PrintStack(PrettyStackTraceHead.get(), OS);
51
// Integrate with crash reporter.
53
extern "C" const char *__crashreporter_info__;
54
const char *__crashreporter_info__ = 0;
58
/// CrashHandler - This callback is run if a fatal signal is delivered to the
59
/// process, it prints the pretty stack trace.
60
static void CrashHandler(void *Cookie) {
62
// On non-apple systems, just emit the crash stack trace to stderr.
63
PrintCurStackTrace(errs());
65
// Otherwise, emit to a smallvector of chars, send *that* to stderr, but also
66
// put it into __crashreporter_info__.
67
SmallString<2048> TmpStr;
69
raw_svector_ostream Stream(TmpStr);
70
PrintCurStackTrace(Stream);
73
if (!TmpStr.empty()) {
74
__crashreporter_info__ = strdup(std::string(TmpStr.str()).c_str());
75
errs() << TmpStr.str();
81
static bool RegisterCrashPrinter() {
82
if (!DisablePrettyStackTrace)
83
sys::AddSignalHandler(CrashHandler, 0);
87
PrettyStackTraceEntry::PrettyStackTraceEntry() {
88
// The first time this is called, we register the crash printer.
89
static bool HandlerRegistered = RegisterCrashPrinter();
90
HandlerRegistered = HandlerRegistered;
93
NextEntry = PrettyStackTraceHead.get();
94
PrettyStackTraceHead.set(this);
97
PrettyStackTraceEntry::~PrettyStackTraceEntry() {
98
assert(PrettyStackTraceHead.get() == this &&
99
"Pretty stack trace entry destruction is out of order");
100
PrettyStackTraceHead.set(getNextEntry());
103
void PrettyStackTraceString::print(raw_ostream &OS) const {
107
void PrettyStackTraceProgram::print(raw_ostream &OS) const {
108
OS << "Program arguments: ";
109
// Print the argument list.
110
for (unsigned i = 0, e = ArgC; i != e; ++i)
111
OS << ArgV[i] << ' ';