<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>