Bug 872947 - Release pseudostack when unregister thread. r=snorp
authorBenoit Girard <b56girard@gmail.com>
Thu, 16 May 2013 11:38:23 -0400
changeset 136624 0f758ffc6db1a67cf06f0fb458c6ea36f9044a2e
parent 136623 a1f379973add3378873ed01a5b66e319e0614a1d
child 136625 b7b799dc6cf914e5e0cb15752ade567b9e367fbf
push id24889
push useremorley@mozilla.com
push dateThu, 27 Jun 2013 10:31:05 +0000
treeherdermozilla-central@b8a80bf3f9da [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssnorp
bugs872947
milestone25.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 872947 - Release pseudostack when unregister thread. r=snorp
tools/profiler/PseudoStack.h
tools/profiler/platform.cpp
--- a/tools/profiler/PseudoStack.h
+++ b/tools/profiler/PseudoStack.h
@@ -109,16 +109,28 @@ public:
     , mSignalLock(false)
     , mMarkerPointer(0)
     , mQueueClearMarker(false)
     , mRuntime(nullptr)
     , mStartJSSampling(false)
     , mPrivacyMode(false)
   { }
 
+  ~PseudoStack() {
+    clearMarkers();
+    if (mStackPointer != 0 || mSignalLock != false ||
+        mMarkerPointer != 0) {
+      // We're releasing the pseudostack while it's still in use.
+      // The label macros keep a non ref counted reference to the
+      // stack to avoid a TLS. If these are not all cleared we will
+      // get a use-after-free so better to crash now.
+      abort();
+    }
+  }
+
   void addMarker(const char *aMarker)
   {
     char* markerCopy = strdup(aMarker);
     mSignalLock = true;
     STORE_SEQUENCER();
 
     if (mQueueClearMarker) {
       clearMarkers();
--- a/tools/profiler/platform.cpp
+++ b/tools/profiler/platform.cpp
@@ -588,16 +588,24 @@ bool mozilla_sampler_register_thread(con
   tlsPseudoStack.set(stack);
 
   return Sampler::RegisterCurrentThread(aName, stack, false, stackTop);
 }
 
 void mozilla_sampler_unregister_thread()
 {
   Sampler::UnregisterCurrentThread();
+
+  PseudoStack *stack = tlsPseudoStack.get();
+  if (!stack) {
+    ASSERT(false);
+    return;
+  }
+  delete stack;
+  tlsPseudoStack.set(nullptr);
 }
 
 double mozilla_sampler_time()
 {
   TimeDuration delta = TimeStamp::Now() - sStartTime;
   return delta.ToMilliseconds();
 }