Bug 1251150 - Add some crash annotations to try to track down a crash bug. r=dholbert, a=ritu
authorTimothy Nikkel <tnikkel@gmail.com>
Thu, 10 Mar 2016 00:37:19 -0600
changeset 323640 2d1dca51243a0f40ffb1d37b4807fef196e08aee
parent 323639 84917fc810b3655b8ef913d3da20140484764b89
child 323641 6fb4fbd3b8feb67f9aa94f7c942f93afcbed4929
push id5913
push userjlund@mozilla.com
push dateMon, 25 Apr 2016 16:57:49 +0000
treeherdermozilla-beta@dcaf0a6fa115 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdholbert, ritu
bugs1251150
milestone47.0a2
Bug 1251150 - Add some crash annotations to try to track down a crash bug. r=dholbert, a=ritu
layout/base/nsPresShell.cpp
layout/base/nsPresShell.h
--- a/layout/base/nsPresShell.cpp
+++ b/layout/base/nsPresShell.cpp
@@ -5533,37 +5533,71 @@ PresShell::MarkImagesInListVisible(const
       if (presShell->mVisibleImages.Count() > count) {
         // content was added to mVisibleImages, so we need to increment its visible count
         content->IncrementVisibleCount();
       }
     }
   }
 }
 
+void
+PresShell::ReportAnyBadState()
+{
+  if (mIsZombie) {
+    gfxCriticalNote << "Got null image in image visibility: mIsZombie";
+  }
+  if (mIsDestroying) {
+    gfxCriticalNote << "Got null image in image visibility: mIsDestroying";
+  }
+  if (mIsReflowing) {
+    gfxCriticalNote << "Got null image in image visibility: mIsReflowing";
+  }
+  if (mPaintingIsFrozen) {
+    gfxCriticalNote << "Got null image in image visibility: mPaintingIsFrozen";
+  }
+  if (mForwardingContainer) {
+    gfxCriticalNote << "Got null image in image visibility: mForwardingContainer";
+  }
+  if (mIsNeverPainting) {
+    gfxCriticalNote << "Got null image in image visibility: mIsNeverPainting";
+  }
+  if (mIsDocumentGone) {
+    gfxCriticalNote << "Got null image in image visibility: mIsDocumentGone";
+  }
+  if (!nsContentUtils::IsSafeToRunScript()) {
+    gfxCriticalNote << "Got null image in image visibility: not safe to run script";
+  }
+}
+
 static void
 DecrementVisibleCount(nsTHashtable<nsRefPtrHashKey<nsIImageLoadingContent>>& aImages,
-                      uint32_t aNonvisibleAction)
+                      uint32_t aNonvisibleAction, PresShell* aPresShell)
 {
   for (auto iter = aImages.Iter(); !iter.Done(); iter.Next()) {
+    if (MOZ_UNLIKELY(!iter.Get()->GetKey())) {
+      // We are about to crash, annotate crash report with some info that might
+      // help debug the crash (bug 1251150)
+      aPresShell->ReportAnyBadState();
+    }
     iter.Get()->GetKey()->DecrementVisibleCount(aNonvisibleAction);
   }
 }
 
 void
 PresShell::RebuildImageVisibilityDisplayList(const nsDisplayList& aList)
 {
   MOZ_ASSERT(!mImageVisibilityVisited, "already visited?");
   mImageVisibilityVisited = true;
   // Remove the entries of the mVisibleImages hashtable and put them in
   // oldVisibleImages.
   nsTHashtable< nsRefPtrHashKey<nsIImageLoadingContent> > oldVisibleImages;
   mVisibleImages.SwapElements(oldVisibleImages);
   MarkImagesInListVisible(aList);
   DecrementVisibleCount(oldVisibleImages,
-                        nsIImageLoadingContent::ON_NONVISIBLE_NO_ACTION);
+                        nsIImageLoadingContent::ON_NONVISIBLE_NO_ACTION, this);
 }
 
 /* static */ void
 PresShell::ClearImageVisibilityVisited(nsView* aView, bool aClear)
 {
   nsViewManager* vm = aView->GetViewManager();
   if (aClear) {
     PresShell* presShell = static_cast<PresShell*>(vm->GetPresShell());
@@ -5576,17 +5610,17 @@ PresShell::ClearImageVisibilityVisited(n
   for (nsView* v = aView->GetFirstChild(); v; v = v->GetNextSibling()) {
     ClearImageVisibilityVisited(v, v->GetViewManager() != vm);
   }
 }
 
 void
 PresShell::ClearVisibleImagesList(uint32_t aNonvisibleAction)
 {
-  DecrementVisibleCount(mVisibleImages, aNonvisibleAction);
+  DecrementVisibleCount(mVisibleImages, aNonvisibleAction, this);
   mVisibleImages.Clear();
 }
 
 void
 PresShell::MarkImagesInSubtreeVisible(nsIFrame* aFrame,
                                       const nsRect& aRect,
                                       bool aRemoveOnly /* = false */)
 {
@@ -5693,17 +5727,17 @@ PresShell::RebuildImageVisibility(nsRect
 
   nsRect vis(nsPoint(0, 0), rootFrame->GetSize());
   if (aRect) {
     vis = *aRect;
   }
   MarkImagesInSubtreeVisible(rootFrame, vis, aRemoveOnly);
 
   DecrementVisibleCount(oldVisibleImages,
-                        nsIImageLoadingContent::ON_NONVISIBLE_NO_ACTION);
+                        nsIImageLoadingContent::ON_NONVISIBLE_NO_ACTION, this);
 }
 
 void
 PresShell::UpdateImageVisibility()
 {
   DoUpdateImageVisibility(/* aRemoveOnly = */ false);
 }
 
--- a/layout/base/nsPresShell.h
+++ b/layout/base/nsPresShell.h
@@ -387,16 +387,18 @@ public:
   virtual void RecordShadowStyleChange(mozilla::dom::ShadowRoot* aShadowRoot) override;
 
   virtual void DispatchAfterKeyboardEvent(nsINode* aTarget,
                                           const mozilla::WidgetKeyboardEvent& aEvent,
                                           bool aEmbeddedCancelled) override;
 
   void SetNextPaintCompressed() { mNextPaintCompressed = true; }
 
+  void ReportAnyBadState();
+
 protected:
   virtual ~PresShell();
 
   void HandlePostedReflowCallbacks(bool aInterruptible);
   void CancelPostedReflowCallbacks();
 
   void ScheduleBeforeFirstPaint();
   void UnsuppressAndInvalidate();