[llvm] r270903 - Don't use recursion to print out the PrettyStackTrace after a crash. If the

Sean Silva via llvm-commits llvm-commits at lists.llvm.org
Fri May 27 00:51:58 PDT 2016


On Thu, May 26, 2016 at 1:21 PM, Richard Smith via llvm-commits <
llvm-commits at lists.llvm.org> wrote:

> Author: rsmith
> Date: Thu May 26 15:21:55 2016
> New Revision: 270903
>
> URL: http://llvm.org/viewvc/llvm-project?rev=270903&view=rev
> Log:
> 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.
>
> Modified:
>     llvm/trunk/include/llvm/Support/PrettyStackTrace.h
>     llvm/trunk/lib/Support/PrettyStackTrace.cpp
>
> Modified: llvm/trunk/include/llvm/Support/PrettyStackTrace.h
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/PrettyStackTrace.h?rev=270903&r1=270902&r2=270903&view=diff
>
> ==============================================================================
> --- llvm/trunk/include/llvm/Support/PrettyStackTrace.h (original)
> +++ llvm/trunk/include/llvm/Support/PrettyStackTrace.h Thu May 26 15:21:55
> 2016
> @@ -29,9 +29,11 @@ namespace llvm {
>    /// constructed and destructed, they will add their symbolic frames to a
>    /// virtual stack trace.  This gets dumped out if the program crashes.
>    class PrettyStackTraceEntry {
> -    const PrettyStackTraceEntry *NextEntry;
> +    friend PrettyStackTraceEntry *ReverseStackTrace(PrettyStackTraceEntry
> *);
> +
> +    PrettyStackTraceEntry *NextEntry;
>      PrettyStackTraceEntry(const PrettyStackTraceEntry &) = delete;
> -    void operator=(const PrettyStackTraceEntry&) = delete;
> +    void operator=(const PrettyStackTraceEntry &) = delete;
>    public:
>      PrettyStackTraceEntry();
>      virtual ~PrettyStackTraceEntry();
> @@ -67,7 +69,7 @@ namespace llvm {
>    };
>
>    /// Returns the topmost element of the "pretty" stack state.
> -  const void* SavePrettyStackState();
> +  const void *SavePrettyStackState();
>
>    /// Restores the topmost element of the "pretty" stack state to State,
> which
>    /// should come from a previous call to SavePrettyStackState().  This is
> @@ -76,7 +78,7 @@ namespace llvm {
>    /// happens after a crash that's been recovered by CrashRecoveryContext
>    /// doesn't have frames on it that were added in code unwound by the
>    /// CrashRecoveryContext.
> -  void RestorePrettyStackState(const void* State);
> +  void RestorePrettyStackState(const void *State);
>
>  } // end namespace llvm
>
>
> Modified: llvm/trunk/lib/Support/PrettyStackTrace.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/PrettyStackTrace.cpp?rev=270903&r1=270902&r2=270903&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/Support/PrettyStackTrace.cpp (original)
> +++ llvm/trunk/lib/Support/PrettyStackTrace.cpp Thu May 26 15:21:55 2016
> @@ -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 LLVM_THREAD_LOCAL 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";
> -  {
> +namespace llvm {
> +PrettyStackTraceEntry *ReverseStackTrace(PrettyStackTraceEntry *Head) {
> +  PrettyStackTraceEntry *Prev = nullptr;
> +  while (Head)
> +    std::tie(Prev, Head, Head->NextEntry) =
> +        std::make_tuple(Head, Head->NextEntry, Prev);
>

Neat trick! Reminds me of the `std::tie(LHS_A,LHS_B,...) <
std::tie(RHS_A,RHS_B,...)` trick for lexicographical comparisons.

-- Sean Silva


> +  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_ostre
>    // 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::~PrettyStackTrace
>  #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
>  }
>
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20160527/72086418/attachment.html>


More information about the llvm-commits mailing list