Bug 1114647 - Use firefox for child processes instead of plugin-container. r=ted

Disabled on Mac (content processes need to use plugin-container.app for
UI reasons) and on Linux unless --disable-sandboxing (build issues).

Based on work by George Wright <george@mozilla.com>.

--HG--
extra : amend_source : 43986e25743de21e3ddfb7893e3ed550fe6eef76
This commit is contained in:
Jed Davis 2016-06-03 12:49:39 -07:00
Родитель f0212d4315
Коммит 78e49e2efb
7 изменённых файлов: 113 добавлений и 22 удалений

Просмотреть файл

@ -30,14 +30,12 @@
#include "nsStringGlue.h"
#ifdef XP_WIN
// we want a wmain entry point
#ifdef MOZ_ASAN
// ASAN requires firefox.exe to be built with -MD, and it's OK if we don't
// support Windows XP SP2 in ASAN builds.
#define XRE_DONT_SUPPORT_XPSP2
#endif
#define XRE_WANT_ENVIRON
#include "nsWindowsWMain.cpp"
#if defined(_MSC_VER) && (_MSC_VER < 1900)
#define snprintf _snprintf
#endif
@ -53,6 +51,12 @@
#include "mozilla/Telemetry.h"
#include "mozilla/WindowsDllBlocklist.h"
#if !defined(MOZ_WIDGET_COCOA) && !defined(MOZ_WIDGET_ANDROID) \
&& !(defined(XP_LINUX) && defined(MOZ_SANDBOX))
#define MOZ_BROWSER_CAN_BE_CONTENTPROC
#include "../../ipc/contentproc/plugin-container.cpp"
#endif
using namespace mozilla;
#ifdef XP_MACOSX
@ -128,6 +132,10 @@ XRE_StartupTimelineRecordType XRE_StartupTimelineRecord;
XRE_mainType XRE_main;
XRE_StopLateWriteChecksType XRE_StopLateWriteChecks;
XRE_XPCShellMainType XRE_XPCShellMain;
XRE_GetProcessTypeType XRE_GetProcessType;
XRE_SetProcessTypeType XRE_SetProcessType;
XRE_InitChildProcessType XRE_InitChildProcess;
XRE_EnableSameExecutableForContentProcType XRE_EnableSameExecutableForContentProc;
static const nsDynamicFunctionLoad kXULFuncs[] = {
{ "XRE_GetFileFromPath", (NSFuncPtr*) &XRE_GetFileFromPath },
@ -138,6 +146,10 @@ static const nsDynamicFunctionLoad kXULFuncs[] = {
{ "XRE_main", (NSFuncPtr*) &XRE_main },
{ "XRE_StopLateWriteChecks", (NSFuncPtr*) &XRE_StopLateWriteChecks },
{ "XRE_XPCShellMain", (NSFuncPtr*) &XRE_XPCShellMain },
{ "XRE_GetProcessType", (NSFuncPtr*) &XRE_GetProcessType },
{ "XRE_SetProcessType", (NSFuncPtr*) &XRE_SetProcessType },
{ "XRE_InitChildProcess", (NSFuncPtr*) &XRE_InitChildProcess },
{ "XRE_EnableSameExecutableForContentProc", (NSFuncPtr*) &XRE_EnableSameExecutableForContentProc },
{ nullptr, nullptr }
};
@ -296,25 +308,54 @@ sizeof(XPCOM_DLL) - 1))
// This will set this thread as the main thread.
NS_LogInit();
// chop XPCOM_DLL off exePath
*lastSlash = '\0';
if (xreDirectory) {
// chop XPCOM_DLL off exePath
*lastSlash = '\0';
#ifdef XP_MACOSX
lastSlash = strrchr(exePath, XPCOM_FILE_PATH_SEPARATOR[0]);
strcpy(lastSlash + 1, kOSXResourcesFolder);
lastSlash = strrchr(exePath, XPCOM_FILE_PATH_SEPARATOR[0]);
strcpy(lastSlash + 1, kOSXResourcesFolder);
#endif
#ifdef XP_WIN
rv = NS_NewLocalFile(NS_ConvertUTF8toUTF16(exePath), false,
xreDirectory);
rv = NS_NewLocalFile(NS_ConvertUTF8toUTF16(exePath), false,
xreDirectory);
#else
rv = NS_NewNativeLocalFile(nsDependentCString(exePath), false,
xreDirectory);
rv = NS_NewNativeLocalFile(nsDependentCString(exePath), false,
xreDirectory);
#endif
}
return rv;
}
int main(int argc, char* argv[], char* envp[])
{
#ifdef MOZ_BROWSER_CAN_BE_CONTENTPROC
// We are launching as a content process, delegate to the appropriate
// main
if (argc > 1 && IsArg(argv[1], "contentproc")) {
#if defined(XP_WIN) && defined(MOZ_SANDBOX)
// We need to initialize the sandbox TargetServices before InitXPCOMGlue
// because we might need the sandbox broker to give access to some files.
if (!sandboxing::GetInitializedTargetServices()) {
Output("Failed to initialize the sandbox target services.");
return 255;
}
#endif
nsresult rv = InitXPCOMGlue(argv[0], nullptr);
if (NS_FAILED(rv)) {
return 255;
}
int result = content_process_main(argc, argv);
// InitXPCOMGlue calls NS_LogInit, so we need to balance it here.
NS_LogTerm();
return result;
}
#endif
mozilla::TimeStamp start = mozilla::TimeStamp::Now();
#ifdef XP_MACOSX
@ -379,6 +420,10 @@ int main(int argc, char* argv[], char* envp[])
#endif
}
#ifdef MOZ_BROWSER_CAN_BE_CONTENTPROC
XRE_EnableSameExecutableForContentProc();
#endif
int result = do_main(argc, argv, envp, xreDirectory);
NS_LogTerm();

Просмотреть файл

@ -92,3 +92,8 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk':
'binder',
'utils',
]
if CONFIG['GNU_CXX']:
CXXFLAGS += ['-Wshadow']
DEFINES['MOZ_PLUGIN_CONTAINER'] = 1;

Просмотреть файл

@ -8,11 +8,6 @@
#include "nsXULAppAPI.h"
#include "nsAutoPtr.h"
// FIXME/cjones testing
#if !defined(OS_WIN)
#include <unistd.h>
#endif
#ifdef XP_WIN
#include <windows.h>
// we want a wmain entry point
@ -20,6 +15,9 @@
#define XRE_DONT_PROTECT_DLL_LOAD
#include "nsWindowsWMain.cpp"
#include "nsSetDllDirectory.h"
#else
// FIXME/cjones testing
#include <unistd.h>
#endif
#include "GMPLoader.h"
@ -217,10 +215,10 @@ content_process_main(int argc, char* argv[])
// the details.
if (XRE_GetProcessType() != GeckoProcessType_Plugin) {
mozilla::SanitizeEnvironmentVariables();
SetDllDirectory(L"");
SetDllDirectoryW(L"");
}
#endif
#if !defined(MOZ_WIDGET_ANDROID) && !defined(MOZ_WIDGET_GONK)
#if !defined(MOZ_WIDGET_ANDROID) && !defined(MOZ_WIDGET_GONK) && defined(MOZ_PLUGIN_CONTAINER)
// On desktop, the GMPLoader lives in plugin-container, so that its
// code can be covered by an EME/GMP vendor's voucher.
nsAutoPtr<mozilla::gmp::SandboxStarter> starter(MakeSandboxStarter());

Просмотреть файл

@ -139,8 +139,24 @@ GeckoChildProcessHost::~GeckoChildProcessHost()
//static
void
GeckoChildProcessHost::GetPathToBinary(FilePath& exePath)
GeckoChildProcessHost::GetPathToBinary(FilePath& exePath, GeckoProcessType processType)
{
if (sRunSelfAsContentProc &&
processType == GeckoProcessType_Content) {
#if defined(OS_WIN)
wchar_t exePathBuf[MAXPATHLEN];
if (!::GetModuleFileNameW(nullptr, exePathBuf, MAXPATHLEN)) {
MOZ_CRASH("GetModuleFileNameW failed (FIXME)");
}
exePath = FilePath::FromWStringHack(exePathBuf);
#elif defined(OS_POSIX)
exePath = FilePath(CommandLine::ForCurrentProcess()->argv()[0]);
#else
# error Sorry; target OS not supported yet.
#endif
return;
}
if (ShouldHaveDirectoryService()) {
MOZ_ASSERT(gGREBinPath);
#ifdef OS_WIN
@ -149,6 +165,7 @@ GeckoChildProcessHost::GetPathToBinary(FilePath& exePath)
nsCOMPtr<nsIFile> childProcPath;
NS_NewLocalFile(nsDependentString(gGREBinPath), false,
getter_AddRefs(childProcPath));
// We need to use an App Bundle on OS X so that we can hide
// the dock icon. See Bug 557225.
childProcPath->AppendNative(NS_LITERAL_CSTRING("plugin-container.app"));
@ -259,7 +276,7 @@ uint32_t GeckoChildProcessHost::GetSupportedArchitecturesForProcessType(GeckoPro
static uint32_t pluginContainerArchs = 0;
if (pluginContainerArchs == 0) {
FilePath exePath;
GetPathToBinary(exePath);
GetPathToBinary(exePath, type);
nsresult rv = GetArchitecturesForBinary(exePath.value().c_str(), &pluginContainerArchs);
NS_ASSERTION(NS_SUCCEEDED(rv) && pluginContainerArchs != 0, "Getting architecture of plugin container failed!");
if (NS_FAILED(rv) || pluginContainerArchs == 0) {
@ -785,7 +802,7 @@ GeckoChildProcessHost::PerformAsyncLaunchInternal(std::vector<std::string>& aExt
#endif // OS_LINUX || OS_MACOSX
FilePath exePath;
GetPathToBinary(exePath);
GetPathToBinary(exePath, mProcessType);
#ifdef MOZ_WIDGET_ANDROID
// The java wrapper unpacks this for us but can't make it executable
@ -828,6 +845,11 @@ GeckoChildProcessHost::PerformAsyncLaunchInternal(std::vector<std::string>& aExt
childArgv.push_back(exePath.value());
if (sRunSelfAsContentProc &&
mProcessType == GeckoProcessType_Content) {
childArgv.push_back("-contentproc");
}
childArgv.insert(childArgv.end(), aExtraOpts.begin(), aExtraOpts.end());
if (Omnijar::IsInitialized()) {
@ -964,9 +986,15 @@ GeckoChildProcessHost::PerformAsyncLaunchInternal(std::vector<std::string>& aExt
#elif defined(OS_WIN)
FilePath exePath;
GetPathToBinary(exePath);
GetPathToBinary(exePath, mProcessType);
CommandLine cmdLine(exePath.ToWStringHack());
if (sRunSelfAsContentProc &&
mProcessType == GeckoProcessType_Content) {
cmdLine.AppendLooseValue(UTF8ToWide("-contentproc"));
}
cmdLine.AppendSwitchWithValue(switches::kProcessChannelID, channel_id());
for (std::vector<std::string>::iterator it = aExtraOpts.begin();
@ -1211,6 +1239,8 @@ GeckoChildProcessHost::OnWaitableEventSignaled(base::WaitableEvent *event)
ChildProcessHost::OnWaitableEventSignaled(event);
}
bool GeckoChildProcessHost::sRunSelfAsContentProc(false);
#ifdef MOZ_NUWA_PROCESS
using mozilla::ipc::GeckoExistingProcessHost;

Просмотреть файл

@ -136,6 +136,8 @@ public:
// for deletion when all actors have cleared their associations.
void DissociateActor();
static void EnableSameExecutableForContentProc() { sRunSelfAsContentProc = true; }
protected:
GeckoProcessType mProcessType;
ChildPrivileges mPrivileges;
@ -200,7 +202,7 @@ private:
bool RunPerformAsyncLaunch(StringVector aExtraOpts=StringVector(),
base::ProcessArchitecture aArch=base::GetCurrentProcessArchitecture());
static void GetPathToBinary(FilePath& exePath);
static void GetPathToBinary(FilePath& exePath, GeckoProcessType processType);
// The buffer is passed to preserve its lifetime until we are done
// with launching the sub-process.
@ -227,6 +229,8 @@ private:
nsCString mRestoreOrigMozLogName;
static uint32_t sNextUniqueID;
static bool sRunSelfAsContentProc;
};
#ifdef MOZ_NUWA_PROCESS

Просмотреть файл

@ -11,6 +11,7 @@
#include "mozilla/dom/ContentParent.h"
#include "mozilla/dom/ContentChild.h"
#include "mozilla/ipc/GeckoChildProcessHost.h"
#include "mozilla/ArrayUtils.h"
#include "mozilla/Attributes.h"
@ -4962,3 +4963,8 @@ OverrideDefaultLocaleIfNeeded() {
setlocale(LC_ALL, "C.UTF-8") || setlocale(LC_ALL, "C");
}
}
void
XRE_EnableSameExecutableForContentProc() {
mozilla::ipc::GeckoChildProcessHost::EnableSameExecutableForContentProc();
}

Просмотреть файл

@ -507,6 +507,9 @@ XRE_API(void,
const nsXREAppData* aAppData));
#endif // MOZ_B2G_LOADER
XRE_API(void,
XRE_EnableSameExecutableForContentProc, ())
XRE_API(int,
XRE_XPCShellMain, (int argc, char** argv, char** envp,
const XREShellData* aShellData))