tor-browser

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

commit be52f52e18286c6ec6946f3cf2b02910aded3964
parent d76e7275215f632e4ebe9b8aa8794c77156a97be
Author: Andrew Osmond <aosmond@gmail.com>
Date:   Mon, 27 Oct 2025 18:29:35 +0000

Bug 1649857 - Fix crash in parent process when RDD and GPU processes crashed simultaneously. r=media-playback-reviewers,alwu

When the RDD and GPU processes crashed simultaneously, we could get into
a position where we would try to recreate PVideoBridge between the RDD
and GPU processes, before bringing back up the RDD process. We should
now skip reinitializing the protocol if the RDD process is unavailable.

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

Diffstat:
Mdom/media/ipc/RDDProcessHost.cpp | 4++--
Mdom/media/ipc/RDDProcessManager.cpp | 23+++++++++++++++--------
Mdom/media/ipc/RDDProcessManager.h | 4++--
3 files changed, 19 insertions(+), 12 deletions(-)

diff --git a/dom/media/ipc/RDDProcessHost.cpp b/dom/media/ipc/RDDProcessHost.cpp @@ -256,7 +256,7 @@ void RDDProcessHost::DestroyProcess() { void RDDProcessHost::ResolvePromise() { MOZ_ASSERT(NS_IsMainThread()); - if (!mLaunchPromiseSettled) { + if (mLaunchPromise && !mLaunchPromiseSettled) { mLaunchPromise->Resolve(true, __func__); mLaunchPromiseSettled = true; } @@ -268,7 +268,7 @@ void RDDProcessHost::ResolvePromise() { void RDDProcessHost::RejectPromise() { MOZ_ASSERT(NS_IsMainThread()); - if (!mLaunchPromiseSettled) { + if (mLaunchPromise && !mLaunchPromiseSettled) { mLaunchPromise->Reject(NS_ERROR_FAILURE, __func__); mLaunchPromiseSettled = true; } diff --git a/dom/media/ipc/RDDProcessManager.cpp b/dom/media/ipc/RDDProcessManager.cpp @@ -129,7 +129,8 @@ RefPtr<GenericNonExclusivePromise> RDDProcessManager::LaunchRDDProcess() { __func__); } - if (mLaunchRDDPromise && mProcess) { + if (mProcess) { + MOZ_DIAGNOSTIC_ASSERT(mLaunchRDDPromise); return mLaunchRDDPromise; } @@ -154,7 +155,7 @@ RefPtr<GenericNonExclusivePromise> RDDProcessManager::LaunchRDDProcess() { NS_ERROR_NOT_AVAILABLE, __func__); } - if (IsRDDProcessDestroyed()) { + if (NS_WARN_IF(!IsRDDProcessLaunching())) { return GenericNonExclusivePromise::CreateAndReject( NS_ERROR_NOT_AVAILABLE, __func__); } @@ -224,14 +225,14 @@ auto RDDProcessManager::EnsureRDDProcessAndCreateBridge( }); } -bool RDDProcessManager::IsRDDProcessLaunching() { +bool RDDProcessManager::IsRDDProcessLaunching() const { MOZ_ASSERT(NS_IsMainThread()); return !!mProcess && !mRDDChild; } -bool RDDProcessManager::IsRDDProcessDestroyed() const { +bool RDDProcessManager::IsRDDProcessAlive() const { MOZ_ASSERT(NS_IsMainThread()); - return !mRDDChild && !mProcess; + return mRDDChild && mRDDChild->CanSend() && mProcess; } void RDDProcessManager::OnProcessUnexpectedShutdown(RDDProcessHost* aHost) { @@ -266,14 +267,20 @@ void RDDProcessManager::NotifyRemoteActorDestroyed( void RDDProcessManager::DestroyProcess() { MOZ_ASSERT(NS_IsMainThread()); + if (!mProcess) { return; } - mProcess->Shutdown(); - mProcessToken = 0; + // Move onto the stack to ensure we don't re-enter from a chained promise + // rejection on the process shutdown. + RDDProcessHost* process = mProcess; mProcess = nullptr; + + process->Shutdown(); + mProcessToken = 0; mRDDChild = nullptr; + mLaunchRDDPromise = nullptr; mQueuedPrefs.Clear(); CrashReporter::RecordAnnotationCString( @@ -285,7 +292,7 @@ bool RDDProcessManager::CreateContentBridge( ipc::Endpoint<PRemoteMediaManagerChild>* aOutRemoteMediaManager) { MOZ_ASSERT(NS_IsMainThread()); - if (IsRDDProcessDestroyed()) { + if (NS_WARN_IF(!IsRDDProcessAlive())) { MOZ_LOG(sPDMLog, LogLevel::Debug, ("RDD shutdown before creating content bridge")); return false; diff --git a/dom/media/ipc/RDDProcessManager.h b/dom/media/ipc/RDDProcessManager.h @@ -74,8 +74,8 @@ class RDDProcessManager final : public RDDProcessHost::Listener { RefPtr<PRDDChild::TestTriggerMetricsPromise> TestTriggerMetrics(); private: - bool IsRDDProcessLaunching(); - bool IsRDDProcessDestroyed() const; + bool IsRDDProcessLaunching() const; + bool IsRDDProcessAlive() const; // Called from our xpcom-shutdown observer. void OnXPCOMShutdown();