Bug 1033522 - Only initialize the Windows Group ID for plugin processes: other process types don't need it. Refactor the saved GRE dir to use a path rather than a non-threadsafe nsIFile object, r=jimm

--HG--
extra : rebase_source : d15c56da6cc5679516b259a6fc7efb31b070f715
This commit is contained in:
Benjamin Smedberg 2014-07-17 11:15:09 -04:00
parent 4a8b50b271
commit d0ac33c5ba
4 changed files with 70 additions and 109 deletions

View File

@ -20,6 +20,7 @@
#include "MainThreadUtils.h"
#include "prprf.h"
#include "prenv.h"
#include "nsXPCOMPrivate.h"
#include "nsExceptionHandler.h"
@ -39,6 +40,7 @@
#include "nsTArray.h"
#include "nsClassHashtable.h"
#include "nsHashKeys.h"
#include "nsNativeCharsetUtils.h"
using mozilla::MonitorAutoLock;
using mozilla::ipc::GeckoChildProcessHost;
@ -60,8 +62,6 @@ static const bool kLowRightsSubprocesses =
#endif
;
mozilla::StaticRefPtr<nsIFile> GeckoChildProcessHost::sGreDir;
static bool
ShouldHaveDirectoryService()
{
@ -124,22 +124,19 @@ void
GeckoChildProcessHost::GetPathToBinary(FilePath& exePath)
{
if (ShouldHaveDirectoryService()) {
MOZ_ASSERT(sGreDir);
if (sGreDir) {
MOZ_ASSERT(gGREPath);
#ifdef OS_WIN
nsString path;
MOZ_ALWAYS_TRUE(NS_SUCCEEDED(sGreDir->GetPath(path)));
exePath = FilePath(gGREPath);
#else
nsCString path;
MOZ_ALWAYS_TRUE(NS_SUCCEEDED(sGreDir->GetNativePath(path)));
nsCString path;
NS_CopyUnicodeToNative(nsDependentString(gGREPath), path);
exePath = FilePath(path.get());
#endif
exePath = FilePath(path.get());
#ifdef MOZ_WIDGET_COCOA
// We need to use an App Bundle on OS X so that we can hide
// the dock icon. See Bug 557225.
exePath = exePath.AppendASCII(MOZ_CHILD_PROCESS_BUNDLE);
// We need to use an App Bundle on OS X so that we can hide
// the dock icon. See Bug 557225.
exePath = exePath.AppendASCII(MOZ_CHILD_PROCESS_BUNDLE);
#endif
}
}
if (exePath.empty()) {
@ -226,7 +223,6 @@ uint32_t GeckoChildProcessHost::GetSupportedArchitecturesForProcessType(GeckoPro
// Cache this, it shouldn't ever change.
static uint32_t pluginContainerArchs = 0;
if (pluginContainerArchs == 0) {
CacheGreDir();
FilePath exePath;
GetPathToBinary(exePath);
nsresult rv = GetArchitecturesForBinary(exePath.value().c_str(), &pluginContainerArchs);
@ -252,42 +248,10 @@ GeckoChildProcessHost::PrepareLaunch()
#endif
#ifdef XP_WIN
InitWindowsGroupID();
#endif
CacheGreDir();
}
//static
void
GeckoChildProcessHost::CacheGreDir()
{
if (sGreDir) {
return;
if (mProcessType == GeckoProcessType_Plugin) {
InitWindowsGroupID();
}
#ifdef MOZ_WIDGET_GONK
// Apparently, this ASSERT should be present on all platforms. Currently,
// this assert causes mochitest failures on the Mac platform if its left in.
// B2G overrides the directory service in JS, so this needs to be called
// on the main thread.
MOZ_ASSERT(NS_IsMainThread());
#endif
if (ShouldHaveDirectoryService()) {
nsCOMPtr<nsIProperties> directoryService(do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID));
MOZ_ASSERT(directoryService, "Expected XPCOM to be available");
if (directoryService) {
// getter_AddRefs doesn't work with StaticRefPtr, so we need to store the
// result in an nsCOMPtr and copy it over.
nsCOMPtr<nsIFile> greDir;
nsresult rv = directoryService->Get(NS_GRE_DIR, NS_GET_IID(nsIFile), getter_AddRefs(greDir));
if (NS_SUCCEEDED(rv)) {
sGreDir = greDir;
mozilla::ClearOnShutdown(&sGreDir);
}
}
}
}
#ifdef XP_WIN
@ -551,65 +515,63 @@ GeckoChildProcessHost::PerformAsyncLaunchInternal(std::vector<std::string>& aExt
// since LD_LIBRARY_PATH is already set correctly in subprocesses
// (meaning that we don't need to set that up in the environment).
if (ShouldHaveDirectoryService()) {
MOZ_ASSERT(sGreDir);
if (sGreDir) {
nsCString path;
MOZ_ALWAYS_TRUE(NS_SUCCEEDED(sGreDir->GetNativePath(path)));
MOZ_ASSERT(gGREPath);
nsCString path;
NS_CopyUnicodeToNative(nsDependentString(gGREPath), path);
# if defined(OS_LINUX) || defined(OS_BSD)
# if defined(MOZ_WIDGET_ANDROID)
path += "/lib";
path += "/lib";
# endif // MOZ_WIDGET_ANDROID
const char *ld_library_path = PR_GetEnv("LD_LIBRARY_PATH");
nsCString new_ld_lib_path;
if (ld_library_path && *ld_library_path) {
new_ld_lib_path.Assign(path.get());
new_ld_lib_path.Append(':');
new_ld_lib_path.Append(ld_library_path);
newEnvVars["LD_LIBRARY_PATH"] = new_ld_lib_path.get();
} else {
newEnvVars["LD_LIBRARY_PATH"] = path.get();
}
const char *ld_library_path = PR_GetEnv("LD_LIBRARY_PATH");
nsCString new_ld_lib_path;
if (ld_library_path && *ld_library_path) {
new_ld_lib_path.Assign(path.get());
new_ld_lib_path.Append(':');
new_ld_lib_path.Append(ld_library_path);
newEnvVars["LD_LIBRARY_PATH"] = new_ld_lib_path.get();
} else {
newEnvVars["LD_LIBRARY_PATH"] = path.get();
}
# if (MOZ_WIDGET_GTK == 3)
if (mProcessType == GeckoProcessType_Plugin) {
const char *ld_preload = PR_GetEnv("LD_PRELOAD");
nsCString new_ld_preload;
if (mProcessType == GeckoProcessType_Plugin) {
const char *ld_preload = PR_GetEnv("LD_PRELOAD");
nsCString new_ld_preload;
new_ld_preload.Assign(path.get());
new_ld_preload.AppendLiteral("/" DLL_PREFIX "mozgtk2" DLL_SUFFIX);
new_ld_preload.Assign(path.get());
new_ld_preload.AppendLiteral("/" DLL_PREFIX "mozgtk2" DLL_SUFFIX);
if (ld_preload && *ld_preload) {
new_ld_preload.AppendLiteral(":");
new_ld_preload.Append(ld_preload);
}
newEnvVars["LD_PRELOAD"] = new_ld_preload.get();
if (ld_preload && *ld_preload) {
new_ld_preload.AppendLiteral(":");
new_ld_preload.Append(ld_preload);
}
newEnvVars["LD_PRELOAD"] = new_ld_preload.get();
}
# endif // MOZ_WIDGET_GTK
# elif OS_MACOSX
newEnvVars["DYLD_LIBRARY_PATH"] = path.get();
// XXX DYLD_INSERT_LIBRARIES should only be set when launching a plugin
// process, and has no effect on other subprocesses (the hooks in
// libplugin_child_interpose.dylib become noops). But currently it
// gets set when launching any kind of subprocess.
//
// Trigger "dyld interposing" for the dylib that contains
// plugin_child_interpose.mm. This allows us to hook OS calls in the
// plugin process (ones that don't work correctly in a background
// process). Don't break any other "dyld interposing" that has already
// been set up by whatever may have launched the browser.
const char* prevInterpose = PR_GetEnv("DYLD_INSERT_LIBRARIES");
nsCString interpose;
if (prevInterpose) {
interpose.Assign(prevInterpose);
interpose.Append(':');
}
interpose.Append(path.get());
interpose.AppendLiteral("/libplugin_child_interpose.dylib");
newEnvVars["DYLD_INSERT_LIBRARIES"] = interpose.get();
# endif // OS_LINUX
newEnvVars["DYLD_LIBRARY_PATH"] = path.get();
// XXX DYLD_INSERT_LIBRARIES should only be set when launching a plugin
// process, and has no effect on other subprocesses (the hooks in
// libplugin_child_interpose.dylib become noops). But currently it
// gets set when launching any kind of subprocess.
//
// Trigger "dyld interposing" for the dylib that contains
// plugin_child_interpose.mm. This allows us to hook OS calls in the
// plugin process (ones that don't work correctly in a background
// process). Don't break any other "dyld interposing" that has already
// been set up by whatever may have launched the browser.
const char* prevInterpose = PR_GetEnv("DYLD_INSERT_LIBRARIES");
nsCString interpose;
if (prevInterpose) {
interpose.Assign(prevInterpose);
interpose.Append(':');
}
interpose.Append(path.get());
interpose.AppendLiteral("/libplugin_child_interpose.dylib");
newEnvVars["DYLD_INSERT_LIBRARIES"] = interpose.get();
# endif // OS_LINUX
}
#endif // OS_LINUX || OS_MACOSX

View File

@ -135,8 +135,6 @@ public:
// For bug 943174: Skip the EnsureProcessTerminated call in the destructor.
void SetAlreadyDead();
static void CacheGreDir();
protected:
GeckoProcessType mProcessType;
ChildPrivileges mPrivileges;
@ -203,9 +201,6 @@ private:
//
// FIXME/cjones: this strongly indicates bad design. Shame on us.
std::queue<IPC::Message> mQueue;
static StaticRefPtr<nsIFile> sGreDir;
static DebugOnly<bool> sGreDirCached;
};
#ifdef MOZ_NUWA_PROCESS

View File

@ -275,11 +275,12 @@ void LogTerm();
extern bool gXPCOMShuttingDown;
extern bool gXPCOMThreadsShutDown;
extern char16_t* gGREPath; // Needed by the IPC layer from off the main thread
namespace mozilla {
namespace services {
/**
/**
* Clears service cache, sets gXPCOMShuttingDown
*/
void Shutdown();

View File

@ -270,6 +270,7 @@ nsXPTIInterfaceInfoManagerGetSingleton(nsISupports* outer,
nsComponentManagerImpl* nsComponentManagerImpl::gComponentManager = nullptr;
bool gXPCOMShuttingDown = false;
bool gXPCOMThreadsShutDown = false;
char16_t* gGREPath = nullptr;
static NS_DEFINE_CID(kComponentManagerCID, NS_COMPONENTMANAGER_CID);
static NS_DEFINE_CID(kINIParserFactoryCID, NS_INIPARSERFACTORY_CID);
@ -564,15 +565,18 @@ NS_InitXPCOM2(nsIServiceManager* *result,
}
nsCOMPtr<nsIFile> xpcomLib;
nsDirectoryService::gService->Get(NS_GRE_DIR,
NS_GET_IID(nsIFile),
getter_AddRefs(xpcomLib));
MOZ_ASSERT(xpcomLib);
if (xpcomLib) {
xpcomLib->AppendNative(nsDependentCString(XPCOM_DLL));
nsDirectoryService::gService->Set(NS_XPCOM_LIBRARY_FILE, xpcomLib);
}
// set gGREPath
nsAutoString path;
xpcomLib->GetPath(path);
gGREPath = ToNewUnicode(path);
xpcomLib->AppendNative(nsDependentCString(XPCOM_DLL));
nsDirectoryService::gService->Set(NS_XPCOM_LIBRARY_FILE, xpcomLib);
if (!mozilla::Omnijar::IsInitialized()) {
mozilla::Omnijar::Init();
@ -719,10 +723,6 @@ NS_InitXPCOM2(nsIServiceManager* *result,
mozilla::eventtracer::Init();
#endif
// TODO: Cache the GRE dir here instead of telling GeckoChildProcessHost to do it.
// Then have GeckoChildProcessHost get the dir from XPCOM::GetGREPath().
mozilla::ipc::GeckoChildProcessHost::CacheGreDir();
return NS_OK;
}
@ -881,6 +881,9 @@ ShutdownXPCOM(nsIServiceManager* servMgr)
// Release the directory service
NS_IF_RELEASE(nsDirectoryService::gService);
NS_Free(gGREPath);
gGREPath = nullptr;
if (moduleLoaders) {
bool more;
nsCOMPtr<nsISupports> el;