From 346a596c504842b498c1c6d592a5df412c866716 Mon Sep 17 00:00:00 2001 From: Timothy Nikkel Date: Mon, 14 Mar 2016 22:59:02 -0500 Subject: [PATCH] Bug 1251150 - Add crash annotations if image visibility is re-entering. r=mats, a=ritu --- gfx/2d/Logging.h | 1 + layout/base/nsPresShell.cpp | 35 +++++++++++++++++++++++++++++++++++ layout/base/nsPresShell.h | 4 ++++ 3 files changed, 40 insertions(+) diff --git a/gfx/2d/Logging.h b/gfx/2d/Logging.h index 4ccc06220b8..da0534c8bdf 100644 --- a/gfx/2d/Logging.h +++ b/gfx/2d/Logging.h @@ -545,6 +545,7 @@ typedef Log CriticalLog; // while the critical error is // gfxCriticalError() << "Something to report and assert"; #define gfxCriticalNote gfxCriticalError(gfxCriticalError::DefaultOptions(false)) +#define gfxCriticalNoteOnce static gfxCriticalError GFX_LOGGING_GLUE(sOnceAtLine,__LINE__) = gfxCriticalNote // The "once" versions will only trigger the first time through. You can do this: // gfxCriticalErrorOnce() << "This message only shows up once; diff --git a/layout/base/nsPresShell.cpp b/layout/base/nsPresShell.cpp index ea1f074f81a..76d3e60ccfa 100644 --- a/layout/base/nsPresShell.cpp +++ b/layout/base/nsPresShell.cpp @@ -5541,6 +5541,9 @@ PresShell::MarkImagesInListVisible(const nsDisplayList& aList) void PresShell::ReportAnyBadState() { + if (!NS_IsMainThread()) { + gfxCriticalNote << "Got null image in image visibility: off-main-thread"; + } if (mIsZombie) { gfxCriticalNote << "Got null image in image visibility: mIsZombie"; } @@ -5567,6 +5570,12 @@ PresShell::ReportAnyBadState() } } +void +PresShell::SetInImageVisibility(bool aState) +{ + mInImageVisibility = aState; +} + static void DecrementVisibleCount(nsTHashtable>& aImages, uint32_t aNonvisibleAction, PresShell* aPresShell) @@ -5577,7 +5586,9 @@ DecrementVisibleCount(nsTHashtable>& aIm // help debug the crash (bug 1251150) aPresShell->ReportAnyBadState(); } + aPresShell->SetInImageVisibility(true); iter.Get()->GetKey()->DecrementVisibleCount(aNonvisibleAction); + aPresShell->SetInImageVisibility(false); } } @@ -5615,6 +5626,10 @@ PresShell::ClearImageVisibilityVisited(nsView* aView, bool aClear) void PresShell::ClearVisibleImagesList(uint32_t aNonvisibleAction) { + if (mInImageVisibility) { + gfxCriticalNoteOnce << "ClearVisibleImagesList is re-entering on " + << (NS_IsMainThread() ? "" : "non-") << "main thread"; + } DecrementVisibleCount(mVisibleImages, aNonvisibleAction, this); mVisibleImages.Clear(); } @@ -5720,6 +5735,11 @@ PresShell::RebuildImageVisibility(nsRect* aRect, return; } + if (mInImageVisibility) { + gfxCriticalNoteOnce << "RebuildImageVisibility is re-entering on " + << (NS_IsMainThread() ? "" : "non-") << "main thread"; + } + // Remove the entries of the mVisibleImages hashtable and put them in // oldVisibleImages. nsTHashtable< nsRefPtrHashKey > oldVisibleImages; @@ -5873,6 +5893,11 @@ PresShell::EnsureImageInVisibleList(nsIImageLoadingContent* aImage) } #endif + if (mInImageVisibility) { + gfxCriticalNoteOnce << "EnsureImageInVisibleList is re-entering on " + << (NS_IsMainThread() ? "" : "non-") << "main thread"; + } + if (!mVisibleImages.Contains(aImage)) { mVisibleImages.PutEntry(aImage); aImage->IncrementVisibleCount(); @@ -5896,6 +5921,11 @@ PresShell::RemoveImageFromVisibleList(nsIImageLoadingContent* aImage) return; } + if (mInImageVisibility) { + gfxCriticalNoteOnce << "RemoveImageFromVisibleList is re-entering on " + << (NS_IsMainThread() ? "" : "non-") << "main thread"; + } + uint32_t count = mVisibleImages.Count(); mVisibleImages.RemoveEntry(aImage); if (mVisibleImages.Count() < count) { @@ -10657,6 +10687,11 @@ PresShell::UpdateImageLockingState() nsresult rv = mDocument->SetImageLockingState(locked); if (locked) { + if (mInImageVisibility) { + gfxCriticalNoteOnce << "UpdateImageLockingState is re-entering on " + << (NS_IsMainThread() ? "" : "non-") << "main thread"; + } + // Request decodes for visible images; we want to start decoding as // quickly as possible when we get foregrounded to minimize flashing. for (auto iter = mVisibleImages.Iter(); !iter.Done(); iter.Next()) { diff --git a/layout/base/nsPresShell.h b/layout/base/nsPresShell.h index 7955ba8d385..6b80569eec1 100644 --- a/layout/base/nsPresShell.h +++ b/layout/base/nsPresShell.h @@ -394,6 +394,8 @@ public: void ReportAnyBadState(); + void SetInImageVisibility(bool aState); + protected: virtual ~PresShell(); @@ -885,6 +887,8 @@ protected: // Whether the widget has received a paint message yet. bool mHasReceivedPaintMessage : 1; + bool mInImageVisibility : 1; + static bool sDisableNonTestMouseEvents; };