|
@@ -21,6 +21,8 @@
|
|
#include "llvm/Support/Watchdog.h"
|
|
#include "llvm/Support/Watchdog.h"
|
|
#include "llvm/Support/raw_ostream.h"
|
|
#include "llvm/Support/raw_ostream.h"
|
|
|
|
|
|
|
|
+#include <tuple>
|
|
|
|
+
|
|
#ifdef HAVE_CRASHREPORTERCLIENT_H
|
|
#ifdef HAVE_CRASHREPORTERCLIENT_H
|
|
#include <CrashReporterClient.h>
|
|
#include <CrashReporterClient.h>
|
|
#endif
|
|
#endif
|
|
@@ -36,20 +38,32 @@ using namespace llvm;
|
|
// objects, but we *really* cannot tolerate destructors running and do not want
|
|
// 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
|
|
// to pay any overhead of synchronizing. As a consequence, we use a raw
|
|
// thread-local variable.
|
|
// 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);
|
|
sys::Watchdog W(5);
|
|
Entry->print(OS);
|
|
Entry->print(OS);
|
|
}
|
|
}
|
|
-
|
|
|
|
- return NextID+1;
|
|
|
|
|
|
+ llvm::ReverseStackTrace(ReversedStack);
|
|
}
|
|
}
|
|
|
|
|
|
/// PrintCurStackTrace - Print the current stack trace to the specified stream.
|
|
/// 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.
|
|
// If there are pretty stack frames registered, walk and emit them.
|
|
OS << "Stack dump:\n";
|
|
OS << "Stack dump:\n";
|
|
|
|
|
|
- PrintStack(PrettyStackTraceHead, OS);
|
|
|
|
|
|
+ PrintStack(OS);
|
|
OS.flush();
|
|
OS.flush();
|
|
}
|
|
}
|
|
|
|
|
|
@@ -123,7 +137,7 @@ PrettyStackTraceEntry::~PrettyStackTraceEntry() {
|
|
#if defined(HAVE_BACKTRACE) && defined(ENABLE_BACKTRACES)
|
|
#if defined(HAVE_BACKTRACE) && defined(ENABLE_BACKTRACES)
|
|
assert(PrettyStackTraceHead == this &&
|
|
assert(PrettyStackTraceHead == this &&
|
|
"Pretty stack trace entry destruction is out of order");
|
|
"Pretty stack trace entry destruction is out of order");
|
|
- PrettyStackTraceHead = getNextEntry();
|
|
|
|
|
|
+ PrettyStackTraceHead = NextEntry;
|
|
#endif
|
|
#endif
|
|
}
|
|
}
|
|
|
|
|
|
@@ -154,7 +168,7 @@ void llvm::EnablePrettyStackTrace() {
|
|
#endif
|
|
#endif
|
|
}
|
|
}
|
|
|
|
|
|
-const void* llvm::SavePrettyStackState() {
|
|
|
|
|
|
+const void *llvm::SavePrettyStackState() {
|
|
#if defined(HAVE_BACKTRACE) && defined(ENABLE_BACKTRACES)
|
|
#if defined(HAVE_BACKTRACE) && defined(ENABLE_BACKTRACES)
|
|
return PrettyStackTraceHead;
|
|
return PrettyStackTraceHead;
|
|
#else
|
|
#else
|
|
@@ -162,9 +176,9 @@ const void* llvm::SavePrettyStackState() {
|
|
#endif
|
|
#endif
|
|
}
|
|
}
|
|
|
|
|
|
-void llvm::RestorePrettyStackState(const void* Top) {
|
|
|
|
|
|
+void llvm::RestorePrettyStackState(const void *Top) {
|
|
#if defined(HAVE_BACKTRACE) && defined(ENABLE_BACKTRACES)
|
|
#if defined(HAVE_BACKTRACE) && defined(ENABLE_BACKTRACES)
|
|
- PrettyStackTraceHead = (const PrettyStackTraceEntry*)Top;
|
|
|
|
|
|
+ PrettyStackTraceHead = (PrettyStackTraceEntry*)Top;
|
|
#endif
|
|
#endif
|
|
}
|
|
}
|
|
|
|
|