X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FSupport%2FPrettyStackTrace.cpp;h=987778a1bde66999171556f571c94c59e352dddb;hb=1691fa27d7c8be0bdedda193a70e905ad3d9c4d6;hp=23ee5ab105aec8316f598e42b261f2a4d4297bd2;hpb=d5e1be03eda2e8036f136fdf12a5f5d9e1e684d8;p=oota-llvm.git diff --git a/lib/Support/PrettyStackTrace.cpp b/lib/Support/PrettyStackTrace.cpp index 23ee5ab105a..987778a1bde 100644 --- a/lib/Support/PrettyStackTrace.cpp +++ b/lib/Support/PrettyStackTrace.cpp @@ -13,8 +13,10 @@ //===----------------------------------------------------------------------===// #include "llvm/Support/PrettyStackTrace.h" +#include "llvm-c/Core.h" #include "llvm/ADT/SmallString.h" #include "llvm/Config/config.h" // Get autoconf configuration settings +#include "llvm/Support/ManagedStatic.h" #include "llvm/Support/Signals.h" #include "llvm/Support/ThreadLocal.h" #include "llvm/Support/Watchdog.h" @@ -26,12 +28,7 @@ using namespace llvm; -namespace llvm { - bool DisablePrettyStackTrace = false; -} - -// FIXME: This should be thread local when llvm supports threads. -static sys::ThreadLocal PrettyStackTraceHead; +static ManagedStatic > PrettyStackTraceHead; static unsigned PrintStack(const PrettyStackTraceEntry *Entry, raw_ostream &OS){ unsigned NextID = 0; @@ -49,12 +46,12 @@ static unsigned PrintStack(const PrettyStackTraceEntry *Entry, raw_ostream &OS){ /// PrintCurStackTrace - Print the current stack trace to the specified stream. static void PrintCurStackTrace(raw_ostream &OS) { // Don't print an empty trace. - if (PrettyStackTraceHead.get() == 0) return; + if (!PrettyStackTraceHead->get()) return; // If there are pretty stack frames registered, walk and emit them. OS << "Stack dump:\n"; - PrintStack(PrettyStackTraceHead.get(), OS); + PrintStack(PrettyStackTraceHead->get(), OS); OS.flush(); } @@ -102,26 +99,28 @@ static void CrashHandler(void *) { #endif } -static bool RegisterCrashPrinter() { - if (!DisablePrettyStackTrace) - sys::AddSignalHandler(CrashHandler, 0); - return false; -} - PrettyStackTraceEntry::PrettyStackTraceEntry() { - // The first time this is called, we register the crash printer. - static bool HandlerRegistered = RegisterCrashPrinter(); - (void)HandlerRegistered; - // Link ourselves. - NextEntry = PrettyStackTraceHead.get(); - PrettyStackTraceHead.set(this); + NextEntry = PrettyStackTraceHead->get(); + PrettyStackTraceHead->set(this); } PrettyStackTraceEntry::~PrettyStackTraceEntry() { - assert(PrettyStackTraceHead.get() == this && + // Do nothing if PrettyStackTraceHead is uninitialized. This can only happen + // if a shutdown occurred after we created the PrettyStackTraceEntry. That + // does occur in the following idiom: + // + // PrettyStackTraceProgram X(...); + // llvm_shutdown_obj Y; + // + // Without this check, we may end up removing ourselves from the stack trace + // after PrettyStackTraceHead has already been destroyed. + if (!PrettyStackTraceHead.isConstructed()) + return; + + assert(PrettyStackTraceHead->get() == this && "Pretty stack trace entry destruction is out of order"); - PrettyStackTraceHead.set(getNextEntry()); + PrettyStackTraceHead->set(getNextEntry()); } void PrettyStackTraceString::print(raw_ostream &OS) const { @@ -135,3 +134,18 @@ void PrettyStackTraceProgram::print(raw_ostream &OS) const { OS << ArgV[i] << ' '; OS << '\n'; } + +static bool RegisterCrashPrinter() { + sys::AddSignalHandler(CrashHandler, nullptr); + return false; +} + +void llvm::EnablePrettyStackTrace() { + // The first time this is called, we register the crash printer. + static bool HandlerRegistered = RegisterCrashPrinter(); + (void)HandlerRegistered; +} + +void LLVMEnablePrettyStackTrace() { + EnablePrettyStackTrace(); +}