diff options
Diffstat (limited to 'contrib/llvm/lib/Support/PrettyStackTrace.cpp')
-rw-r--r-- | contrib/llvm/lib/Support/PrettyStackTrace.cpp | 47 |
1 files changed, 31 insertions, 16 deletions
diff --git a/contrib/llvm/lib/Support/PrettyStackTrace.cpp b/contrib/llvm/lib/Support/PrettyStackTrace.cpp index 05b3e31..ebad67b 100644 --- a/contrib/llvm/lib/Support/PrettyStackTrace.cpp +++ b/contrib/llvm/lib/Support/PrettyStackTrace.cpp @@ -21,6 +21,8 @@ #include "llvm/Support/Watchdog.h" #include "llvm/Support/raw_ostream.h" +#include <tuple> + #ifdef HAVE_CRASHREPORTERCLIENT_H #include <CrashReporterClient.h> #endif @@ -36,20 +38,32 @@ using namespace llvm; // objects, but we *really* cannot tolerate destructors running and do not want // to pay any overhead of synchronizing. As a consequence, we use a raw // thread-local variable. -static LLVM_THREAD_LOCAL const PrettyStackTraceEntry *PrettyStackTraceHead = - nullptr; - -static unsigned PrintStack(const PrettyStackTraceEntry *Entry, raw_ostream &OS){ - unsigned NextID = 0; - if (Entry->getNextEntry()) - NextID = PrintStack(Entry->getNextEntry(), OS); - OS << NextID << ".\t"; - { +static LLVM_THREAD_LOCAL PrettyStackTraceEntry *PrettyStackTraceHead = nullptr; + +namespace llvm { +PrettyStackTraceEntry *ReverseStackTrace(PrettyStackTraceEntry *Head) { + PrettyStackTraceEntry *Prev = nullptr; + while (Head) + std::tie(Prev, Head, Head->NextEntry) = + std::make_tuple(Head, Head->NextEntry, Prev); + return Prev; +} +} + +static void PrintStack(raw_ostream &OS) { + // Print out the stack in reverse order. To avoid recursion (which is likely + // to fail if we crashed due to stack overflow), we do an up-front pass to + // reverse the stack, then print it, then reverse it again. + unsigned ID = 0; + PrettyStackTraceEntry *ReversedStack = + llvm::ReverseStackTrace(PrettyStackTraceHead); + for (const PrettyStackTraceEntry *Entry = ReversedStack; Entry; + Entry = Entry->getNextEntry()) { + OS << ID++ << ".\t"; sys::Watchdog W(5); Entry->print(OS); } - - return NextID+1; + llvm::ReverseStackTrace(ReversedStack); } /// PrintCurStackTrace - Print the current stack trace to the specified stream. @@ -60,7 +74,7 @@ static void PrintCurStackTrace(raw_ostream &OS) { // If there are pretty stack frames registered, walk and emit them. OS << "Stack dump:\n"; - PrintStack(PrettyStackTraceHead, OS); + PrintStack(OS); OS.flush(); } @@ -123,7 +137,7 @@ PrettyStackTraceEntry::~PrettyStackTraceEntry() { #if defined(HAVE_BACKTRACE) && defined(ENABLE_BACKTRACES) assert(PrettyStackTraceHead == this && "Pretty stack trace entry destruction is out of order"); - PrettyStackTraceHead = getNextEntry(); + PrettyStackTraceHead = NextEntry; #endif } @@ -154,7 +168,7 @@ void llvm::EnablePrettyStackTrace() { #endif } -const void* llvm::SavePrettyStackState() { +const void *llvm::SavePrettyStackState() { #if defined(HAVE_BACKTRACE) && defined(ENABLE_BACKTRACES) return PrettyStackTraceHead; #else @@ -162,9 +176,10 @@ const void* llvm::SavePrettyStackState() { #endif } -void llvm::RestorePrettyStackState(const void* Top) { +void llvm::RestorePrettyStackState(const void *Top) { #if defined(HAVE_BACKTRACE) && defined(ENABLE_BACKTRACES) - PrettyStackTraceHead = (const PrettyStackTraceEntry*)Top; + PrettyStackTraceHead = + static_cast<PrettyStackTraceEntry *>(const_cast<void *>(Top)); #endif } |