commit 857dc0c7fe05bc2af62f6f608b1f668256ab426b
parent 509c13d6867e64dced5a7583d428dc5d277e6f5d
Author: Vincent Hilla <vhilla@mozilla.com>
Date: Tue, 16 Dec 2025 11:23:22 +0000
Bug 2003759 - Add crash annotations for docshell initialization failure reasons. r=hsivonen,gsvelto
Differential Revision: https://phabricator.services.mozilla.com/D276521
Diffstat:
4 files changed, 61 insertions(+), 13 deletions(-)
diff --git a/docshell/base/nsDocShell.cpp b/docshell/base/nsDocShell.cpp
@@ -444,19 +444,19 @@ nsresult nsDocShell::InitWindow(nsIWidget* aParentWidget, int32_t aX,
mozilla::dom::WindowGlobalChild* aWindowActor) {
SetParentWidget(aParentWidget);
SetPositionAndSize(aX, aY, aWidth, aHeight, 0);
- NS_ENSURE_TRUE(Initialize(aOpenWindowInfo, aWindowActor), NS_ERROR_FAILURE);
-
- return NS_OK;
+ return Initialize(aOpenWindowInfo, aWindowActor);
}
-bool nsDocShell::Initialize(nsIOpenWindowInfo* aOpenWindowInfo,
- mozilla::dom::WindowGlobalChild* aWindowActor) {
+nsresult nsDocShell::Initialize(nsIOpenWindowInfo* aOpenWindowInfo,
+ mozilla::dom::WindowGlobalChild* aWindowActor) {
if (mInitialized) {
// We've already been initialized.
MOZ_ASSERT(!aOpenWindowInfo,
"Tried to reinitialize with override principal");
MOZ_ASSERT(!aWindowActor, "Tried to reinitialize with a window actor");
- return true;
+ CrashReporter::AppendAppNotesToCrashReport(
+ "nsDocShell::Initialize mInitialized."_ns);
+ return NS_ERROR_UNEXPECTED;
}
MOZ_ASSERT(aOpenWindowInfo,
@@ -465,15 +465,14 @@ bool nsDocShell::Initialize(nsIOpenWindowInfo* aOpenWindowInfo,
NS_ASSERTION(mItemType == typeContent || mItemType == typeChrome,
"Unexpected item type in docshell");
- NS_ENSURE_TRUE(Preferences::GetRootBranch(), false);
+ NS_ENSURE_TRUE(Preferences::GetRootBranch(), NS_ERROR_NOT_AVAILABLE);
mInitialized = true;
mDisableMetaRefreshWhenInactive =
Preferences::GetBool("browser.meta_refresh_when_inactive.disabled",
mDisableMetaRefreshWhenInactive);
- bool succeeded =
- NS_SUCCEEDED(CreateInitialDocumentViewer(aOpenWindowInfo, aWindowActor));
+ nsresult rv = CreateInitialDocumentViewer(aOpenWindowInfo, aWindowActor);
if (nsCOMPtr<nsIObserverService> serv = services::GetObserverService()) {
const char* msg = mItemType == typeContent ? NS_WEBNAVIGATION_CREATE
@@ -481,7 +480,7 @@ bool nsDocShell::Initialize(nsIOpenWindowInfo* aOpenWindowInfo,
serv->NotifyWhenScriptSafe(GetAsSupports(this), msg, nullptr);
}
- return succeeded;
+ return rv;
}
/* static */
@@ -6660,6 +6659,8 @@ nsresult nsDocShell::CreateInitialDocumentViewer(
nsIOpenWindowInfo* aOpenWindowInfo,
mozilla::dom::WindowGlobalChild* aWindowActor) {
if (mIsBeingDestroyed) {
+ CrashReporter::AppendAppNotesToCrashReport(
+ "nsDocShell initially mIsBeingDestroyed."_ns);
return NS_ERROR_FAILURE;
}
MOZ_ASSERT(!mDocumentViewer);
@@ -6685,6 +6686,10 @@ nsresult nsDocShell::CreateInitialDocumentViewer(
/* aTryToSaveOldPresentation */ true,
/* aCheckPermitUnload */ true, aWindowActor);
+ if (!mDocumentViewer) {
+ CrashReporter::AppendAppNotesToCrashReport(
+ "nsDocShell no viewer after create viewer."_ns);
+ }
NS_ENSURE_STATE(mDocumentViewer);
if (NS_SUCCEEDED(rv)) {
@@ -6729,12 +6734,15 @@ nsresult nsDocShell::CreateAboutBlankDocumentViewer(
NS_ASSERTION(!mCreatingDocument,
"infinite(?) loop creating document averted");
if (mCreatingDocument) {
+ CrashReporter::AppendAppNotesToCrashReport(
+ "nsDocShell mCreatingDocument."_ns);
return NS_ERROR_FAILURE;
}
if (!mBrowsingContext->AncestorsAreCurrent() ||
(mozilla::SessionHistoryInParent() && mBrowsingContext->IsInBFCache())) {
mBrowsingContext->RemoveRootFromBFCacheSync();
+ CrashReporter::AppendAppNotesToCrashReport("nsDocShell BFCache check."_ns);
return NS_ERROR_NOT_AVAILABLE;
}
@@ -6782,13 +6790,21 @@ nsresult nsDocShell::CreateAboutBlankDocumentViewer(
rv = mDocumentViewer->PermitUnload(&okToUnload);
if (mIsBeingDestroyed) {
// unload handler destroyed this docshell.
+ CrashReporter::AppendAppNotesToCrashReport(
+ "nsDocShell mIsBeingDestroyed after PermitUnload."_ns);
return NS_ERROR_NOT_AVAILABLE;
}
if (NS_SUCCEEDED(rv) && !okToUnload) {
// The user chose not to unload the page, interrupt the load.
MaybeResetInitTiming(toBeReset);
+ CrashReporter::AppendAppNotesToCrashReport(
+ "nsDocShell !okToUnload."_ns);
return NS_ERROR_FAILURE;
}
+ if (NS_FAILED(rv)) {
+ CrashReporter::AppendAppNotesToCrashReport(
+ "nsDocShell failed PermitUnload."_ns);
+ }
if (mTiming) {
mTiming->NotifyUnloadAccepted(mCurrentURI);
}
@@ -6816,6 +6832,8 @@ nsresult nsDocShell::CreateAboutBlankDocumentViewer(
(void)FirePageHideNotification(!mSavingOldViewer);
// pagehide notification might destroy this docshell.
if (mIsBeingDestroyed) {
+ CrashReporter::AppendAppNotesToCrashReport(
+ "nsDocShell mIsBeingDestroyed after PageHide."_ns);
return NS_ERROR_DOCSHELL_DYING;
}
}
@@ -6885,6 +6903,8 @@ nsresult nsDocShell::CreateAboutBlankDocumentViewer(
};
nsresult rv = csp->SetRequestContextWithDocument(blankDoc);
if (NS_WARN_IF(NS_FAILED(rv))) {
+ CrashReporter::AppendAppNotesToCrashReport(
+ "nsDocShell failed SetRequestContextWithDocument."_ns);
return rv;
}
}
@@ -6928,12 +6948,20 @@ nsresult nsDocShell::CreateAboutBlankDocumentViewer(
mLoadingEntry->mInfo.SetTransient();
}
rv = Embed(viewer, aActor, true, nullptr, mCurrentURI);
+ if (NS_FAILED(rv)) {
+ CrashReporter::AppendAppNotesToCrashReport(
+ "nsDocShell failed Embed."_ns);
+ }
NS_ENSURE_SUCCESS(rv, rv);
SetCurrentURI(blankDoc->GetDocumentURI(), nullptr,
/* aFireLocationChange */ true,
/* aIsInitialAboutBlank */ aIsInitialDocument,
/* aLocationFlags */ 0);
+ if (mIsBeingDestroyed) {
+ CrashReporter::AppendAppNotesToCrashReport(
+ "nsDocShell mIsBeingDestroyed at the end."_ns);
+ }
rv = mIsBeingDestroyed ? NS_ERROR_NOT_AVAILABLE : NS_OK;
}
@@ -8263,6 +8291,8 @@ nsresult nsDocShell::SetupNewViewer(nsIDocumentViewer* aNewViewer,
mDocumentViewer = nullptr;
SetCurrentURIInternal(nullptr);
NS_WARNING("DocumentViewer Initialization failed");
+ CrashReporter::AppendAppNotesToCrashReport(
+ "nsDocShell failed viewer init."_ns);
return NS_ERROR_FAILURE;
}
@@ -8272,6 +8302,10 @@ nsresult nsDocShell::SetupNewViewer(nsIDocumentViewer* aNewViewer,
newViewer->SetReloadEncodingAndSource(reloadEncoding, reloadEncodingSource);
}
+ if (!mDocumentViewer) {
+ CrashReporter::AppendAppNotesToCrashReport(
+ "nsDocShell no viewer after initializing viewer."_ns);
+ }
NS_ENSURE_TRUE(mDocumentViewer, NS_ERROR_FAILURE);
// Stuff the bgcolor from the old pres shell into the new
diff --git a/docshell/base/nsDocShell.h b/docshell/base/nsDocShell.h
@@ -190,8 +190,8 @@ class nsDocShell final : public nsDocLoader,
mozilla::dom::BrowsingContext* aBrowsingContext,
uint64_t aContentWindowID = 0);
- bool Initialize(nsIOpenWindowInfo* aOpenWindowInfo,
- mozilla::dom::WindowGlobalChild* aWindowActor);
+ nsresult Initialize(nsIOpenWindowInfo* aOpenWindowInfo,
+ mozilla::dom::WindowGlobalChild* aWindowActor);
nsresult InitWindow(nsIWidget* aParentWidget, int32_t aX, int32_t aY,
int32_t aWidth, int32_t aHeight,
diff --git a/dom/base/nsFrameLoader.cpp b/dom/base/nsFrameLoader.cpp
@@ -2299,7 +2299,7 @@ nsresult nsFrameLoader::MaybeCreateDocShell() {
doc->GetPolicyContainer();
openWindowInfo->mCoepToInheritForAboutBlank = doc->GetEmbedderPolicy();
openWindowInfo->mBaseUriToInheritForAboutBlank = mOwnerContent->GetBaseURI();
- if (!docShell->Initialize(openWindowInfo, nullptr)) {
+ if (NS_FAILED(docShell->Initialize(openWindowInfo, nullptr))) {
// Do not call Destroy() here. See bug 472312.
NS_WARNING("Something wrong when creating the docshell for a frameloader!");
return NS_ERROR_FAILURE;
diff --git a/toolkit/components/browser/nsWebBrowser.cpp b/toolkit/components/browser/nsWebBrowser.cpp
@@ -112,6 +112,12 @@ already_AddRefed<nsWebBrowser> nsWebBrowser::Create(
RefPtr<nsDocShell> docShell =
nsDocShell::Create(aBrowsingContext, outerWindowId);
if (NS_WARN_IF(!docShell)) {
+ if (aInitialWindowChild) {
+ // If aInitialWindowChild, we were called from
+ // ContentChild::RecvConstructBrowser and would crash there. Let's already
+ // crash here to help diagnose bug 2003244.
+ MOZ_CRASH("Failed to create docshell.");
+ }
return nullptr;
}
browser->SetDocShell(docShell);
@@ -142,6 +148,14 @@ already_AddRefed<nsWebBrowser> nsWebBrowser::Create(
nsresult rv = docShell->InitWindow(docShellParentWidget, 0, 0, 0, 0,
aOpenWindowInfo, aInitialWindowChild);
if (NS_WARN_IF(NS_FAILED(rv))) {
+ if (aInitialWindowChild) {
+ // If aInitialWindowChild, we were called from
+ // ContentChild::RecvConstructBrowser and would crash there. Let's already
+ // crash here to help diagnose bug 2003244. Since bug 543435, InitWindow
+ // also involves creating viewer and document.
+ CrashReporter::AppendAppNotesToCrashReport(nsPrintfCString("rv=%u.", rv));
+ MOZ_CRASH("Failed to initialize docshell, check app notes.");
+ }
return nullptr;
}