[llvm] r190730 - Make PrettyStackTraceEntry use ManagedStatic for its ThreadLocal.

Filip Pizlo fpizlo at apple.com
Fri Sep 13 15:59:47 PDT 2013


Author: fpizlo
Date: Fri Sep 13 17:59:47 2013
New Revision: 190730

URL: http://llvm.org/viewvc/llvm-project?rev=190730&view=rev
Log:
Make PrettyStackTraceEntry use ManagedStatic for its ThreadLocal.

This was somewhat tricky because ~PrettyStackTraceEntry() may run after 
llvm_shutdown() has been called. This is rare and only happens for a common idiom 
used in the main() functions of command-line tools. This works around the idiom by 
skipping the stack clean-up if the PrettyStackTraceHead ManagedStatic is not 
constructed (i.e. llvm_shutdown() has been called).


Modified:
    llvm/trunk/include/llvm/Support/ManagedStatic.h
    llvm/trunk/lib/Support/PrettyStackTrace.cpp

Modified: llvm/trunk/include/llvm/Support/ManagedStatic.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/ManagedStatic.h?rev=190730&r1=190729&r2=190730&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Support/ManagedStatic.h (original)
+++ llvm/trunk/include/llvm/Support/ManagedStatic.h Fri Sep 13 17:59:47 2013
@@ -99,7 +99,6 @@ public:
 /// llvm_shutdown - Deallocate and destroy all ManagedStatic variables.
 void llvm_shutdown();
 
-
 /// llvm_shutdown_obj - This is a simple helper class that calls
 /// llvm_shutdown() when it is destroyed.
 struct llvm_shutdown_obj {

Modified: llvm/trunk/lib/Support/PrettyStackTrace.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/PrettyStackTrace.cpp?rev=190730&r1=190729&r2=190730&view=diff
==============================================================================
--- llvm/trunk/lib/Support/PrettyStackTrace.cpp (original)
+++ llvm/trunk/lib/Support/PrettyStackTrace.cpp Fri Sep 13 17:59:47 2013
@@ -15,6 +15,7 @@
 #include "llvm/Support/PrettyStackTrace.h"
 #include "llvm/ADT/SmallString.h"
 #include "llvm/Config/config.h"     // Get autoconf configuration settings
+#include "llvm/Support/ManagedStatic.h"
 #include "llvm/Support/Signals.h"
 #include "llvm/Support/ThreadLocal.h"
 #include "llvm/Support/Watchdog.h"
@@ -30,8 +31,7 @@ namespace llvm {
   bool DisablePrettyStackTrace = false;
 }
 
-// FIXME: This should be thread local when llvm supports threads.
-static sys::ThreadLocal<const PrettyStackTraceEntry> PrettyStackTraceHead;
+static ManagedStatic<sys::ThreadLocal<const PrettyStackTraceEntry> > PrettyStackTraceHead;
 
 static unsigned PrintStack(const PrettyStackTraceEntry *Entry, raw_ostream &OS){
   unsigned NextID = 0;
@@ -49,12 +49,12 @@ static unsigned PrintStack(const PrettyS
 /// PrintCurStackTrace - Print the current stack trace to the specified stream.
 static void PrintCurStackTrace(raw_ostream &OS) {
   // Don't print an empty trace.
-  if (PrettyStackTraceHead.get() == 0) return;
+  if (PrettyStackTraceHead->get() == 0) return;
   
   // If there are pretty stack frames registered, walk and emit them.
   OS << "Stack dump:\n";
   
-  PrintStack(PrettyStackTraceHead.get(), OS);
+  PrintStack(PrettyStackTraceHead->get(), OS);
   OS.flush();
 }
 
@@ -114,14 +114,26 @@ PrettyStackTraceEntry::PrettyStackTraceE
   (void)HandlerRegistered;
     
   // Link ourselves.
-  NextEntry = PrettyStackTraceHead.get();
-  PrettyStackTraceHead.set(this);
+  NextEntry = PrettyStackTraceHead->get();
+  PrettyStackTraceHead->set(this);
 }
 
 PrettyStackTraceEntry::~PrettyStackTraceEntry() {
-  assert(PrettyStackTraceHead.get() == this &&
+  // Do nothing if PrettyStackTraceHead is uninitialized. This can only happen
+  // if a shutdown occurred after we created the PrettyStackTraceEntry. That
+  // does occur in the following idiom:
+  //
+  // PrettyStackTraceProgram X(...);
+  // llvm_shutdown_obj Y;
+  //
+  // Without this check, we may end up removing ourselves from the stack trace
+  // after PrettyStackTraceHead has already been destroyed.
+  if (!PrettyStackTraceHead.isConstructed())
+    return;
+  
+  assert(PrettyStackTraceHead->get() == this &&
          "Pretty stack trace entry destruction is out of order");
-  PrettyStackTraceHead.set(getNextEntry());
+  PrettyStackTraceHead->set(getNextEntry());
 }
 
 void PrettyStackTraceString::print(raw_ostream &OS) const {





More information about the llvm-commits mailing list