summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Support/PrettyStackTrace.cpp
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2016-05-26 20:21:55 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2016-05-26 20:21:55 +0000
commit3de58a5e421baaf0c7f3cd36b602c8df4f4f39f6 (patch)
tree23a8885c12a1cdcb41e946b8071dd8ad97be38d2 /llvm/lib/Support/PrettyStackTrace.cpp
parent23a217dce6763ce0bd817e9c3ed536c63aab93be (diff)
downloadbcm5719-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.cpp46
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
}
OpenPOWER on IntegriCloud