Bug 1354933. Add some asserts for document viewer teardown. r=mats

This commit is contained in:
Timothy Nikkel 2017-06-03 01:31:12 -05:00
parent 269f7e9f5c
commit 6c8d12a5d2
3 changed files with 54 additions and 2 deletions

View File

@ -1162,6 +1162,12 @@ PresShell::Destroy()
{
// Do not add code before this line please!
if (mHaveShutDown) {
// If we never got a root frame the root view could exist now still.
// In that case assert that it has no children and no frame.
MOZ_RELEASE_ASSERT(!mViewManager || !mViewManager->GetRootView() ||
(!mViewManager->GetRootView()->GetFrame() &&
!mViewManager->GetRootView()->GetFirstChild()));
MOZ_RELEASE_ASSERT(!mFrameConstructor || !mFrameConstructor->GetRootFrame());
return;
}

View File

@ -409,6 +409,8 @@ protected:
bool mInitializedForPrintPreview;
bool mHidden;
bool mPrintRelated; // Only use for asserts.
bool mPresShellDestroyed; // Only use for asserts.
bool mDestroyWasFull; // Only use for asserts.
};
namespace mozilla {
@ -543,7 +545,9 @@ nsDocumentViewer::nsDocumentViewer()
mIsPageMode(false),
mInitializedForPrintPreview(false),
mHidden(false),
mPrintRelated(false)
mPrintRelated(false),
mPresShellDestroyed(true),
mDestroyWasFull(false)
{
PrepareToStartLoad();
}
@ -580,16 +584,31 @@ nsDocumentViewer::~nsDocumentViewer()
mDocument->Destroy();
}
nsIFrame* vmRootFrame =
mViewManager && mViewManager->GetRootView()
? mViewManager->GetRootView()->GetFrame()
: nullptr;
nsIFrame* psRootFrame = mPresShell ? mPresShell->GetRootFrame() : nullptr;
MOZ_RELEASE_ASSERT(vmRootFrame == psRootFrame);
NS_ASSERTION(!mPresShell && !mPresContext,
"User did not call nsIContentViewer::Destroy");
if (mPresShell || mPresContext) {
// Make sure we don't hand out a reference to the content viewer to
// the SHEntry!
mSHEntry = nullptr;
mDestroyWasFull = false;
Destroy();
MOZ_RELEASE_ASSERT(mDestroyWasFull);
}
MOZ_RELEASE_ASSERT(mPresShellDestroyed);
MOZ_RELEASE_ASSERT(!mPresShell || !mPresShell->GetRootFrame());
MOZ_RELEASE_ASSERT(!mViewManager || !mViewManager->GetRootView() ||
(!mViewManager->GetRootView()->GetFrame() &&
!mViewManager->GetRootView()->GetFirstChild()));
if (mSelectionListener) {
mSelectionListener->Disconnect();
}
@ -708,6 +727,7 @@ nsDocumentViewer::InitPresentationStuff(bool aDoInitialReflow)
styleSet->Delete();
return NS_ERROR_FAILURE;
}
mPresShellDestroyed = false;
// We're done creating the style set
styleSet->EndUpdate();
@ -1796,6 +1816,8 @@ nsDocumentViewer::Destroy()
mViewManager = nullptr;
mContainer = WeakPtr<nsDocShell>();
mDestroyWasFull = true;
return NS_OK;
}
@ -4657,6 +4679,13 @@ nsDocumentViewer::SetIsHidden(bool aHidden)
void
nsDocumentViewer::DestroyPresShell()
{
nsIFrame* vmRootFrame =
mViewManager && mViewManager->GetRootView()
? mViewManager->GetRootView()->GetFrame()
: nullptr;
nsIFrame* psRootFrame = mPresShell ? mPresShell->GetRootFrame() : nullptr;
MOZ_RELEASE_ASSERT(vmRootFrame == psRootFrame);
// Break circular reference (or something)
mPresShell->EndObservingDocument();
@ -4665,7 +4694,18 @@ nsDocumentViewer::DestroyPresShell()
selection->RemoveSelectionListener(mSelectionListener);
nsAutoScriptBlocker scriptBlocker;
bool hadRootFrame = !!mPresShell->GetRootFrame();
mPresShell->Destroy();
mPresShellDestroyed = true;
MOZ_RELEASE_ASSERT(!mPresShell->GetRootFrame());
// destroying the frame tree via presshell destroy should have done this
if (hadRootFrame) {
MOZ_RELEASE_ASSERT(!mViewManager || !mViewManager->GetRootView());
}
MOZ_RELEASE_ASSERT(!mViewManager || !mViewManager->GetRootView() ||
(!mViewManager->GetRootView()->GetFrame() &&
!mViewManager->GetRootView()->GetFirstChild()));
mPresShell = nullptr;
}

View File

@ -68,6 +68,10 @@ nsView::~nsView()
bool printRelated = mViewManager && mViewManager->GetPrintRelated();
if (mViewManager && (mViewManager->GetRootView() == this)) {
MOZ_RELEASE_ASSERT(!GetFirstChild());
}
while (GetFirstChild())
{
nsView* child = GetFirstChild();
@ -472,6 +476,8 @@ void nsView::InsertChild(nsView *aChild, nsView *aSibling)
{
aChild->SetNextSibling(mFirstChild);
mFirstChild = aChild;
MOZ_RELEASE_ASSERT(!mFirstChild || mFrame ||
mFirstChild->GetViewManager() != GetViewManager());
}
aChild->SetParent(this);