Bug 1251150 - Add crash annotations if image visibility is re-entering. r=mats, a=ritu

This commit is contained in:
Timothy Nikkel 2016-03-14 22:59:02 -05:00
parent 3777573189
commit 346a596c50
3 changed files with 40 additions and 0 deletions

View File

@ -545,6 +545,7 @@ typedef Log<LOG_CRITICAL, CriticalLogger> CriticalLog;
// while the critical error is // while the critical error is
// gfxCriticalError() << "Something to report and assert"; // gfxCriticalError() << "Something to report and assert";
#define gfxCriticalNote gfxCriticalError(gfxCriticalError::DefaultOptions(false)) #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: // The "once" versions will only trigger the first time through. You can do this:
// gfxCriticalErrorOnce() << "This message only shows up once; // gfxCriticalErrorOnce() << "This message only shows up once;

View File

@ -5541,6 +5541,9 @@ PresShell::MarkImagesInListVisible(const nsDisplayList& aList)
void void
PresShell::ReportAnyBadState() PresShell::ReportAnyBadState()
{ {
if (!NS_IsMainThread()) {
gfxCriticalNote << "Got null image in image visibility: off-main-thread";
}
if (mIsZombie) { if (mIsZombie) {
gfxCriticalNote << "Got null image in image visibility: mIsZombie"; gfxCriticalNote << "Got null image in image visibility: mIsZombie";
} }
@ -5567,6 +5570,12 @@ PresShell::ReportAnyBadState()
} }
} }
void
PresShell::SetInImageVisibility(bool aState)
{
mInImageVisibility = aState;
}
static void static void
DecrementVisibleCount(nsTHashtable<nsRefPtrHashKey<nsIImageLoadingContent>>& aImages, DecrementVisibleCount(nsTHashtable<nsRefPtrHashKey<nsIImageLoadingContent>>& aImages,
uint32_t aNonvisibleAction, PresShell* aPresShell) uint32_t aNonvisibleAction, PresShell* aPresShell)
@ -5577,7 +5586,9 @@ DecrementVisibleCount(nsTHashtable<nsRefPtrHashKey<nsIImageLoadingContent>>& aIm
// help debug the crash (bug 1251150) // help debug the crash (bug 1251150)
aPresShell->ReportAnyBadState(); aPresShell->ReportAnyBadState();
} }
aPresShell->SetInImageVisibility(true);
iter.Get()->GetKey()->DecrementVisibleCount(aNonvisibleAction); iter.Get()->GetKey()->DecrementVisibleCount(aNonvisibleAction);
aPresShell->SetInImageVisibility(false);
} }
} }
@ -5615,6 +5626,10 @@ PresShell::ClearImageVisibilityVisited(nsView* aView, bool aClear)
void void
PresShell::ClearVisibleImagesList(uint32_t aNonvisibleAction) PresShell::ClearVisibleImagesList(uint32_t aNonvisibleAction)
{ {
if (mInImageVisibility) {
gfxCriticalNoteOnce << "ClearVisibleImagesList is re-entering on "
<< (NS_IsMainThread() ? "" : "non-") << "main thread";
}
DecrementVisibleCount(mVisibleImages, aNonvisibleAction, this); DecrementVisibleCount(mVisibleImages, aNonvisibleAction, this);
mVisibleImages.Clear(); mVisibleImages.Clear();
} }
@ -5720,6 +5735,11 @@ PresShell::RebuildImageVisibility(nsRect* aRect,
return; 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 // Remove the entries of the mVisibleImages hashtable and put them in
// oldVisibleImages. // oldVisibleImages.
nsTHashtable< nsRefPtrHashKey<nsIImageLoadingContent> > oldVisibleImages; nsTHashtable< nsRefPtrHashKey<nsIImageLoadingContent> > oldVisibleImages;
@ -5873,6 +5893,11 @@ PresShell::EnsureImageInVisibleList(nsIImageLoadingContent* aImage)
} }
#endif #endif
if (mInImageVisibility) {
gfxCriticalNoteOnce << "EnsureImageInVisibleList is re-entering on "
<< (NS_IsMainThread() ? "" : "non-") << "main thread";
}
if (!mVisibleImages.Contains(aImage)) { if (!mVisibleImages.Contains(aImage)) {
mVisibleImages.PutEntry(aImage); mVisibleImages.PutEntry(aImage);
aImage->IncrementVisibleCount(); aImage->IncrementVisibleCount();
@ -5896,6 +5921,11 @@ PresShell::RemoveImageFromVisibleList(nsIImageLoadingContent* aImage)
return; return;
} }
if (mInImageVisibility) {
gfxCriticalNoteOnce << "RemoveImageFromVisibleList is re-entering on "
<< (NS_IsMainThread() ? "" : "non-") << "main thread";
}
uint32_t count = mVisibleImages.Count(); uint32_t count = mVisibleImages.Count();
mVisibleImages.RemoveEntry(aImage); mVisibleImages.RemoveEntry(aImage);
if (mVisibleImages.Count() < count) { if (mVisibleImages.Count() < count) {
@ -10657,6 +10687,11 @@ PresShell::UpdateImageLockingState()
nsresult rv = mDocument->SetImageLockingState(locked); nsresult rv = mDocument->SetImageLockingState(locked);
if (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 // Request decodes for visible images; we want to start decoding as
// quickly as possible when we get foregrounded to minimize flashing. // quickly as possible when we get foregrounded to minimize flashing.
for (auto iter = mVisibleImages.Iter(); !iter.Done(); iter.Next()) { for (auto iter = mVisibleImages.Iter(); !iter.Done(); iter.Next()) {

View File

@ -394,6 +394,8 @@ public:
void ReportAnyBadState(); void ReportAnyBadState();
void SetInImageVisibility(bool aState);
protected: protected:
virtual ~PresShell(); virtual ~PresShell();
@ -885,6 +887,8 @@ protected:
// Whether the widget has received a paint message yet. // Whether the widget has received a paint message yet.
bool mHasReceivedPaintMessage : 1; bool mHasReceivedPaintMessage : 1;
bool mInImageVisibility : 1;
static bool sDisableNonTestMouseEvents; static bool sDisableNonTestMouseEvents;
}; };