Bug 1332173 - Rollup patch. Align nsSuiteApp.cpp with nsBrowserApp.cpp. r=IanN a=IanN
authorEdmund Wong <ewong@pw-wspx.org>
Sun, 22 Jan 2017 18:09:12 +0100
changeset 24101 0ac5cccaad09773d8c5be2ddd345643e9c450cac
parent 24100 c789fe71e02c0b1396da5e8c5c1107a1598dfad4
child 24102 0b133d08280371eb9dcd007bbf91d90676a5edd5
push id1973
push userclokep@gmail.com
push dateMon, 23 Jan 2017 21:55:50 +0000
treeherdercomm-aurora@9b85bcae26a8 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersIanN, IanN
bugs1332173, 1306327, 1330533, 1332523
Bug 1332173 - Rollup patch. Align nsSuiteApp.cpp with nsBrowserApp.cpp. r=IanN a=IanN Port Bug 1306327 [Build an XPCOM startup API specifically for the Firefox stub] Port Bug 1330533 [Simplify LibFuzzer setup] Port Bug 1332523 [Cleanup bootstrap API]
suite/app/moz.build
suite/app/nsSuiteApp.cpp
--- a/suite/app/moz.build
+++ b/suite/app/moz.build
@@ -14,16 +14,19 @@ LOCAL_INCLUDES += [
 ]
 
 if CONFIG['OS_ARCH'] == 'WINNT':
     RCINCLUDE = 'splash.rc'
     DEFINES['MOZ_SUITE'] = True
 
 if CONFIG['LIBFUZZER']:
     USE_LIBS += [ 'fuzzer' ]
+    LOCAL_INCLUDES += [
+        '/mozilla//tools/fuzzing/libfuzzer',
+    ]
 
 if CONFIG['_MSC_VER']:
     # Always enter a Windows program through wmain, whether or not we're
     # a console application.
     WIN32_EXE_LDFLAGS += ['-ENTRY:wmainCRTStartup']
 
 if CONFIG['MOZ_SANDBOX'] and CONFIG['OS_ARCH'] == 'WINNT':
     # For sandbox includes and the include dependencies those have
--- a/suite/app/nsSuiteApp.cpp
+++ b/suite/app/nsSuiteApp.cpp
@@ -1,17 +1,17 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* 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 "nsXULAppAPI.h"
 #include "mozilla/XREAppData.h"
 #include "application.ini.h"
-#include "nsXPCOMGlue.h"
+#include "mozilla/Bootstrap.h"
 #if defined(XP_WIN)
 #include <windows.h>
 #include <stdlib.h>
 #elif defined(XP_UNIX)
 #include <sys/resource.h>
 #include <unistd.h>
 #endif
 
@@ -38,16 +38,20 @@
 #include "BinaryPath.h"
 
 #include "nsXPCOMPrivate.h" // for MAXPATHLEN and XPCOM_DLL
 
 #include "mozilla/Sprintf.h"
 #include "mozilla/Telemetry.h"
 #include "mozilla/WindowsDllBlocklist.h"
 
+#ifdef LIBFUZZER
+#include "FuzzerDefs.h"
+#endif
+
 #ifdef MOZ_LINUX_32_SSE2_STARTUP_ERROR
 #include <cpuid.h>
 #include "mozilla/Unused.h"
 
 static bool
 IsSSE2Available()
 {
   // The rest of the app has been compiled to assume that SSE2 is present
@@ -84,36 +88,37 @@ SSE2Check()
   MOZ_UNUSED(write(STDERR_FILENO,
                    sSSE2Message,
                    MOZ_ARRAY_LENGTH(sSSE2Message) - 1));
   // _exit() instead of exit() to avoid running the usual "at exit" code.
   _exit(255);
 }
 #endif
 
-#if !defined(MOZ_WIDGET_COCOA) && !defined(MOZ_WIDGET_ANDROID) \
-  && !(defined(XP_LINUX) && defined(MOZ_SANDBOX))
+#if !defined(MOZ_WIDGET_COCOA) && !defined(MOZ_WIDGET_ANDROID)
 #define MOZ_BROWSER_CAN_BE_CONTENTPROC
 #include "../../mozilla/ipc/contentproc/plugin-container.cpp"
 #endif
 
 using namespace mozilla;
 
 #ifdef XP_MACOSX
 #define kOSXResourcesFolder "Resources"
 #endif
+#define kDesktopFolder ""
 
 static void Output(const char *fmt, ... )
 {
   va_list ap;
   va_start(ap, fmt);
 
-#ifdef XP_WIN
+#ifndef XP_WIN
+  vfprintf(stderr, fmt, ap);
+#else
   char msg[2048];
-
   vsnprintf_s(msg, _countof(msg), _TRUNCATE, fmt, ap);
 
   wchar_t wide_msg[2048];
   MultiByteToWideChar(CP_UTF8,
                       0,
                       msg,
                       -1,
                       wide_msg,
@@ -130,18 +135,16 @@ static void Output(const char *fmt, ... 
     if (messageBoxW) {
       messageBoxW(nullptr, wide_msg, L"XULRunner", MB_OK
                                                  | MB_ICONERROR
                                                  | MB_SETFOREGROUND);
     }
     FreeLibrary(user32);
   }
 #endif
-#else
-  vfprintf(stderr, fmt, ap);
 #endif
 
   va_end(ap);
 }
 
 /**
  * Return true if |arg| matches the given argument name.
  */
@@ -157,89 +160,30 @@ static bool IsArg(const char* arg, const
 #if defined(XP_WIN)
   if (*arg == '/')
     return !strcasecmp(++arg, s);
 #endif
 
   return false;
 }
 
-XRE_GetFileFromPathType XRE_GetFileFromPath;
-XRE_ParseAppDataType XRE_ParseAppData;
-XRE_TelemetryAccumulateType XRE_TelemetryAccumulate;
-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;
-#ifdef LIBFUZZER
-XRE_LibFuzzerSetMainType XRE_LibFuzzerSetMain;
-XRE_LibFuzzerGetFuncsType XRE_LibFuzzerGetFuncs;
-#endif
+Bootstrap::UniquePtr gBootstrap;
 
-static const nsDynamicFunctionLoad kXULFuncs[] = {
-    { "XRE_GetFileFromPath", (NSFuncPtr*) &XRE_GetFileFromPath },
-    { "XRE_ParseAppData", (NSFuncPtr*) &XRE_ParseAppData },
-    { "XRE_TelemetryAccumulate", (NSFuncPtr*) &XRE_TelemetryAccumulate },
-    { "XRE_StartupTimelineRecord", (NSFuncPtr*) &XRE_StartupTimelineRecord },
-    { "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 },
-#ifdef LIBFUZZER
-    { "XRE_LibFuzzerSetMain", (NSFuncPtr*) &XRE_LibFuzzerSetMain },
-    { "XRE_LibFuzzerGetFuncs", (NSFuncPtr*) &XRE_LibFuzzerGetFuncs },
-#endif
-    { nullptr, nullptr }
-};
-
-#ifdef LIBFUZZER
-int libfuzzer_main(int argc, char **argv);
-
-/* This wrapper is used by the libFuzzer main to call into libxul */
-
-void libFuzzerGetFuncs(const char* moduleName, LibFuzzerInitFunc* initFunc,
-                       LibFuzzerTestingFunc* testingFunc) {
-  return XRE_LibFuzzerGetFuncs(moduleName, initFunc, testingFunc);
-}
-#endif
-
-static int do_main(int argc, char* argv[], char* envp[], nsIFile *xreDirectory)
+static int do_main(int argc, char* argv[], char* envp[])
 {
-  nsCOMPtr<nsIFile> appini;
-  nsresult rv;
-  uint32_t mainFlags = 0;
-
   // Allow seamonkey.exe to launch XULRunner apps via -app <application.ini>
   // Note that -app must be the *first* argument.
   const char *appDataFile = getenv("XUL_APP_FILE");
-  if (appDataFile && *appDataFile) {
-    rv = XRE_GetFileFromPath(appDataFile, getter_AddRefs(appini));
-    if (NS_FAILED(rv)) {
-      Output("Invalid path found: '%s'", appDataFile);
-      return 255;
-    }
-  }
-  else if (argc > 1 && IsArg(argv[1], "app")) {
+  if ((!appDataFile || !*appDataFile) &&
+      (argc > 1 && IsArg(argv[1], "app"))) {
     if (argc == 2) {
       Output("Incorrect number of arguments passed to -app");
       return 255;
     }
-
-    rv = XRE_GetFileFromPath(argv[2], getter_AddRefs(appini));
-    if (NS_FAILED(rv)) {
-      Output("application.ini path not recognized: '%s'", argv[2]);
-      return 255;
-    }
+    appDataFile = argv[2];
 
     char appEnv[MAXPATHLEN];
     SprintfLiteral(appEnv, "XUL_APP_FILE=%s", argv[2]);
     // Bug 1271574 Purposefully leak the XUL_APP_FILE string passed to putenv.
     if (putenv(strdup(appEnv))) {
       Output("Couldn't set %s.\n", appEnv);
       return 255;
     }
@@ -247,223 +191,132 @@ static int do_main(int argc, char* argv[
     argv += 2;
     argc -= 2;
   } else if (argc > 1 && IsArg(argv[1], "xpcshell")) {
     for (int i = 1; i < argc; i++) {
       argv[i] = argv[i + 1];
     }
 
     XREShellData shellData;
-
 #if defined(XP_WIN) && defined(MOZ_SANDBOX)
     shellData.sandboxBrokerServices =
       sandboxing::GetInitializedBrokerServices();
 #endif
 
-    return XRE_XPCShellMain(--argc, argv, envp, &shellData);
+    return gBootstrap->XRE_XPCShellMain(--argc, argv, envp, &shellData);
   }
 
-  XREAppData appData;
-  appData.xreDirectory = xreDirectory;
+  BootstrapConfig config;
 
-  if (appini) {
-    rv = XRE_ParseAppData(appini, appData);
-    if (NS_FAILED(rv)) {
-      Output("Couldn't read application.ini");
-      return 255;
-    }
-
-    appini->GetParent(getter_AddRefs(appData.directory));
+  if (appDataFile && *appDataFile) {
+    config.appData = nullptr;
+    config.appDataPath = appDataFile;
   } else {
     // no -app flag so we use the compiled-in app data
-    appData = sAppData;
-
-    nsCOMPtr<nsIFile> exeFile;
-    rv = mozilla::BinaryPath::GetFile(argv[0], getter_AddRefs(exeFile));
-    if (NS_FAILED(rv)) {
-      Output("Couldn't find the application directory.\n");
-      return 255;
-    }
-
-    nsCOMPtr<nsIFile> greDir;
-    exeFile->GetParent(getter_AddRefs(greDir));
-#ifdef XP_MACOSX
-    greDir->SetNativeLeafName(NS_LITERAL_CSTRING(kOSXResourcesFolder));
-#endif
-    nsCOMPtr<nsIFile> appDir;
-    greDir->Clone(getter_AddRefs(appDir));
-    appData.directory = appDir;
+    config.appData = &sAppData;
+    config.appDataPath = kDesktopFolder;
   }
 
-#if defined(HAS_DLL_BLOCKLIST)
-  // The dll blocklist operates in the exe vs. xullib. Pass a flag to
-  // xullib so automated tests can check the result once the browser
-  // is up and running.
-  appData.flags |=
-    DllBlocklist_CheckStatus() ? NS_XRE_DLL_BLOCKLIST_ENABLED : 0;
-#endif
-
 #if defined(XP_WIN) && defined(MOZ_SANDBOX)
   sandbox::BrokerServices* brokerServices =
     sandboxing::GetInitializedBrokerServices();
 #if defined(MOZ_CONTENT_SANDBOX)
   if (!brokerServices) {
     Output("Couldn't initialize the broker services.\n");
     return 255;
   }
 #endif
-  appData.sandboxBrokerServices = brokerServices;
+  config.sandboxBrokerServices = brokerServices;
 #endif
 
 #ifdef LIBFUZZER
   if (getenv("LIBFUZZER"))
-    XRE_LibFuzzerSetMain(argc, argv, libfuzzer_main);
+    gBootstrap->XRE_LibFuzzerSetDriver(fuzzer::FuzzerDriver);
 #endif
 
-  return XRE_main(argc, argv, appData, mainFlags);
-}
-
-static bool
-FileExists(const char *path)
-{
-#ifdef XP_WIN
-  wchar_t wideDir[MAX_PATH];
-  MultiByteToWideChar(CP_UTF8, 0, path, -1, wideDir, MAX_PATH);
-  DWORD fileAttrs = GetFileAttributesW(wideDir);
-  return fileAttrs != INVALID_FILE_ATTRIBUTES;
-#else
-  return access(path, R_OK) == 0;
-#endif
+  return gBootstrap->XRE_main(argc, argv, config);
 }
 
 static nsresult
-InitXPCOMGlue(const char *argv0, nsIFile **xreDirectory)
+InitXPCOMGlue(const char *argv0)
 {
-  char exePath[MAXPATHLEN];
-
-  nsresult rv = mozilla::BinaryPath::Get(argv0, exePath);
-  if (NS_FAILED(rv)) {
+  UniqueFreePtr<char> exePath = BinaryPath::Get(argv0);
+  if (!exePath) {
     Output("Couldn't find the application directory.\n");
-    return rv;
-  }
-
-  char *lastSlash = strrchr(exePath, XPCOM_FILE_PATH_SEPARATOR[0]);
-  if (!lastSlash ||
-      (size_t(lastSlash - exePath) > MAXPATHLEN - sizeof(XPCOM_DLL) - 1))
-    return NS_ERROR_FAILURE;
-
-  strcpy(lastSlash + 1, XPCOM_DLL);
-
-  if (!FileExists(exePath)) {
-    Output("Could not find the Mozilla runtime.\n");
     return NS_ERROR_FAILURE;
   }
 
-  // We do this because of data in bug 771745
-  XPCOMGlueEnablePreload();
-
-  rv = XPCOMGlueStartup(exePath);
-  if (NS_FAILED(rv)) {
+  gBootstrap = mozilla::GetBootstrap(exePath.get());
+  if (!gBootstrap) {
     Output("Couldn't load XPCOM.\n");
-    return rv;
-  }
-
-  rv = XPCOMGlueLoadXULFunctions(kXULFuncs);
-  if (NS_FAILED(rv)) {
-    Output("Couldn't load XRE functions.\n");
-    return rv;
+    return NS_ERROR_FAILURE;
   }
 
   // This will set this thread as the main thread.
-  NS_LogInit();
+  gBootstrap->NS_LogInit();
 
-  if (xreDirectory) {
-    // chop XPCOM_DLL off exePath
-    *lastSlash = '\0';
-#ifdef XP_MACOSX
-    lastSlash = strrchr(exePath, XPCOM_FILE_PATH_SEPARATOR[0]);
-    strcpy(lastSlash + 1, kOSXResourcesFolder);
-#endif
-#ifdef XP_WIN
-    rv = NS_NewLocalFile(NS_ConvertUTF8toUTF16(exePath), false,
-                         xreDirectory);
-#else
-    rv = NS_NewNativeLocalFile(nsDependentCString(exePath), false,
-                               xreDirectory);
-#endif
-  }
-
-  return rv;
+  return NS_OK;
 }
 
 int main(int argc, char* argv[], char* envp[])
 {
   mozilla::TimeStamp start = mozilla::TimeStamp::Now();
 
 #ifdef HAS_DLL_BLOCKLIST
   DllBlocklist_Initialize();
-
-#ifdef DEBUG
-  // In order to be effective against AppInit DLLs, the blocklist must be
-  // initialized before user32.dll is loaded into the process (bug 932100).
-  if (GetModuleHandleA("user32.dll")) {
-    fprintf(stderr, "DLL blocklist was unable to intercept AppInit DLLs.\n");
-  }
-#endif
 #endif
 
 #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 (IsSandboxedProcess() && !sandboxing::GetInitializedTargetServices()) {
       Output("Failed to initialize the sandbox target services.");
       return 255;
     }
 #endif
 
-    nsresult rv = InitXPCOMGlue(argv[0], nullptr);
+    nsresult rv = InitXPCOMGlue(argv[0]);
     if (NS_FAILED(rv)) {
       return 255;
     }
 
-    int result = content_process_main(argc, argv);
+    int result = content_process_main(gBootstrap.get(), argc, argv);
 
     // InitXPCOMGlue calls NS_LogInit, so we need to balance it here.
-    NS_LogTerm();
+    gBootstrap->NS_LogTerm();
 
     return result;
   }
 #endif
 
 
-  nsCOMPtr<nsIFile> xreDirectory;
-
-  nsresult rv = InitXPCOMGlue(argv[0], getter_AddRefs(xreDirectory));
+  nsresult rv = InitXPCOMGlue(argv[0]);
   if (NS_FAILED(rv)) {
     return 255;
   }
 
-  XRE_StartupTimelineRecord(mozilla::StartupTimeline::START, start);
+  gBootstrap->XRE_StartupTimelineRecord(mozilla::StartupTimeline::START, start);
 
 #ifdef MOZ_BROWSER_CAN_BE_CONTENTPROC
-  XRE_EnableSameExecutableForContentProc();
+  gBootstrap->XRE_EnableSameExecutableForContentProc();
 #endif
 
-  int result = do_main(argc, argv, envp, xreDirectory);
+  int result = do_main(argc, argv, envp);
 
-  xreDirectory = nullptr;
-  NS_LogTerm();
+  gBootstrap->NS_LogTerm();
 
 #ifdef XP_MACOSX
   // Allow writes again. While we would like to catch writes from static
   // destructors to allow early exits to use _exit, we know that there is
   // at least one such write that we don't control (see bug 826029). For
   // now we enable writes again and early exits will have to use exit instead
   // of _exit.
-  XRE_StopLateWriteChecks();
+  gBootstrap->XRE_StopLateWriteChecks();
 #endif
 
+  gBootstrap.reset();
+
   return result;
 }