<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Thu, May 26, 2016 at 1:21 PM, Richard Smith via llvm-commits <span dir="ltr"><<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: rsmith<br>
Date: Thu May 26 15:21:55 2016<br>
New Revision: 270903<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=270903&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project?rev=270903&view=rev</a><br>
Log:<br>
Don't use recursion to print out the PrettyStackTrace after a crash. If the<br>
crash was due to a stack overflow, chances are good that this would also cause<br>
a stack overflow.<br>
<br>
Modified:<br>
llvm/trunk/include/llvm/Support/PrettyStackTrace.h<br>
llvm/trunk/lib/Support/PrettyStackTrace.cpp<br>
<br>
Modified: llvm/trunk/include/llvm/Support/PrettyStackTrace.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/PrettyStackTrace.h?rev=270903&r1=270902&r2=270903&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/PrettyStackTrace.h?rev=270903&r1=270902&r2=270903&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/include/llvm/Support/PrettyStackTrace.h (original)<br>
+++ llvm/trunk/include/llvm/Support/PrettyStackTrace.h Thu May 26 15:21:55 2016<br>
@@ -29,9 +29,11 @@ namespace llvm {<br>
/// constructed and destructed, they will add their symbolic frames to a<br>
/// virtual stack trace. This gets dumped out if the program crashes.<br>
class PrettyStackTraceEntry {<br>
- const PrettyStackTraceEntry *NextEntry;<br>
+ friend PrettyStackTraceEntry *ReverseStackTrace(PrettyStackTraceEntry *);<br>
+<br>
+ PrettyStackTraceEntry *NextEntry;<br>
PrettyStackTraceEntry(const PrettyStackTraceEntry &) = delete;<br>
- void operator=(const PrettyStackTraceEntry&) = delete;<br>
+ void operator=(const PrettyStackTraceEntry &) = delete;<br>
public:<br>
PrettyStackTraceEntry();<br>
virtual ~PrettyStackTraceEntry();<br>
@@ -67,7 +69,7 @@ namespace llvm {<br>
};<br>
<br>
/// Returns the topmost element of the "pretty" stack state.<br>
- const void* SavePrettyStackState();<br>
+ const void *SavePrettyStackState();<br>
<br>
/// Restores the topmost element of the "pretty" stack state to State, which<br>
/// should come from a previous call to SavePrettyStackState(). This is<br>
@@ -76,7 +78,7 @@ namespace llvm {<br>
/// happens after a crash that's been recovered by CrashRecoveryContext<br>
/// doesn't have frames on it that were added in code unwound by the<br>
/// CrashRecoveryContext.<br>
- void RestorePrettyStackState(const void* State);<br>
+ void RestorePrettyStackState(const void *State);<br>
<br>
} // end namespace llvm<br>
<br>
<br>
Modified: llvm/trunk/lib/Support/PrettyStackTrace.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/PrettyStackTrace.cpp?rev=270903&r1=270902&r2=270903&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/PrettyStackTrace.cpp?rev=270903&r1=270902&r2=270903&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Support/PrettyStackTrace.cpp (original)<br>
+++ llvm/trunk/lib/Support/PrettyStackTrace.cpp Thu May 26 15:21:55 2016<br>
@@ -21,6 +21,8 @@<br>
#include "llvm/Support/Watchdog.h"<br>
#include "llvm/Support/raw_ostream.h"<br>
<br>
+#include <tuple><br>
+<br>
#ifdef HAVE_CRASHREPORTERCLIENT_H<br>
#include <CrashReporterClient.h><br>
#endif<br>
@@ -36,20 +38,32 @@ using namespace llvm;<br>
// objects, but we *really* cannot tolerate destructors running and do not want<br>
// to pay any overhead of synchronizing. As a consequence, we use a raw<br>
// thread-local variable.<br>
-static LLVM_THREAD_LOCAL const PrettyStackTraceEntry *PrettyStackTraceHead =<br>
- nullptr;<br>
+static LLVM_THREAD_LOCAL PrettyStackTraceEntry *PrettyStackTraceHead = nullptr;<br>
<br>
-static unsigned PrintStack(const PrettyStackTraceEntry *Entry, raw_ostream &OS){<br>
- unsigned NextID = 0;<br>
- if (Entry->getNextEntry())<br>
- NextID = PrintStack(Entry->getNextEntry(), OS);<br>
- OS << NextID << ".\t";<br>
- {<br>
+namespace llvm {<br>
+PrettyStackTraceEntry *ReverseStackTrace(PrettyStackTraceEntry *Head) {<br>
+ PrettyStackTraceEntry *Prev = nullptr;<br>
+ while (Head)<br>
+ std::tie(Prev, Head, Head->NextEntry) =<br>
+ std::make_tuple(Head, Head->NextEntry, Prev);<br></blockquote><div><br></div><div>Neat trick! Reminds me of the `std::tie(LHS_A,LHS_B,...) < std::tie(RHS_A,RHS_B,...)` trick for lexicographical comparisons.</div><div><br></div><div>-- Sean Silva</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+ return Prev;<br>
+}<br>
+}<br>
+<br>
+static void PrintStack(raw_ostream &OS) {<br>
+ // Print out the stack in reverse order. To avoid recursion (which is likely<br>
+ // to fail if we crashed due to stack overflow), we do an up-front pass to<br>
+ // reverse the stack, then print it, then reverse it again.<br>
+ unsigned ID = 0;<br>
+ PrettyStackTraceEntry *ReversedStack =<br>
+ llvm::ReverseStackTrace(PrettyStackTraceHead);<br>
+ for (const PrettyStackTraceEntry *Entry = ReversedStack; Entry;<br>
+ Entry = Entry->getNextEntry()) {<br>
+ OS << ID++ << ".\t";<br>
sys::Watchdog W(5);<br>
Entry->print(OS);<br>
}<br>
-<br>
- return NextID+1;<br>
+ llvm::ReverseStackTrace(ReversedStack);<br>
}<br>
<br>
/// PrintCurStackTrace - Print the current stack trace to the specified stream.<br>
@@ -60,7 +74,7 @@ static void PrintCurStackTrace(raw_ostre<br>
// If there are pretty stack frames registered, walk and emit them.<br>
OS << "Stack dump:\n";<br>
<br>
- PrintStack(PrettyStackTraceHead, OS);<br>
+ PrintStack(OS);<br>
OS.flush();<br>
}<br>
<br>
@@ -123,7 +137,7 @@ PrettyStackTraceEntry::~PrettyStackTrace<br>
#if defined(HAVE_BACKTRACE) && defined(ENABLE_BACKTRACES)<br>
assert(PrettyStackTraceHead == this &&<br>
"Pretty stack trace entry destruction is out of order");<br>
- PrettyStackTraceHead = getNextEntry();<br>
+ PrettyStackTraceHead = NextEntry;<br>
#endif<br>
}<br>
<br>
@@ -154,7 +168,7 @@ void llvm::EnablePrettyStackTrace() {<br>
#endif<br>
}<br>
<br>
-const void* llvm::SavePrettyStackState() {<br>
+const void *llvm::SavePrettyStackState() {<br>
#if defined(HAVE_BACKTRACE) && defined(ENABLE_BACKTRACES)<br>
return PrettyStackTraceHead;<br>
#else<br>
@@ -162,9 +176,9 @@ const void* llvm::SavePrettyStackState()<br>
#endif<br>
}<br>
<br>
-void llvm::RestorePrettyStackState(const void* Top) {<br>
+void llvm::RestorePrettyStackState(const void *Top) {<br>
#if defined(HAVE_BACKTRACE) && defined(ENABLE_BACKTRACES)<br>
- PrettyStackTraceHead = (const PrettyStackTraceEntry*)Top;<br>
+ PrettyStackTraceHead = (PrettyStackTraceEntry*)Top;<br>
#endif<br>
}<br>
<br>
<br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@lists.llvm.org">llvm-commits@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits</a><br>
</blockquote></div><br></div></div>