Bug 484442: Firefox crashes on on bringing up safe-mode with any/all of the Options Checked. r=mossop
authorBenjamin Smedberg <benjamin@smedbergs.us>
Tue, 21 Apr 2009 11:36:44 -0700
changeset 27580 22a5636b3f9d6c17f27fa3f7574271bd80a9dc5b
parent 27579 30ac20416be4c46eb323f0f4a6ffe1c840c85d93
child 27581 524233971e2c0b172dd6fc9bffd85aa95db886c6
push id6624
push userdtownsend@mozilla.com
push dateTue, 21 Apr 2009 18:37:51 +0000
treeherdermozilla-central@22a5636b3f9d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmossop
bugs484442
milestone1.9.2a1pre
Bug 484442: Firefox crashes on on bringing up safe-mode with any/all of the Options Checked. r=mossop
toolkit/components/startup/public/nsIAppStartup.idl
toolkit/components/startup/src/nsAppStartup.cpp
toolkit/components/startup/src/nsAppStartup.h
toolkit/xre/nsAppRunner.cpp
--- a/toolkit/components/startup/public/nsIAppStartup.idl
+++ b/toolkit/components/startup/public/nsIAppStartup.idl
@@ -109,16 +109,22 @@ interface nsIAppStartup : nsISupports
      *
      * @param aMode
      *        This parameter modifies how the app is shutdown, and it is
      *        constructed from the constants defined above.
      */
     void quit(in PRUint32 aMode);
 };
 
+[scriptable, uuid(3012668f-44b6-49b1-89fb-761a912a78c1)]
+interface nsIAppStartup2 : nsIAppStartup
+{
+    readonly attribute boolean shuttingDown;
+};
+
 %{C++
 /**
  * This success code may be returned by nsIAppStartup::Run to indicate that the
  * application should be restarted.  This condition corresponds to the case in
  * which nsIAppStartup::Quit was called with the eRestart flag.
  */
 #define NS_SUCCESS_RESTART_APP \
     NS_ERROR_GENERATE_SUCCESS(NS_ERROR_MODULE_GENERAL, 1)
--- a/toolkit/components/startup/src/nsAppStartup.cpp
+++ b/toolkit/components/startup/src/nsAppStartup.cpp
@@ -123,18 +123,19 @@ nsAppStartup::Init()
   return NS_OK;
 }
 
 
 //
 // nsAppStartup->nsISupports
 //
 
-NS_IMPL_THREADSAFE_ISUPPORTS5(nsAppStartup,
+NS_IMPL_THREADSAFE_ISUPPORTS6(nsAppStartup,
                               nsIAppStartup,
+                              nsIAppStartup2,
                               nsIWindowCreator,
                               nsIWindowCreator2,
                               nsIObserver,
                               nsISupportsWeakReference)
 
 
 //
 // nsAppStartup->nsIAppStartup
@@ -419,16 +420,27 @@ nsAppStartup::ExitLastWindowClosingSurvi
   if (!mShuttingDown && mRunning && (mConsiderQuitStopper == 0))
     Quit(eConsiderQuit);
 #endif
 
   return NS_OK;
 }
 
 //
+// nsAppStartup->nsIAppStartup2
+//
+
+NS_IMETHODIMP
+nsAppStartup::GetShuttingDown(PRBool *aResult)
+{
+  *aResult = mShuttingDown;
+  return NS_OK;
+}
+
+//
 // nsAppStartup->nsIWindowCreator
 //
 
 NS_IMETHODIMP
 nsAppStartup::CreateChromeWindow(nsIWebBrowserChrome *aParent,
                                  PRUint32 aChromeFlags,
                                  nsIWebBrowserChrome **_retval)
 {
--- a/toolkit/components/startup/src/nsAppStartup.h
+++ b/toolkit/components/startup/src/nsAppStartup.h
@@ -50,24 +50,25 @@
 
 struct PLEvent;
 
 // {7DD4D320-C84B-4624-8D45-7BB9B2356977}
 #define NS_TOOLKIT_APPSTARTUP_CID \
 { 0x7dd4d320, 0xc84b, 0x4624, { 0x8d, 0x45, 0x7b, 0xb9, 0xb2, 0x35, 0x69, 0x77 } }
 
 
-class nsAppStartup : public nsIAppStartup,
+class nsAppStartup : public nsIAppStartup2,
                      public nsIWindowCreator2,
                      public nsIObserver,
                      public nsSupportsWeakReference
 {
 public:
   NS_DECL_ISUPPORTS
   NS_DECL_NSIAPPSTARTUP
+  NS_DECL_NSIAPPSTARTUP2
   NS_DECL_NSIWINDOWCREATOR
   NS_DECL_NSIWINDOWCREATOR2
   NS_DECL_NSIOBSERVER
 
   nsAppStartup();
   nsresult Init();
 
 private:
--- a/toolkit/xre/nsAppRunner.cpp
+++ b/toolkit/xre/nsAppRunner.cpp
@@ -3169,17 +3169,17 @@ XRE_main(int argc, char* argv[], const n
           nsCOMPtr<nsIObserver> startupNotifier
             (do_CreateInstance(NS_APPSTARTUPNOTIFIER_CONTRACTID, &rv));
           NS_ENSURE_SUCCESS(rv, 1);
 
           startupNotifier->Observe(nsnull, APPSTARTUP_TOPIC, nsnull);
           NS_TIMELINE_LEAVE("startupNotifier");
         }
 
-        nsCOMPtr<nsIAppStartup> appStartup
+        nsCOMPtr<nsIAppStartup2> appStartup
           (do_GetService(NS_APPSTARTUP_CONTRACTID));
         NS_ENSURE_TRUE(appStartup, 1);
 
         if (gDoMigration) {
           nsCOMPtr<nsIFile> file;
           dirProvider.GetAppDir()->Clone(getter_AddRefs(file));
           file->AppendNative(NS_LITERAL_CSTRING("override.ini"));
           nsINIParser parser;
@@ -3201,166 +3201,185 @@ XRE_main(int argc, char* argv[], const n
           gDoMigration = PR_FALSE;
           nsCOMPtr<nsIProfileMigrator> pm
             (do_CreateInstance(NS_PROFILEMIGRATOR_CONTRACTID));
           if (pm)
             pm->Migrate(&dirProvider);
         }
         dirProvider.DoStartup();
 
-        nsCOMPtr<nsICommandLineRunner> cmdLine
-          (do_CreateInstance("@mozilla.org/toolkit/command-line;1"));
-        NS_ENSURE_TRUE(cmdLine, 1);
-
-        nsCOMPtr<nsIFile> workingDir;
-        rv = NS_GetSpecialDirectory(NS_OS_CURRENT_WORKING_DIR, getter_AddRefs(workingDir));
-        NS_ENSURE_SUCCESS(rv, 1);
-
-        rv = cmdLine->Init(gArgc, gArgv,
-                           workingDir, nsICommandLine::STATE_INITIAL_LAUNCH);
-        NS_ENSURE_SUCCESS(rv, 1);
-
-        /* Special-case services that need early access to the command
-           line. */
-        nsCOMPtr<nsIObserver> chromeObserver
-          (do_GetService("@mozilla.org/chrome/chrome-registry;1"));
-        if (chromeObserver) {
-          chromeObserver->Observe(cmdLine, "command-line-startup", nsnull);
-        }
-
-        NS_TIMELINE_ENTER("appStartup->CreateHiddenWindow");
-        rv = appStartup->CreateHiddenWindow();
-        NS_TIMELINE_LEAVE("appStartup->CreateHiddenWindow");
-        NS_ENSURE_SUCCESS(rv, 1);
+        PRBool shuttingDown = PR_FALSE;
+        appStartup->GetShuttingDown(&shuttingDown);
+
+        nsCOMPtr<nsICommandLineRunner> cmdLine;
 
 #if defined(HAVE_DESKTOP_STARTUP_ID) && defined(MOZ_WIDGET_GTK2)
         nsRefPtr<nsGTKToolkit> toolkit = GetGTKToolkit();
         if (toolkit && !desktopStartupID.IsEmpty()) {
           toolkit->SetDesktopStartupID(desktopStartupID);
         }
 #endif
 
-        // Extension Compatibility Checking and Startup
-        if (gAppData->flags & NS_XRE_ENABLE_EXTENSION_MANAGER) {
-          nsCOMPtr<nsIExtensionManager> em(do_GetService("@mozilla.org/extensions/manager;1"));
-          NS_ENSURE_TRUE(em, 1);
-
-          ar = CheckArg("install-global-extension", PR_TRUE);
-          if (ar == ARG_BAD) {
-            PR_fprintf(PR_STDERR, "Error: argument -install-global-extension is invalid when argument -osint is specified\n");
-            return 1;
-          } else if (ar == ARG_FOUND) {
-            // Do the required processing and then shut down.
-            em->HandleCommandLineArgs(cmdLine);
-            return 0;
+        if (!shuttingDown) {
+          cmdLine = do_CreateInstance("@mozilla.org/toolkit/command-line;1");
+          NS_ENSURE_TRUE(cmdLine, 1);
+
+          nsCOMPtr<nsIFile> workingDir;
+          rv = NS_GetSpecialDirectory(NS_OS_CURRENT_WORKING_DIR, getter_AddRefs(workingDir));
+          NS_ENSURE_SUCCESS(rv, 1);
+
+          rv = cmdLine->Init(gArgc, gArgv,
+                             workingDir, nsICommandLine::STATE_INITIAL_LAUNCH);
+          NS_ENSURE_SUCCESS(rv, 1);
+
+          /* Special-case services that need early access to the command
+             line. */
+          nsCOMPtr<nsIObserver> chromeObserver
+            (do_GetService("@mozilla.org/chrome/chrome-registry;1"));
+          if (chromeObserver) {
+            chromeObserver->Observe(cmdLine, "command-line-startup", nsnull);
           }
 
-          ar = CheckArg("install-global-theme", PR_TRUE);
-          if (ar == ARG_BAD) {
-            PR_fprintf(PR_STDERR, "Error: argument -install-global-theme is invalid when argument -osint is specified\n");
-            return 1;
-          } else if (ar == ARG_FOUND) {
-            // Do the required processing and then shut down.
-            em->HandleCommandLineArgs(cmdLine);
-            return 0;
+          NS_TIMELINE_ENTER("appStartup->CreateHiddenWindow");
+          rv = appStartup->CreateHiddenWindow();
+          NS_TIMELINE_LEAVE("appStartup->CreateHiddenWindow");
+          NS_ENSURE_SUCCESS(rv, 1);
+
+          // Extension Compatibility Checking and Startup
+          if (gAppData->flags & NS_XRE_ENABLE_EXTENSION_MANAGER) {
+            nsCOMPtr<nsIExtensionManager> em(do_GetService("@mozilla.org/extensions/manager;1"));
+            NS_ENSURE_TRUE(em, 1);
+
+            ar = CheckArg("install-global-extension", PR_TRUE);
+            if (ar == ARG_BAD) {
+              PR_fprintf(PR_STDERR, "Error: argument -install-global-extension is invalid when argument -osint is specified\n");
+              return 1;
+            } else if (ar == ARG_FOUND) {
+              // Do the required processing and then shut down.
+              em->HandleCommandLineArgs(cmdLine);
+              return 0;
+            }
+
+            ar = CheckArg("install-global-theme", PR_TRUE);
+            if (ar == ARG_BAD) {
+              PR_fprintf(PR_STDERR, "Error: argument -install-global-theme is invalid when argument -osint is specified\n");
+              return 1;
+            } else if (ar == ARG_FOUND) {
+              // Do the required processing and then shut down.
+              em->HandleCommandLineArgs(cmdLine);
+              return 0;
+            }
+
+            if (upgraded) {
+              rv = em->CheckForMismatches(&needsRestart);
+              if (NS_FAILED(rv)) {
+                needsRestart = PR_FALSE;
+                upgraded = PR_FALSE;
+              }
+            }
+            
+            if (!upgraded || !needsRestart)
+              em->Start(cmdLine, &needsRestart);
           }
 
-          if (upgraded) {
-            rv = em->CheckForMismatches(&needsRestart);
-            if (NS_FAILED(rv)) {
-              needsRestart = PR_FALSE;
-              upgraded = PR_FALSE;
+          // We want to restart no more than 2 times. The first restart,
+          // NO_EM_RESTART == "0" , and the second time, "1".
+          char* noEMRestart = PR_GetEnv("NO_EM_RESTART");
+          if (noEMRestart && *noEMRestart && *noEMRestart == '1') {
+            if (upgraded || needsRestart) {
+              NS_WARNING("EM tried to force us to restart twice! Forcefully preventing that.");
             }
+            needsRestart = upgraded = PR_FALSE;
           }
-
-          if (!upgraded || !needsRestart)
-            em->Start(cmdLine, &needsRestart);
-        }
-
-        // We want to restart no more than 2 times. The first restart,
-        // NO_EM_RESTART == "0" , and the second time, "1".
-        char* noEMRestart = PR_GetEnv("NO_EM_RESTART");
-        if (noEMRestart && *noEMRestart && *noEMRestart == '1') {
-          if (upgraded || needsRestart) {
-            NS_WARNING("EM tried to force us to restart twice! Forcefully preventing that.");
-          }
-          needsRestart = upgraded = PR_FALSE;
         }
 
         if (!upgraded && !needsRestart) {
           SaveStateForAppInitiatedRestart();
 
           // clear out any environment variables which may have been set 
           // during the relaunch process now that we know we won't be relaunching.
           PR_SetEnv("XRE_PROFILE_PATH=");
           PR_SetEnv("XRE_PROFILE_LOCAL_PATH=");
           PR_SetEnv("XRE_PROFILE_NAME=");
           PR_SetEnv("XRE_START_OFFLINE=");
           PR_SetEnv("XRE_IMPORT_PROFILES=");
           PR_SetEnv("NO_EM_RESTART=");
           PR_SetEnv("XUL_APP_FILE=");
           PR_SetEnv("XRE_BINARY_PATH=");
 
+          if (!shuttingDown) {
 #ifdef XP_MACOSX
-          // we re-initialize the command-line service and do appleevents munging
-          // after we are sure that we're not restarting
-          cmdLine = do_CreateInstance("@mozilla.org/toolkit/command-line;1");
-          NS_ENSURE_TRUE(cmdLine, 1);
-
-          SetupMacCommandLine(gArgc, gArgv);
-
-          rv = cmdLine->Init(gArgc, gArgv,
-                             workingDir, nsICommandLine::STATE_INITIAL_LAUNCH);
-          NS_ENSURE_SUCCESS(rv, 1);
+            // we re-initialize the command-line service and do appleevents munging
+            // after we are sure that we're not restarting
+            cmdLine = do_CreateInstance("@mozilla.org/toolkit/command-line;1");
+            NS_ENSURE_TRUE(cmdLine, 1);
+
+            SetupMacCommandLine(gArgc, gArgv);
+
+            rv = cmdLine->Init(gArgc, gArgv,
+                               workingDir, nsICommandLine::STATE_INITIAL_LAUNCH);
+            NS_ENSURE_SUCCESS(rv, 1);
 #endif
 #ifdef MOZ_WIDGET_COCOA
-          // Prepare Cocoa's form of Apple Event handling.
-          SetupMacApplicationDelegate();
+            // Prepare Cocoa's form of Apple Event handling.
+            SetupMacApplicationDelegate();
 #endif
-          nsCOMPtr<nsIObserverService> obsService
-            (do_GetService("@mozilla.org/observer-service;1"));
-          if (obsService)
-            obsService->NotifyObservers(nsnull, "final-ui-startup", nsnull);
-
-          rv = cmdLine->Run();
-          NS_ENSURE_SUCCESS_LOG(rv, 1);
-
+
+            nsCOMPtr<nsIObserverService> obsService
+              (do_GetService("@mozilla.org/observer-service;1"));
+            if (obsService)
+              obsService->NotifyObservers(nsnull, "final-ui-startup", nsnull);
+
+            appStartup->GetShuttingDown(&shuttingDown);
+          }
+
+          if (!shuttingDown) {
+            rv = cmdLine->Run();
+            NS_ENSURE_SUCCESS_LOG(rv, 1);
+
+            appStartup->GetShuttingDown(&shuttingDown);
+          }
+
+          nsCOMPtr<nsIRemoteService> remoteService;
+          if (!shuttingDown) {
 #ifdef MOZ_ENABLE_XREMOTE
-          // if we have X remote support, start listening for requests on the
-          // proxy window.
-          nsCOMPtr<nsIRemoteService> remoteService;
-          remoteService = do_GetService("@mozilla.org/toolkit/remote-service;1");
-          if (remoteService)
-            remoteService->Startup(gAppData->name,
-                                   PromiseFlatCString(profileName).get());
+            // if we have X remote support, start listening for requests on the
+            // proxy window.
+            remoteService = do_GetService("@mozilla.org/toolkit/remote-service;1");
+            if (remoteService)
+              remoteService->Startup(gAppData->name,
+                                     PromiseFlatCString(profileName).get());
 #endif /* MOZ_ENABLE_XREMOTE */
 
-          // enable win32 DDE responses and Mac appleevents responses
-          nativeApp->Enable();
+            // enable win32 DDE responses and Mac appleevents responses
+            nativeApp->Enable();
+          }
 
           NS_TIMELINE_ENTER("appStartup->Run");
           rv = appStartup->Run();
           NS_TIMELINE_LEAVE("appStartup->Run");
           if (NS_FAILED(rv)) {
             NS_ERROR("failed to run appstartup");
             gLogConsoleErrors = PR_TRUE;
           }
 
           // Check for an application initiated restart.  This is one that
           // corresponds to nsIAppStartup.quit(eRestart)
           if (rv == NS_SUCCESS_RESTART_APP) {
             needsRestart = PR_TRUE;
             appInitiatedRestart = PR_TRUE;
           }
 
+          if (!shuttingDown) {
 #ifdef MOZ_ENABLE_XREMOTE
-          // shut down the x remote proxy window
-          if (remoteService)
-            remoteService->Shutdown();
+            // shut down the x remote proxy window
+            if (remoteService)
+              remoteService->Shutdown();
 #endif /* MOZ_ENABLE_XREMOTE */
+          }
 
 #ifdef MOZ_TIMELINE
           // Make sure we print this out even if timeline is runtime disabled
           if (NS_FAILED(NS_TIMELINE_LEAVE("main1")))
             NS_TimelineForceMark("...main1");
 #endif
         }
         else {