From 583d256da791cbdb33b4f85f54c14f60bb8fd79a Mon Sep 17 00:00:00 2001 From: Jed Davis Date: Wed, 9 Aug 2023 21:35:50 +0000 Subject: [PATCH] Bug 1840515 - Step 2: Preload the omnijars in the fork server. r=nika This extends the previous support for `-greomni` and `-appomni` to the fork server, so that it can pre-open the jar files and thus continue using the correct versions in forked child processes even if the files on disk are replaced by an update or deleted. Differential Revision: https://phabricator.services.mozilla.com/D185331 --- dom/ipc/ContentProcess.cpp | 7 +++++-- ipc/glue/ForkServer.cpp | 26 ++++++++++++++++++++------ ipc/glue/GeckoChildProcessHost.cpp | 4 +++- 3 files changed, 28 insertions(+), 9 deletions(-) diff --git a/dom/ipc/ContentProcess.cpp b/dom/ipc/ContentProcess.cpp index 3a70329c53fa..10118cd38ff0 100644 --- a/dom/ipc/ContentProcess.cpp +++ b/dom/ipc/ContentProcess.cpp @@ -151,8 +151,11 @@ bool ContentProcess::Init(int aArgc, char* aArgv[]) { return false; } - // Handle the -greomni/-appomni flags - Omnijar::ChildProcessInit(aArgc, aArgv); + // Handle the -greomni/-appomni flags (unless the forkserver already + // preloaded the jar(s)). + if (!Omnijar::IsInitialized()) { + Omnijar::ChildProcessInit(aArgc, aArgv); + } rv = NS_InitXPCOM(nullptr, xpcomAppDir, &mDirProvider); if (NS_FAILED(rv)) { diff --git a/ipc/glue/ForkServer.cpp b/ipc/glue/ForkServer.cpp index 23ce9362fb42..21ad95b65e20 100644 --- a/ipc/glue/ForkServer.cpp +++ b/ipc/glue/ForkServer.cpp @@ -1,21 +1,24 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* vim: set ts=8 sts=4 et sw=4 tw=80: */ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + #include "mozilla/ipc/ForkServer.h" -#include "mozilla/Logging.h" + #include "chrome/common/chrome_switches.h" +#include "ipc/IPCMessageUtilsSpecializations.h" #include "mozilla/BlockingResourceBase.h" -#include "mozilla/ipc/ProtocolMessageUtils.h" +#include "mozilla/Logging.h" +#include "mozilla/Omnijar.h" #include "mozilla/ipc/FileDescriptor.h" #include "mozilla/ipc/IPDLParamTraits.h" -#include "ipc/IPCMessageUtilsSpecializations.h" +#include "mozilla/ipc/ProtocolMessageUtils.h" #include "nsTraceRefcnt.h" +#include #include #include -#include #if defined(XP_LINUX) && defined(MOZ_SANDBOX) # include "mozilla/SandboxLaunch.h" @@ -40,6 +43,16 @@ void ForkServer::InitProcess(int* aArgc, char*** aArgv) { DataBufferClear::AfterReceiving); } +/** + * Preload any resources that the forked child processes might need, + * and which might change incompatibly or become unavailable by the + * time they're started. For example: the omnijar files, or certain + * shared libraries. + */ +static void ForkServerPreload(int& aArgc, char** aArgv) { + Omnijar::ChildProcessInit(aArgc, aArgv); +} + /** * Start providing the service at the IPC channel. */ @@ -251,6 +264,7 @@ bool ForkServer::RunForkServer(int* aArgc, char*** aArgv) { XRE_SetProcessType("forkserver"); NS_LogInit(); mozilla::LogModule::Init(0, nullptr); + ForkServerPreload(*aArgc, *aArgv); MOZ_LOG(gForkServiceLog, LogLevel::Verbose, ("Start a fork server")); { DebugOnly forkserver_pid = base::GetCurrentProcId(); diff --git a/ipc/glue/GeckoChildProcessHost.cpp b/ipc/glue/GeckoChildProcessHost.cpp index 8972c86c347d..b4d8be956421 100644 --- a/ipc/glue/GeckoChildProcessHost.cpp +++ b/ipc/glue/GeckoChildProcessHost.cpp @@ -1255,7 +1255,9 @@ Result PosixProcessLauncher::DoSetup() { mChildArgv.insert(mChildArgv.end(), mExtraOpts.begin(), mExtraOpts.end()); - if (mProcessType == GeckoProcessType_Content && Omnijar::IsInitialized()) { + if ((mProcessType == GeckoProcessType_Content || + mProcessType == GeckoProcessType_ForkServer) && + Omnijar::IsInitialized()) { // Make sure that child processes can find the omnijar, if they // use full XPCOM. See Omnijar::ChildProcessInit and its callers. nsAutoCString path;