blob: 1462ef0eb813e58643b6a85e50fcf1ec0fb0a893 [file] [log] [blame]
Chris Lattnere97c7332009-03-04 21:40:23 +00001//===- 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 occuring while your program is running.
12//
13//===----------------------------------------------------------------------===//
14
15#include "llvm/Support/PrettyStackTrace.h"
16#include "llvm/Support/raw_ostream.h"
17#include "llvm/System/Signals.h"
18using namespace llvm;
19
20// FIXME: This should be thread local when llvm supports threads.
21static const PrettyStackTraceEntry *PrettyStackTraceHead = 0;
22
Chris Lattnerd56786f2009-03-05 07:03:49 +000023static unsigned PrintStack(const PrettyStackTraceEntry *Entry, raw_ostream &OS){
24 unsigned NextID = 0;
25 if (Entry->getNextEntry())
26 NextID = PrintStack(Entry->getNextEntry(), OS);
27 OS << NextID << ".\t";
28 Entry->print(OS);
29
30 return NextID+1;
31}
32
Chris Lattnere97c7332009-03-04 21:40:23 +000033/// CrashHandler - This callback is run if a fatal signal is delivered to the
34/// process, it prints the pretty stack trace.
35static void CrashHandler(void *Cookie) {
Chris Lattnerd56786f2009-03-05 07:03:49 +000036 // Don't print an empty trace.
37 if (PrettyStackTraceHead == 0) return;
38
Chris Lattnere97c7332009-03-04 21:40:23 +000039 // If there are pretty stack frames registered, walk and emit them.
40 raw_ostream &OS = errs();
41 OS << "Stack dump:\n";
42
Chris Lattnerd56786f2009-03-05 07:03:49 +000043 PrintStack(PrettyStackTraceHead, OS);
Chris Lattnere97c7332009-03-04 21:40:23 +000044 OS.flush();
45}
46
47static bool RegisterCrashPrinter() {
48 sys::AddSignalHandler(CrashHandler, 0);
49 return false;
50}
51
52PrettyStackTraceEntry::PrettyStackTraceEntry() {
53 // The first time this is called, we register the crash printer.
54 static bool HandlerRegistered = RegisterCrashPrinter();
55 HandlerRegistered = HandlerRegistered;
56
57 // Link ourselves.
58 NextEntry = PrettyStackTraceHead;
59 PrettyStackTraceHead = this;
60}
61
62PrettyStackTraceEntry::~PrettyStackTraceEntry() {
63 assert(PrettyStackTraceHead == this &&
64 "Pretty stack trace entry destruction is out of order");
65 PrettyStackTraceHead = getNextEntry();
66}
67
68void PrettyStackTraceString::print(raw_ostream &OS) const {
69 OS << Str << "\n";
70}
71
72void PrettyStackTraceProgram::print(raw_ostream &OS) const {
Chris Lattnerfcba7cd2009-03-05 06:51:42 +000073 OS << "Program arguments: ";
Chris Lattnere97c7332009-03-04 21:40:23 +000074 // Print the argument list.
75 for (unsigned i = 0, e = ArgC; i != e; ++i)
76 OS << ArgV[i] << ' ';
77 OS << '\n';
Chris Lattnerfcba7cd2009-03-05 06:51:42 +000078}
79