tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

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:
Mdocshell/base/nsDocShell.cpp | 54++++++++++++++++++++++++++++++++++++++++++++----------
Mdocshell/base/nsDocShell.h | 4++--
Mdom/base/nsFrameLoader.cpp | 2+-
Mtoolkit/components/browser/nsWebBrowser.cpp | 14++++++++++++++
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; }