diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2016-05-26 20:21:55 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2016-05-26 20:21:55 +0000 |
commit | 3de58a5e421baaf0c7f3cd36b602c8df4f4f39f6 (patch) | |
tree | 23a8885c12a1cdcb41e946b8071dd8ad97be38d2 /llvm/lib/Support/PrettyStackTrace.cpp | |
parent | 23a217dce6763ce0bd817e9c3ed536c63aab93be (diff) | |
download | bcm5719-llvm-3de58a5e421baaf0c7f3cd36b602c8df4f4f39f6.tar.gz bcm5719-llvm-3de58a5e421baaf0c7f3cd36b602c8df4f4f39f6.zip |
Don't use recursion to print out the PrettyStackTrace after a crash. If the
crash was due to a stack overflow, chances are good that this would also cause
a stack overflow.
llvm-svn: 270903
Diffstat (limited to 'llvm/lib/Support/PrettyStackTrace.cpp')
-rw-r--r-- | llvm/lib/Support/PrettyStackTrace.cpp | 46 |
1 files changed, 30 insertions, 16 deletions
diff --git a/llvm/lib/Support/PrettyStackTrace.cpp b/llvm/lib/Support/PrettyStackTrace.cpp index 05b3e31644b..613416a7f0f 100644 --- a/llvm/lib/Support/PrettyStackTrace.cpp +++ b/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,9 @@ 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 = (PrettyStackTraceEntry*)Top; #endif } |