
# HG changeset patch
# User Eden Chuang <echuang@mozilla.com>
# Date 1744130274 0
# Node ID 4159736c2897215a6d22fc33272e05e370d50f5c
# Parent  11dc373cc55d14b1ca924ae63703cab228e8b1e1
Bug 1790526 - Handle the discarded BrowsingContext that propagated to SessionStoreParent. r=smaug

According to the Pernosco trace, https://static.pernos.co/server/7c640bc4ed587e824fab0ca8aa44f41d1b5595b5/rebuilding.html?redirect=https%3A%2F%2Fpernos.co%2Fdebug%2FAKTDVC62g_oHMo8GmtoA1g%2Findex.html, this is a case that the propagated BrowingContext has been discarded already, so it causes aBrowsingContext.GetMaybeDiscarded() get a nullptr.

This patch just check if the propageted BrowsingContext is discarded.
For the discarded BrowsingContext, try to use its BrowsingContextId to get the corresponding CanonicalBrowsingContext instead of using the propagated one.

Differential Revision: https://phabricator.services.mozilla.com/D237702

diff --git a/toolkit/components/sessionstore/SessionStoreParent.cpp b/toolkit/components/sessionstore/SessionStoreParent.cpp
--- a/toolkit/components/sessionstore/SessionStoreParent.cpp
+++ b/toolkit/components/sessionstore/SessionStoreParent.cpp
@@ -194,36 +194,57 @@ mozilla::ipc::IPCResult SessionStorePare
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult SessionStoreParent::RecvIncrementalSessionStoreUpdate(
     const MaybeDiscarded<BrowsingContext>& aBrowsingContext,
     const Maybe<FormData>& aFormData, const Maybe<nsPoint>& aScrollPosition,
     uint32_t aEpoch) {
   if (!aBrowsingContext.IsNull()) {
+    // The passed in BrowsingContext maybe already discarded and its mRawPtr is
+    // nullptr here. Let try to use the BrowsingContextId to get its
+    // Canonical one in the parent process for SessionStore update.
+    RefPtr<CanonicalBrowsingContext> bc;
+    if (aBrowsingContext.IsDiscarded()) {
+      bc = CanonicalBrowsingContext::Get(aBrowsingContext.ContextId());
+    } else {
+      bc = aBrowsingContext.GetMaybeDiscarded()->Canonical();
+    }
+    if (!bc) {
+      return IPC_OK();
+    }
     if (aFormData.isSome()) {
       mHasNewFormData = true;
     }
     if (aScrollPosition.isSome()) {
       mHasNewScrollPosition = true;
     }
 
-    mSessionStore->UpdateSessionStore(
-        aBrowsingContext.GetMaybeDiscarded()->Canonical(), aFormData,
-        aScrollPosition, aEpoch);
+    mSessionStore->UpdateSessionStore(bc, aFormData, aScrollPosition, aEpoch);
   }
 
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult SessionStoreParent::RecvResetSessionStore(
     const MaybeDiscarded<BrowsingContext>& aBrowsingContext, uint32_t aEpoch) {
   if (!aBrowsingContext.IsNull()) {
-    mSessionStore->RemoveSessionStore(
-        aBrowsingContext.GetMaybeDiscarded()->Canonical());
+    // The passed in BrowsingContext maybe already discarded and its mRawPtr is
+    // nullptr here. Let try to use the BrowsingContextId to get its
+    // Canonical one in the parent process for SessionStore update.
+    RefPtr<CanonicalBrowsingContext> bc;
+    if (aBrowsingContext.IsDiscarded()) {
+      bc = CanonicalBrowsingContext::Get(aBrowsingContext.ContextId());
+    } else {
+      bc = aBrowsingContext.GetMaybeDiscarded()->Canonical();
+    }
+    if (!bc) {
+      return IPC_OK();
+    }
+    mSessionStore->RemoveSessionStore(bc);
   }
   return IPC_OK();
 }
 
 void SessionStoreParent::SessionStoreUpdate(
     const Maybe<nsCString>& aDocShellCaps, const Maybe<bool>& aPrivatedMode,
     const MaybeSessionStoreZoom& aZoom, const bool aNeedCollectSHistory,
     const uint32_t& aEpoch) {

