Platform/Integration/InjectEject/Launcher Process/

From MozillaWiki
Jump to: navigation, search

Introduction

In Windows builds of Firefox, the Launcher Process is the initial process that is started when the user runs Firefox. Its sole purpose is to create the browser process in a suspended state, configure the browser process, resume the browser process, and then hand off GUI foreground to the browser. Once the launcher process has completed this objective, it exits.

The configuration actions performed by the launcher process provide security, performance, and stability enhancements that improve the Firefox user experience:

  • The launcher process creates the browser process with various process mitigation policies, dependent on the underlying version of Windows.
  • If the launcher process was started by a user running with full Administrator privileges (ie. at a high integrity level), it configures the browser to run as a normal user.
  • The launcher process performs early initialization of the DLL blocklist.

Since the launcher process is part of the critical path of Firefox startup, special considerations need to be taken when working on its code:

  • Its code must be as fast and efficient as possible;
  • It must recover gracefully from failures;
  • Its code must be self-contained inside firefox.exe;
  • Its code cannot start nor rely on prefs, XPCOM, nsString, crash reporter, or other aspects of the Gecko runtime. Header-only code that does not depend on xul.dll (such as MFBT) is safe to use in the launcher process;
  • Some parts of its code must be freestanding -- that is, those parts cannot assume the presence of either the C runtime or the Win32 API.

Considerations for Users

Dropping Full Administrator Privileges

The Launcher Process selects one of multiple techniques for dropping the privileges of the browser process:

  • When UAC is enabled, the launcher process requests that Explorer starts the browser. This ensures that the browser runs under the privileges of the user whose desktop we are currently running in. As an example of a scenario where this might be useful, suppose that a user is starting Firefox from within their command prompt, but they accidentally used their elevated command prompt instead of their normal command prompt.
  • When UAC is disabled, the launcher process duplicates the user's token and drops the duplicate token's integrity level from high to medium. The launcher process then creates the browser process using that medium-integrity token.
    • Firefox will not have write access to directories that are configured with a high-integrity ACL. By default, this includes root directories, \Program Files, \windows\system32, among others.
    • Firefox will be affected by User Interface Privilege Isolation (UIPI); the Firefox UI is not allowed to communicate with other UI running at higher integrity levels. Since the user's desktop and other applications are most likely still running at high integrity level, the Firefox UI will not be able to communicate with them. This means that certain GUI features such as drag-and-drop will not work.
    • We have an article in the SUMO Knowledge Base instructing users on how to mitigate these issues.
      • Note: Do not advise users to attempt these suggestions unless it is known for a fact that they are running as Administrator with UAC disabled! It is not a "catch-all" solution for launcher process problems.

Starting Firefox via Automation / Scripting

As mentioned in the introduction, once the launcher process has handed GUI foreground off to the browser process, the launcher process exits. For users who are starting Firefox via a batch file or script, this may present a problem if the script is written to assume that Firefox has closed before continuing to execute.

The solution to this is to modify the script by adding the -wait-for-browser option to the Firefox command line.

The launcher process also implicitly waits for the browser under any combination of the following conditions:

  • Firefox is started with the -marionette command line option;
  • Firefox is started with the -headless command line option;
  • Firefox is started with the MOZ_AUTOMATION environment variable set;
  • Firefox is started with the MOZ_HEADLESS environment variable set;

Why does the Launcher Process not wait for the browser by default?

  • Over the course of a Firefox browsing session, the launcher process would lie dormant and its private virtual memory would eventually be paged out to disk. However, it would still be visible as yet another firefox.exe process in the operating system's process list.
    • To avoid the launcher process being charged against Firefox's overall resource usage (and the public perceptions that doing so would entail), we let the launcher process exit.
    • We also do not want launcher process VM to be unnecessarily occupying space in the page file on machines where there is limited page file space. This is not uncommon - see our various OOM crash reports if you don't believe it!
  • This would not work with the scenario where an elevated launcher process asks Explorer to restart the browser as a normal user; Explorer does not return any process ID or handle information to the launcher process, so there is nothing for the launcher process to wait on. This would introduce an undesirable inconsistency in the command-line behavior of the launcher process. By explicitly opting into waiting for the browser process, the launcher process adjusts its behavior to avoid this scenario, but uses a less desirable mechanism for restarting the browser.

Considerations for Developers

  • The launcher process is enabled by default both in local and CI builds. In local builds, the launcher process may be disabled by default by specifying the --disable-launcher-process option in mozconfig. Leaving this as its default is preferred to ensure that the launcher process receives just as much testing as our other processes.
    • If you have disabled the launcher process by default in your local build, but would like to run it during a test, use the -launcher command-line option.
  • Both mach run and mach gtest automatically specify the -wait-for-browser option when starting Firefox. Visual Studio projects generated by the build system also automatically include this flag when running Firefox.
  • Developers using the Visual Studio Debugger should install the Child Process Debugging Power Tool to enable the debugger to attach to multiple processes simultaneously.
  • WinDbg users should either open Firefox with the Debug child processes also option checked, or if starting from the command line, including the -o option.

The Launcher Process also supports the following environment variables for debugging:

  • Setting MOZ_DEBUG_BROWSER_PROCESS causes the browser process to trigger a breakpoint during initial startup;
  • Setting MOZ_DEBUG_BROWSER_PAUSE to a positive integer causes the browser process to print its process ID to stderr and pause for MOZ_DEBUG_BROWSER_PAUSE seconds before resuming, thus offering the developer a chance to attach a debugger.

As previously mentioned, the launcher process is designed to be resilient against failures. If the launcher process encounters an error, it automatically disables itself for future instantiations of Firefox. On the other hand, developers may want to intentionally reproduce those failures. To forcibly run the launcher process despite being previously disabled, specify the -force-launcher option on the command line.

Other Troubleshooting

If the launcher process fails and telemetry is enabled, the launcher process generates and sends a telemetry ping containing an error code and the source code location of the failure. If telemetry is disabled, or if for some reason the launcher process was unable to successfully send its telemetry ping, the launcher process will log the failure to the Windows event log.

To view launcher process failure events in the system event viewer, open the Control Panel [Note: this must be the legacy Control Panel app, not the new Settings app found in Windows 8 and Windows 10], select Administrative Tools, and double-click on Event Viewer. Looking at the tree in the left pane, expand the Windows Logs branch, and click Application.

It is also possible to force the launcher process to always log failures to the Windows event log by adding the -log-launcher-error option to the command line. This may be useful when assisting specific users who are experiencing launcher process failures.