Bug Summary

File:var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dist/include/mozilla/CmdLineAndEnvUtils.h
Warning:line 710, column 1
Potential leak of memory pointed to by 'expr'

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name nsAppRunner.cpp -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=all -relaxed-aliasing -ffp-contract=off -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/toolkit/xre -fcoverage-compilation-dir=/var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/toolkit/xre -resource-dir /usr/lib/llvm-18/lib/clang/18 -include /var/lib/jenkins/workspace/firefox-scan-build/config/gcc_hidden.h -include /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/mozilla-config.h -I /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dist/stl_wrappers -I /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dist/system_wrappers -U _FORTIFY_SOURCE -D _FORTIFY_SOURCE=2 -D DEBUG=1 -D TELEMETRY_PING_FORMAT_VERSION=4 -D PROXY_PRINTING=1 -D USE_GLX_TEST -D MOZ_APP_NAME="firefox" -D MOZ_APP_BASENAME="Firefox" -D MOZ_APP_DISPLAYNAME="Nightly" -D MOZ_APP_VENDOR="Mozilla" -D MOZ_APP_VERSION="128.0a1" -D OS_TARGET="Linux" -D MOZ_WIDGET_TOOLKIT="gtk" -D MOZ_UPDATER -D MOZ_DISTRIBUTION_ID="org.mozilla" -D TARGET_OS_ABI="Linux_x86_64-gcc3" -D GRE_MILESTONE=128.0a1 -D MOZ_APP_VERSION_DISPLAY=128.0a1 -D APP_VERSION=128.0a1 -D APP_ID={ec8030f7-c20a-464f-9b0e-13a3a9e97384} -D MOZ_BUILD_APP_IS_BROWSER -D MAR_NSS -D TOPOBJDIR=/var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu -D MOZ_HAS_MOZGLUE -D MOZILLA_INTERNAL_API -D IMPL_LIBXUL -D STATIC_EXPORTABLE_JS_API -I /var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre -I /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/toolkit/xre -I /var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/remote -I /var/lib/jenkins/workspace/firefox-scan-build/widget -I /var/lib/jenkins/workspace/firefox-scan-build/widget/gtk -I /var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/printingui -I /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/ipc/ipdl/_ipdlheaders -I /var/lib/jenkins/workspace/firefox-scan-build/ipc/chromium/src -I /var/lib/jenkins/workspace/firefox-scan-build/other-licenses/nsis/Contrib/CityHash/cityhash -I /var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/find -I /var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/printingui/ipc -I /var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/windowwatcher -I /var/lib/jenkins/workspace/firefox-scan-build/toolkit/mozapps/update/common -I /var/lib/jenkins/workspace/firefox-scan-build/toolkit/profile -I /var/lib/jenkins/workspace/firefox-scan-build/config -I /var/lib/jenkins/workspace/firefox-scan-build/dom/base -I /var/lib/jenkins/workspace/firefox-scan-build/dom/commandhandler -I /var/lib/jenkins/workspace/firefox-scan-build/dom/ipc -I /var/lib/jenkins/workspace/firefox-scan-build/dom/webbrowserpersist -I /var/lib/jenkins/workspace/firefox-scan-build/testing/gtest/mozilla -I /var/lib/jenkins/workspace/firefox-scan-build/toolkit/crashreporter -I /var/lib/jenkins/workspace/firefox-scan-build/xpcom/build -I /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dist/include -I /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dist/include/nspr -I /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dist/include/nss -D MOZILLA_CLIENT -I /usr/include/dbus-1.0 -I /usr/lib/x86_64-linux-gnu/dbus-1.0/include -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib/x86_64-linux-gnu/glib-2.0/include -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/x86_64-linux-gnu -I /usr/include/webp -I /usr/include/gio-unix-2.0 -I /usr/include/cloudproviders -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/at-spi-2.0 -I /usr/include/dbus-1.0 -I /usr/lib/x86_64-linux-gnu/dbus-1.0/include -I /usr/include/gtk-3.0/unix-print -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib/x86_64-linux-gnu/glib-2.0/include -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/cairo -I /usr/include/pixman-1 -internal-isystem /usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13 -internal-isystem /usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/x86_64-linux-gnu/c++/13 -internal-isystem /usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/backward -internal-isystem /usr/lib/llvm-18/lib/clang/18/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-error=tautological-type-limit-compare -Wno-invalid-offsetof -Wno-range-loop-analysis -Wno-deprecated-anon-enum-enum-conversion -Wno-deprecated-enum-enum-conversion -Wno-deprecated-this-capture -Wno-inline-new-delete -Wno-error=deprecated-declarations -Wno-error=array-bounds -Wno-error=free-nonheap-object -Wno-error=atomic-alignment -Wno-error=deprecated-builtins -Wno-psabi -Wno-error=builtin-macro-redefined -Wno-vla-cxx-extension -Wno-unknown-warning-option -fdeprecated-macro -ferror-limit 19 -stack-protector 2 -fstack-clash-protection -ftrivial-auto-var-init=pattern -fno-rtti -fgnuc-version=4.2.1 -fno-aligned-allocation -vectorize-loops -vectorize-slp -analyzer-checker optin.performance.Padding -analyzer-output=html -analyzer-config stable-report-filename=true -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /tmp/scan-build-2024-05-16-034744-15991-1 -x c++ /var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp

/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp

1/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2/* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5
6#include "mozilla/dom/ContentParent.h"
7#include "mozilla/dom/ContentChild.h"
8#include "mozilla/ipc/GeckoChildProcessHost.h"
9
10#include "mozilla/AppShutdown.h"
11#include "mozilla/ArrayUtils.h"
12#include "mozilla/Assertions.h"
13#include "mozilla/Attributes.h"
14#include "mozilla/Components.h"
15#include "mozilla/FilePreferences.h"
16#include "mozilla/ChaosMode.h"
17#include "mozilla/CmdLineAndEnvUtils.h"
18#include "mozilla/IOInterposer.h"
19#include "mozilla/ipc/UtilityProcessChild.h"
20#include "mozilla/Likely.h"
21#include "mozilla/MemoryChecking.h"
22#include "mozilla/Poison.h"
23#include "mozilla/Preferences.h"
24#include "mozilla/PreferenceSheet.h"
25#include "mozilla/Printf.h"
26#include "mozilla/ProcessType.h"
27#include "mozilla/ResultExtensions.h"
28#include "mozilla/RuntimeExceptionModule.h"
29#include "mozilla/ScopeExit.h"
30#include "mozilla/StaticPrefs_browser.h"
31#include "mozilla/StaticPrefs_fission.h"
32#include "mozilla/StaticPrefs_webgl.h"
33#include "mozilla/StaticPrefs_widget.h"
34#include "mozilla/Telemetry.h"
35#include "mozilla/Utf8.h"
36#include "mozilla/intl/LocaleService.h"
37#include "mozilla/JSONWriter.h"
38#include "mozilla/gfx/gfxVars.h"
39#include "mozilla/glean/GleanMetrics.h"
40#include "mozilla/glean/GleanPings.h"
41#include "mozilla/widget/TextRecognition.h"
42#include "BaseProfiler.h"
43
44#include "nsAppRunner.h"
45#include "mozilla/XREAppData.h"
46#include "mozilla/Bootstrap.h"
47#if defined(MOZ_UPDATER1) && !defined(MOZ_WIDGET_ANDROID)
48# include "nsUpdateDriver.h"
49# include "nsUpdateSyncManager.h"
50#endif
51#include "ProfileReset.h"
52
53#ifdef MOZ_INSTRUMENT_EVENT_LOOP1
54# include "EventTracer.h"
55#endif
56
57#ifdef XP_MACOSX
58# include "nsVersionComparator.h"
59# include "MacLaunchHelper.h"
60# include "MacApplicationDelegate.h"
61# include "MacAutoreleasePool.h"
62# include "MacRunFromDmgUtils.h"
63// these are needed for sysctl
64# include <sys/types.h>
65# include <sys/sysctl.h>
66#endif
67
68#include "prnetdb.h"
69#include "prprf.h"
70#include "prproces.h"
71#include "prenv.h"
72#include "prtime.h"
73
74#include "nsIAppStartup.h"
75#include "nsCategoryManagerUtils.h"
76#include "nsIMutableArray.h"
77#include "nsCommandLine.h"
78#include "nsIComponentRegistrar.h"
79#include "nsIDialogParamBlock.h"
80#include "mozilla/ModuleUtils.h"
81#include "nsIIOService.h"
82#include "nsIObserverService.h"
83#include "nsINativeAppSupport.h"
84#include "nsIPlatformInfo.h"
85#include "nsIProcess.h"
86#include "nsIProfileUnlocker.h"
87#include "nsIPromptService.h"
88#include "nsIPropertyBag2.h"
89#include "nsIServiceManager.h"
90#include "nsIStringBundle.h"
91#include "nsISupportsPrimitives.h"
92#include "nsIToolkitProfile.h"
93#include "nsToolkitProfileService.h"
94#include "nsIURI.h"
95#include "nsIURL.h"
96#include "nsIWindowCreator.h"
97#include "nsIWindowWatcher.h"
98#include "nsIXULAppInfo.h"
99#include "nsIXULRuntime.h"
100#include "nsPIDOMWindow.h"
101#include "nsIWidget.h"
102#include "nsAppShellCID.h"
103#include "mozilla/dom/quota/QuotaManager.h"
104#include "mozilla/scache/StartupCache.h"
105#include "gfxPlatform.h"
106#include "PDMFactory.h"
107#ifdef XP_MACOSX
108# include "gfxPlatformMac.h"
109#endif
110
111#include "mozilla/Unused.h"
112
113#ifdef XP_WIN
114# include "nsIWinAppHelper.h"
115# include <windows.h>
116# include <intrin.h>
117# include <math.h>
118# include "cairo/cairo-features.h"
119# include "detect_win32k_conflicts.h"
120# include "mozilla/PreXULSkeletonUI.h"
121# include "mozilla/DllPrefetchExperimentRegistryInfo.h"
122# include "mozilla/WindowsBCryptInitialization.h"
123# include "mozilla/WindowsDllBlocklist.h"
124# include "mozilla/WindowsMsctfInitialization.h"
125# include "mozilla/WindowsProcessMitigations.h"
126# include "mozilla/WindowsVersion.h"
127# include "mozilla/WinHeaderOnlyUtils.h"
128# include "mozilla/mscom/ProcessRuntime.h"
129# include "mozilla/mscom/ProfilerMarkers.h"
130# include "WinTokenUtils.h"
131
132# if defined(MOZ_LAUNCHER_PROCESS)
133# include "mozilla/LauncherRegistryInfo.h"
134# endif
135
136# if defined(MOZ_DEFAULT_BROWSER_AGENT)
137# include "nsIWindowsRegKey.h"
138# endif
139
140# ifndef PROCESS_DEP_ENABLE
141# define PROCESS_DEP_ENABLE 0x1
142# endif
143#endif
144
145#if defined(MOZ_SANDBOX1)
146# include "mozilla/SandboxSettings.h"
147#endif
148
149#ifdef ACCESSIBILITY1
150# include "nsAccessibilityService.h"
151# if defined(XP_WIN)
152# include "mozilla/a11y/Compatibility.h"
153# include "mozilla/a11y/Platform.h"
154# endif
155#endif
156
157#include "nsCRT.h"
158#include "nsCOMPtr.h"
159#include "nsDirectoryServiceDefs.h"
160#include "nsDirectoryServiceUtils.h"
161#include "nsEmbedCID.h"
162#include "nsIDUtils.h"
163#include "nsNetUtil.h"
164#include "nsReadableUtils.h"
165#include "nsXPCOM.h"
166#include "nsXPCOMCIDInternal.h"
167#include "nsString.h"
168#include "nsPrintfCString.h"
169#include "nsVersionComparator.h"
170
171#include "nsAppDirectoryServiceDefs.h"
172#include "nsXULAppAPI.h"
173#include "nsXREDirProvider.h"
174
175#include "nsINIParser.h"
176#include "mozilla/Omnijar.h"
177#include "mozilla/StartupTimeline.h"
178#include "mozilla/LateWriteChecks.h"
179
180#include <stdlib.h>
181#include <locale.h>
182
183#ifdef XP_UNIX1
184# include <errno(*__errno_location ()).h>
185# include <pwd.h>
186# include <string.h>
187# include <sys/resource.h>
188# include <sys/stat.h>
189# include <unistd.h>
190#endif
191
192#ifdef XP_WIN
193# include <process.h>
194# include <shlobj.h>
195# include "mozilla/WinDllServices.h"
196# include "nsThreadUtils.h"
197# include "WinUtils.h"
198#endif
199
200#ifdef XP_MACOSX
201# include "nsILocalFileMac.h"
202# include "nsCommandLineServiceMac.h"
203#endif
204
205// for X remote support
206#if defined(MOZ_HAS_REMOTE1)
207# include "nsRemoteService.h"
208#endif
209
210#if defined(DEBUG1) && defined(XP_WIN)
211# include <malloc.h>
212#endif
213
214#if defined(XP_MACOSX)
215# include <Carbon/Carbon.h>
216#endif
217
218#ifdef DEBUG1
219# include "mozilla/Logging.h"
220#endif
221
222#ifdef MOZ_JPROF
223# include "jprof.h"
224#endif
225
226#include "nsExceptionHandler.h"
227#include "nsICrashReporter.h"
228#include "nsIPrefService.h"
229#include "nsIMemoryInfoDumper.h"
230#if defined(XP_LINUX1) && !defined(ANDROID)
231# include "mozilla/widget/LSBUtils.h"
232#endif
233
234#include "base/command_line.h"
235#include "GTestRunner.h"
236
237#ifdef MOZ_WIDGET_ANDROID
238# include "mozilla/java/GeckoAppShellWrappers.h"
239#endif
240
241#if defined(MOZ_SANDBOX1)
242# if defined(XP_LINUX1) && !defined(ANDROID)
243# include "mozilla/SandboxInfo.h"
244# elif defined(XP_WIN)
245# include "sandboxBroker.h"
246# endif
247#endif
248
249#ifdef MOZ_CODE_COVERAGE
250# include "mozilla/CodeCoverageHandler.h"
251#endif
252
253#include "GMPProcessChild.h"
254#include "SafeMode.h"
255
256#ifdef MOZ_BACKGROUNDTASKS1
257# include "mozilla/BackgroundTasks.h"
258# include "nsIPowerManagerService.h"
259# include "nsIStringBundle.h"
260#endif
261
262#ifdef USE_GLX_TEST1
263# include "mozilla/GUniquePtr.h"
264# include "mozilla/GfxInfo.h"
265#endif
266
267#ifdef MOZ_WIDGET_GTK1
268# include "nsAppShell.h"
269#endif
270#ifdef MOZ_ENABLE_DBUS1
271# include "DBusService.h"
272#endif
273
274extern uint32_t gRestartMode;
275extern void InstallSignalHandlers(const char* ProgramName);
276
277#define FILE_COMPATIBILITY_INFO"compatibility.ini"_ns "compatibility.ini"_ns
278#define FILE_INVALIDATE_CACHES".purgecaches"_ns ".purgecaches"_ns
279#define FILE_STARTUP_INCOMPLETEu".startup-incomplete"_ns u".startup-incomplete"_ns
280
281#if defined(MOZ_BLOCK_PROFILE_DOWNGRADE1) || defined(MOZ_LAUNCHER_PROCESS) || \
282 defined(MOZ_DEFAULT_BROWSER_AGENT)
283static const char kPrefHealthReportUploadEnabled[] =
284 "datareporting.healthreport.uploadEnabled";
285#endif // defined(MOZ_BLOCK_PROFILE_DOWNGRADE) || defined(MOZ_LAUNCHER_PROCESS)
286 // || defined(MOZ_DEFAULT_BROWSER_AGENT)
287#if defined(MOZ_DEFAULT_BROWSER_AGENT)
288static const char kPrefDefaultAgentEnabled[] = "default-browser-agent.enabled";
289
290static const char kPrefServicesSettingsServer[] = "services.settings.server";
291static const char kPrefSetDefaultBrowserUserChoicePref[] =
292 "browser.shell.setDefaultBrowserUserChoice";
293#endif // defined(MOZ_DEFAULT_BROWSER_AGENT)
294
295#if defined(XP_WIN)
296static const char kPrefThemeId[] = "extensions.activeThemeID";
297static const char kPrefBrowserStartupBlankWindow[] =
298 "browser.startup.blankWindow";
299static const char kPrefPreXulSkeletonUI[] = "browser.startup.preXulSkeletonUI";
300#endif // defined(XP_WIN)
301
302#if defined(MOZ_WIDGET_GTK1)
303constexpr nsLiteralCString kStartupTokenNames[] = {
304 "XDG_ACTIVATION_TOKEN"_ns,
305 "DESKTOP_STARTUP_ID"_ns,
306};
307#endif
308
309int gArgc;
310char** gArgv;
311
312static const char gToolkitVersion[] = MOZ_STRINGIFY(GRE_MILESTONE)"128.0a1";
313// The gToolkitBuildID global is defined to MOZ_BUILDID via gen_buildid.py
314// in toolkit/library. See related comment in toolkit/library/moz.build.
315extern const char gToolkitBuildID[];
316
317static nsIProfileLock* gProfileLock;
318#if defined(MOZ_HAS_REMOTE1)
319static nsRemoteService* gRemoteService;
320bool gRestartWithoutRemote = false;
321#endif
322
323int gRestartArgc;
324char** gRestartArgv;
325
326// If gRestartedByOS is set, we were automatically restarted by the OS.
327bool gRestartedByOS = false;
328
329bool gIsGtest = false;
330
331bool gKioskMode = false;
332int gKioskMonitor = -1;
333
334bool gAllowContentAnalysisArgPresent = false;
335
336nsString gAbsoluteArgv0Path;
337
338#if defined(XP_WIN)
339nsString gProcessStartupShortcut;
340#endif
341
342#if defined(MOZ_WIDGET_GTK1)
343# include <glib.h>
344# include "mozilla/WidgetUtilsGtk.h"
345# include <gtk/gtk.h>
346# ifdef MOZ_WAYLAND1
347# include <gdk/gdkwayland.h>
348# include "mozilla/widget/nsWaylandDisplay.h"
349# include "wayland-proxy.h"
350# endif
351# ifdef MOZ_X111
352# include <gdk/gdkx.h>
353# endif /* MOZ_X11 */
354#endif
355
356#if defined(MOZ_WAYLAND1)
357std::unique_ptr<WaylandProxy> gWaylandProxy;
358#endif
359
360#include "BinaryPath.h"
361
362#ifdef MOZ_LOGGING1
363# include "mozilla/Logging.h"
364extern mozilla::LazyLogModule gWidgetWaylandLog;
365#endif /* MOZ_LOGGING */
366
367#ifdef FUZZING
368# include "FuzzerRunner.h"
369
370namespace mozilla {
371FuzzerRunner* fuzzerRunner = 0;
372} // namespace mozilla
373
374# ifdef LIBFUZZER
375void XRE_LibFuzzerSetDriver(LibFuzzerDriver aDriver) {
376 mozilla::fuzzerRunner->setParams(aDriver);
377}
378# endif
379#endif // FUZZING
380
381// Undo X11/X.h's definition of None
382#undef None
383
384namespace mozilla {
385int (*RunGTest)(int*, char**) = 0;
386
387bool RunningGTest() { return RunGTest; }
388} // namespace mozilla
389
390using namespace mozilla;
391using namespace mozilla::widget;
392using namespace mozilla::startup;
393using mozilla::Unused;
394using mozilla::dom::ContentChild;
395using mozilla::dom::ContentParent;
396using mozilla::dom::quota::QuotaManager;
397using mozilla::intl::LocaleService;
398using mozilla::scache::StartupCache;
399
400// Save the given word to the specified environment variable.
401static void MOZ_NEVER_INLINE__attribute__((noinline)) SaveWordToEnv(const char* name,
402 const nsACString& word) {
403 char* expr =
404 Smprintf("%s=%s", name, PromiseFlatCStringTPromiseFlatString<char>(word).get()).release();
405 if (expr) PR_SetEnv(expr);
406 // We intentionally leak |expr| here since it is required by PR_SetEnv.
407}
408
409// Save the path of the given file to the specified environment variable.
410static void SaveFileToEnv(const char* name, nsIFile* file) {
411#ifdef XP_WIN
412 nsAutoString path;
413 file->GetPath(path);
414 SetEnvironmentVariableW(NS_ConvertASCIItoUTF16(name).get(), path.get());
415#else
416 nsAutoCString path;
417 file->GetNativePath(path);
418 SaveWordToEnv(name, path);
419#endif
420}
421
422static bool gIsExpectedExit = false;
423
424void MozExpectedExit() { gIsExpectedExit = true; }
425
426/**
427 * Runs atexit() to catch unexpected exit from 3rd party libraries like the
428 * Intel graphics driver calling exit in an error condition. When they
429 * call exit() to report an error we won't shutdown correctly and wont catch
430 * the issue with our crash reporter.
431 */
432static void UnexpectedExit() {
433 if (!gIsExpectedExit) {
434 gIsExpectedExit = true; // Don't risk re-entrency issues when crashing.
435 MOZ_CRASH("Exit called by third party code.")do { do { } while (false); MOZ_ReportCrash("" "Exit called by third party code."
, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 435); AnnotateMozCrashReason("MOZ_CRASH(" "Exit called by third party code."
")"); do { *((volatile int*)__null) = 435; __attribute__((nomerge
)) ::abort(); } while (false); } while (false)
;
436 }
437}
438
439#if defined(MOZ_WAYLAND1)
440bool IsWaylandEnabled() {
441 static bool isWaylandEnabled = []() {
442 const char* waylandDisplay = PR_GetEnv("WAYLAND_DISPLAY");
443 if (!waylandDisplay) {
444 return false;
445 }
446 if (!PR_GetEnv("DISPLAY")) {
447 // No X11 display, so try to run wayland.
448 return true;
449 }
450 // MOZ_ENABLE_WAYLAND is our primary Wayland on/off switch.
451 if (const char* waylandPref = PR_GetEnv("MOZ_ENABLE_WAYLAND")) {
452 return *waylandPref == '1';
453 }
454 if (const char* backendPref = PR_GetEnv("GDK_BACKEND")) {
455 if (!strncmp(backendPref, "wayland", 7)) {
456 NS_WARNING(NS_DebugBreak(NS_DEBUG_WARNING, "Wayland backend should be enabled by MOZ_ENABLE_WAYLAND=1."
"GDK_BACKEND is a Gtk3 debug variable and may cause issues."
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 458)
457 "Wayland backend should be enabled by MOZ_ENABLE_WAYLAND=1."NS_DebugBreak(NS_DEBUG_WARNING, "Wayland backend should be enabled by MOZ_ENABLE_WAYLAND=1."
"GDK_BACKEND is a Gtk3 debug variable and may cause issues."
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 458)
458 "GDK_BACKEND is a Gtk3 debug variable and may cause issues.")NS_DebugBreak(NS_DEBUG_WARNING, "Wayland backend should be enabled by MOZ_ENABLE_WAYLAND=1."
"GDK_BACKEND is a Gtk3 debug variable and may cause issues."
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 458)
;
459 return true;
460 }
461 }
462 // Enable by default when we're running on a recent enough GTK version. We'd
463 // like to check further details like compositor version and so on ideally
464 // to make sure we don't enable it on old Mutter or what not, but we can't,
465 // so let's assume that if the user is running on a Wayland session by
466 // default we're ok, since either the distro has enabled Wayland by default,
467 // or the user has gone out of their way to use Wayland.
468 return !gtk_check_version(3, 24, 30);
469 }();
470 return isWaylandEnabled;
471}
472#else
473bool IsWaylandEnabled() { return false; }
474#endif
475
476/**
477 * Output a string to the user. This method is really only meant to be used to
478 * output last-ditch error messages designed for developers NOT END USERS.
479 *
480 * @param isError
481 * Pass true to indicate severe errors.
482 * @param fmt
483 * printf-style format string followed by arguments.
484 */
485static MOZ_FORMAT_PRINTF(2, 3)__attribute__((format(printf, 2, 3))) void Output(bool isError, const char* fmt, ...) {
486 va_list ap;
487 va_start(ap, fmt)__builtin_va_start(ap, fmt);
488
489#if defined(XP_WIN) && !MOZ_WINCONSOLE
490 SmprintfPointer msg = mozilla::Vsmprintf(fmt, ap);
491 if (msg) {
492 UINT flags = MB_OK;
493 if (isError)
494 flags |= MB_ICONERROR;
495 else
496 flags |= MB_ICONINFORMATION;
497
498 wchar_t wide_msg[1024];
499 MultiByteToWideChar(CP_ACP, 0, msg.get(), -1, wide_msg,
500 sizeof(wide_msg) / sizeof(wchar_t));
501
502 MessageBoxW(nullptr, wide_msg, L"XULRunner", flags);
503 }
504#elif defined(MOZ_WIDGET_ANDROID)
505 SmprintfPointer msg = mozilla::Vsmprintf(fmt, ap);
506 if (msg) {
507 __android_log_print(isError ? ANDROID_LOG_ERROR : ANDROID_LOG_INFO,
508 "GeckoRuntime", "%s", msg.get());
509 }
510#else
511 vfprintf(stderrstderr, fmt, ap);
512#endif
513
514 va_end(ap)__builtin_va_end(ap);
515}
516
517/**
518 * Check for a commandline flag. If the flag takes a parameter, the
519 * parameter is returned in aParam. Flags may be in the form -arg or
520 * --arg (or /arg on win32).
521 *
522 * @param aArg the parameter to check. Must be lowercase.
523 * @param aParam if non-null, the -arg <data> will be stored in this pointer.
524 * This is *not* allocated, but rather a pointer to the argv data.
525 * @param aFlags flags @see CheckArgFlag
526 */
527static ArgResult CheckArg(const char* aArg, const char** aParam = nullptr,
528 CheckArgFlag aFlags = CheckArgFlag::RemoveArg) {
529 MOZ_ASSERT(gArgv, "gArgv must be initialized before CheckArg()")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(gArgv)>::isValid, "invalid assertion condition");
if ((__builtin_expect(!!(!(!!(gArgv))), 0))) { do { } while (
false); MOZ_ReportAssertionFailure("gArgv" " (" "gArgv must be initialized before CheckArg()"
")", "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 529); AnnotateMozCrashReason("MOZ_ASSERT" "(" "gArgv" ") ("
"gArgv must be initialized before CheckArg()" ")"); do { *((
volatile int*)__null) = 529; __attribute__((nomerge)) ::abort
(); } while (false); } } while (false)
;
530 return CheckArg(gArgc, gArgv, aArg, aParam, aFlags);
531}
532
533/**
534 * Check for a commandline flag. Ignore data that's passed in with the flag.
535 * Flags may be in the form -arg or --arg (or /arg on win32).
536 * Will not remove flag if found.
537 *
538 * @param aArg the parameter to check. Must be lowercase.
539 */
540static ArgResult CheckArgExists(const char* aArg) {
541 return CheckArg(aArg, nullptr, CheckArgFlag::None);
542}
543
544bool gSafeMode = false;
545bool gFxREmbedded = false;
546
547enum E10sStatus {
548 kE10sEnabledByDefault,
549 kE10sForceDisabled,
550};
551
552static bool gBrowserTabsRemoteAutostart = false;
553static E10sStatus gBrowserTabsRemoteStatus;
554static bool gBrowserTabsRemoteAutostartInitialized = false;
555
556namespace mozilla {
557
558bool BrowserTabsRemoteAutostart() {
559 if (gBrowserTabsRemoteAutostartInitialized) {
560 return gBrowserTabsRemoteAutostart;
561 }
562 gBrowserTabsRemoteAutostartInitialized = true;
563
564 // If we're not in the parent process, we are running E10s.
565 if (!XRE_IsParentProcess()) {
566 gBrowserTabsRemoteAutostart = true;
567 return gBrowserTabsRemoteAutostart;
568 }
569
570 gBrowserTabsRemoteAutostart = true;
571 E10sStatus status = kE10sEnabledByDefault;
572
573 // We use "are non-local connections disabled" as a proxy for
574 // "are we running some kind of automated test". It would be nicer to use
575 // xpc::IsInAutomation(), but that depends on some prefs being set, which
576 // they are not in (at least) gtests (where we can't) and xpcshell.
577 // Long-term, hopefully we can make all tests e10s-friendly,
578 // then we could remove this automation-only env variable.
579 if (gBrowserTabsRemoteAutostart && xpc::AreNonLocalConnectionsDisabled()) {
580 const char* forceDisable = PR_GetEnv("MOZ_FORCE_DISABLE_E10S");
581 if (forceDisable && !strcmp(forceDisable, "1")) {
582 gBrowserTabsRemoteAutostart = false;
583 status = kE10sForceDisabled;
584 }
585 }
586
587 gBrowserTabsRemoteStatus = status;
588
589 return gBrowserTabsRemoteAutostart;
590}
591
592} // namespace mozilla
593
594// Win32k Infrastructure ==============================================
595
596// This bool tells us if we have initialized the following two statics
597// upon startup.
598
599static bool gWin32kInitialized = false;
600
601// Win32k Lockdown for the current session is determined once, at startup,
602// and then remains the same for the duration of the session.
603
604static nsIXULRuntime::ContentWin32kLockdownState gWin32kStatus;
605
606// The status of the win32k experiment. It is determined once, at startup,
607// and then remains the same for the duration of the session.
608
609static nsIXULRuntime::ExperimentStatus gWin32kExperimentStatus =
610 nsIXULRuntime::eExperimentStatusUnenrolled;
611
612#ifdef XP_WIN
613// The states for win32k lockdown can be generalized to:
614// - User doesn't meet requirements (bad OS, webrender, remotegl) aka
615// PersistentRequirement
616// - User has Safe Mode enabled, Win32k Disabled by Env Var, or E10S disabled
617// by Env Var aka TemporaryRequirement
618// - User has set the win32k pref to something non-default aka NonDefaultPref
619// - User has been enrolled in the experiment and does what it says aka
620// Enrolled
621// - User does the default aka Default
622//
623// We expect the below behvaior. In the code, there may be references to these
624// behaviors (e.g. [A]) but not always.
625//
626// [A] Becoming enrolled in the experiment while NonDefaultPref disqualifies
627// you upon next browser start
628// [B] Becoming enrolled in the experiment while PersistentRequirement
629// disqualifies you upon next browser start
630// [C] Becoming enrolled in the experiment while TemporaryRequirement does not
631// disqualify you
632// [D] Becoming enrolled in the experiment will only take effect after restart
633// [E] While enrolled, becoming PersistentRequirement will not disqualify you
634// until browser restart, but if the state is present at browser start,
635// will disqualify you. Additionally, it will not affect the session value
636// of gWin32kStatus.
637// XXX(bobowen): I hope both webrender and wbgl.out-of-process require a
638// restart to take effect!
639// [F] While enrolled, becoming NonDefaultPref will disqualify you upon next
640// browser start
641// [G] While enrolled, becoming TemporaryRequirement will _not_ disqualify you,
642// but the session status will prevent win32k lockdown from taking effect.
643
644// The win32k pref
645static const char kPrefWin32k[] = "security.sandbox.content.win32k-disable";
646
647// The current enrollment status as controlled by Normandy. This value is only
648// stored in the default preference branch, and is not persisted across
649// sessions by the preference service. It therefore isn't available early
650// enough at startup, and needs to be synced to a preference in the user
651// branch which is persisted across sessions.
652static const char kPrefWin32kExperimentEnrollmentStatus[] =
653 "security.sandbox.content.win32k-experiment.enrollmentStatus";
654
655// The enrollment status to be used at browser startup. This automatically
656// synced from the above enrollmentStatus preference whenever the latter is
657// changed. We reused the Fission experiment enum - it can have any of the
658// values defined in the `nsIXULRuntime_ExperimentStatus` enum _except_ rollout.
659// Meanings are documented in the declaration of
660// `nsIXULRuntime.fissionExperimentStatus`
661static const char kPrefWin32kExperimentStartupEnrollmentStatus[] =
662 "security.sandbox.content.win32k-experiment.startupEnrollmentStatus";
663
664namespace mozilla {
665
666bool Win32kExperimentEnrolled() {
667 MOZ_ASSERT(XRE_IsParentProcess())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(XRE_IsParentProcess())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(XRE_IsParentProcess()))), 0)
)) { do { } while (false); MOZ_ReportAssertionFailure("XRE_IsParentProcess()"
, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 667); AnnotateMozCrashReason("MOZ_ASSERT" "(" "XRE_IsParentProcess()"
")"); do { *((volatile int*)__null) = 667; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
668 return gWin32kExperimentStatus == nsIXULRuntime::eExperimentStatusControl ||
669 gWin32kExperimentStatus == nsIXULRuntime::eExperimentStatusTreatment;
670}
671
672} // namespace mozilla
673
674static bool Win32kRequirementsUnsatisfied(
675 nsIXULRuntime::ContentWin32kLockdownState aStatus) {
676 return aStatus == nsIXULRuntime::ContentWin32kLockdownState::
677 OperatingSystemNotSupported ||
678 aStatus ==
679 nsIXULRuntime::ContentWin32kLockdownState::MissingWebRender ||
680 aStatus ==
681 nsIXULRuntime::ContentWin32kLockdownState::MissingRemoteWebGL ||
682 aStatus ==
683 nsIXULRuntime::ContentWin32kLockdownState::DecodersArentRemote;
684}
685
686static void Win32kExperimentDisqualify() {
687 MOZ_ASSERT(XRE_IsParentProcess())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(XRE_IsParentProcess())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(XRE_IsParentProcess()))), 0)
)) { do { } while (false); MOZ_ReportAssertionFailure("XRE_IsParentProcess()"
, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 687); AnnotateMozCrashReason("MOZ_ASSERT" "(" "XRE_IsParentProcess()"
")"); do { *((volatile int*)__null) = 687; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
688 Preferences::SetUint(kPrefWin32kExperimentEnrollmentStatus,
689 nsIXULRuntime::eExperimentStatusDisqualified);
690}
691
692static void OnWin32kEnrollmentStatusChanged(const char* aPref, void* aData) {
693 auto newStatusInt =
694 Preferences::GetUint(kPrefWin32kExperimentEnrollmentStatus,
695 nsIXULRuntime::eExperimentStatusUnenrolled);
696 auto newStatus = newStatusInt < nsIXULRuntime::eExperimentStatusCount
697 ? nsIXULRuntime::ExperimentStatus(newStatusInt)
698 : nsIXULRuntime::eExperimentStatusDisqualified;
699
700 // Set the startup pref for next browser start [D]
701 Preferences::SetUint(kPrefWin32kExperimentStartupEnrollmentStatus, newStatus);
702}
703
704namespace {
705// This observer is notified during `profile-before-change`, and ensures that
706// the experiment enrollment status is synced over before the browser shuts
707// down, even if it was not modified since win32k was initialized.
708class Win32kEnrollmentStatusShutdownObserver final : public nsIObserver {
709 public:
710 NS_DECL_ISUPPORTSpublic: virtual nsresult QueryInterface(const nsIID& aIID
, void** aInstancePtr) override; virtual MozExternalRefCountType
AddRef(void) override; virtual MozExternalRefCountType Release
(void) override; using HasThreadSafeRefCnt = std::false_type;
protected: nsAutoRefCnt mRefCnt; nsAutoOwningThread _mOwningThread
; public:
711
712 NS_IMETHODvirtual nsresult Observe(nsISupports* aSubject, const char* aTopic,
713 const char16_t* aData) override {
714 MOZ_ASSERT(!strcmp("profile-before-change", aTopic))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!strcmp("profile-before-change", aTopic))>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(!strcmp("profile-before-change", aTopic)))), 0))) { do { }
while (false); MOZ_ReportAssertionFailure("!strcmp(\"profile-before-change\", aTopic)"
, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 714); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!strcmp(\"profile-before-change\", aTopic)"
")"); do { *((volatile int*)__null) = 714; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
715 OnWin32kEnrollmentStatusChanged(kPrefWin32kExperimentEnrollmentStatus,
716 nullptr);
717 return NS_OK;
718 }
719
720 private:
721 ~Win32kEnrollmentStatusShutdownObserver() = default;
722};
723NS_IMPL_ISUPPORTS(Win32kEnrollmentStatusShutdownObserver, nsIObserver)MozExternalRefCountType Win32kEnrollmentStatusShutdownObserver
::AddRef(void) { static_assert(!std::is_destructible_v<Win32kEnrollmentStatusShutdownObserver
>, "Reference-counted class " "Win32kEnrollmentStatusShutdownObserver"
" should not have a public destructor. " "Make this class's destructor non-public"
); do { static_assert( mozilla::detail::AssertionConditionType
<decltype(int32_t(mRefCnt) >= 0)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(int32_t(mRefCnt) >= 0))),
0))) { do { } while (false); MOZ_ReportAssertionFailure("int32_t(mRefCnt) >= 0"
" (" "illegal refcnt" ")", "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 723); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) >= 0"
") (" "illegal refcnt" ")"); do { *((volatile int*)__null) =
723; __attribute__((nomerge)) ::abort(); } while (false); } }
while (false); do { static_assert( mozilla::detail::AssertionConditionType
<decltype("Win32kEnrollmentStatusShutdownObserver" != nullptr
)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!("Win32kEnrollmentStatusShutdownObserver" != nullptr)
)), 0))) { do { } while (false); MOZ_ReportAssertionFailure("\"Win32kEnrollmentStatusShutdownObserver\" != nullptr"
" (" "Must specify a name" ")", "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 723); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"Win32kEnrollmentStatusShutdownObserver\" != nullptr"
") (" "Must specify a name" ")"); do { *((volatile int*)__null
) = 723; __attribute__((nomerge)) ::abort(); } while (false);
} } while (false); if (!mRefCnt.isThreadSafe) _mOwningThread
.AssertOwnership("Win32kEnrollmentStatusShutdownObserver" " not thread-safe"
); nsrefcnt count = ++mRefCnt; NS_LogAddRef((this), (count), (
"Win32kEnrollmentStatusShutdownObserver"), (uint32_t)(sizeof(
*this))); return count; } MozExternalRefCountType Win32kEnrollmentStatusShutdownObserver
::Release(void) { do { static_assert( mozilla::detail::AssertionConditionType
<decltype(int32_t(mRefCnt) > 0)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(int32_t(mRefCnt) > 0))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("int32_t(mRefCnt) > 0"
" (" "dup release" ")", "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 723); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) > 0"
") (" "dup release" ")"); do { *((volatile int*)__null) = 723
; __attribute__((nomerge)) ::abort(); } while (false); } } while
(false); do { static_assert( mozilla::detail::AssertionConditionType
<decltype("Win32kEnrollmentStatusShutdownObserver" != nullptr
)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!("Win32kEnrollmentStatusShutdownObserver" != nullptr)
)), 0))) { do { } while (false); MOZ_ReportAssertionFailure("\"Win32kEnrollmentStatusShutdownObserver\" != nullptr"
" (" "Must specify a name" ")", "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 723); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"Win32kEnrollmentStatusShutdownObserver\" != nullptr"
") (" "Must specify a name" ")"); do { *((volatile int*)__null
) = 723; __attribute__((nomerge)) ::abort(); } while (false);
} } while (false); if (!mRefCnt.isThreadSafe) _mOwningThread
.AssertOwnership("Win32kEnrollmentStatusShutdownObserver" " not thread-safe"
); const char* const nametmp = "Win32kEnrollmentStatusShutdownObserver"
; nsrefcnt count = --mRefCnt; NS_LogRelease((this), (count), (
nametmp)); if (count == 0) { mRefCnt = 1; delete (this); return
0; } return count; } nsresult Win32kEnrollmentStatusShutdownObserver
::QueryInterface(const nsIID& aIID, void** aInstancePtr) {
do { if (!(aInstancePtr)) { NS_DebugBreak(NS_DEBUG_ASSERTION
, "QueryInterface requires a non-NULL destination!", "aInstancePtr"
, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 723); MOZ_PretendNoReturn(); } } while (0); nsresult rv = NS_ERROR_FAILURE
; static_assert(1 > 0, "Need more arguments to NS_INTERFACE_TABLE"
); static const QITableEntry table[] = { {&mozilla::detail
::kImplementedIID<Win32kEnrollmentStatusShutdownObserver, nsIObserver
>, int32_t( reinterpret_cast<char*>(static_cast<nsIObserver
*>((Win32kEnrollmentStatusShutdownObserver*)0x1000)) - reinterpret_cast
<char*>((Win32kEnrollmentStatusShutdownObserver*)0x1000
))}, {&mozilla::detail::kImplementedIID<Win32kEnrollmentStatusShutdownObserver
, nsISupports>, int32_t(reinterpret_cast<char*>(static_cast
<nsISupports*>( static_cast<nsIObserver*>((Win32kEnrollmentStatusShutdownObserver
*)0x1000))) - reinterpret_cast<char*>((Win32kEnrollmentStatusShutdownObserver
*)0x1000))}, { nullptr, 0 } } ; static_assert((sizeof(table) /
sizeof(table[0])) > 1, "need at least 1 interface"); rv =
NS_TableDrivenQI(static_cast<void*>(this), aIID, aInstancePtr
, table); return rv; }
724} // namespace
725
726static void OnWin32kChanged(const char* aPref, void* aData) {
727 // If we're actively enrolled in the Win32k experiment, disqualify the user
728 // from the experiment if the Win32k pref is modified. [F]
729 if (Win32kExperimentEnrolled() && Preferences::HasUserValue(kPrefWin32k)) {
730 Win32kExperimentDisqualify();
731 }
732}
733
734#endif // XP_WIN
735
736namespace mozilla {
737void EnsureWin32kInitialized();
738}
739
740nsIXULRuntime::ContentWin32kLockdownState GetLiveWin32kLockdownState() {
741#ifdef XP_WIN
742
743 // HasUserValue The Pref functions can only be called on main thread
744 MOZ_ASSERT(NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 744); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { *((volatile int*)__null) = 744; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
745
746# ifdef MOZ_BACKGROUNDTASKS1
747 if (BackgroundTasks::IsBackgroundTaskMode()) {
748 // Let's bail out before loading all the graphics libs.
749 return nsIXULRuntime::ContentWin32kLockdownState::DisabledByDefault;
750 }
751# endif
752
753 mozilla::EnsureWin32kInitialized();
754 gfxPlatform::GetPlatform();
755
756 if (gSafeMode) {
757 return nsIXULRuntime::ContentWin32kLockdownState::DisabledBySafeMode;
758 }
759
760 if (EnvHasValue("MOZ_ENABLE_WIN32K")) {
761 return nsIXULRuntime::ContentWin32kLockdownState::DisabledByEnvVar;
762 }
763
764 if (!mozilla::BrowserTabsRemoteAutostart()) {
765 return nsIXULRuntime::ContentWin32kLockdownState::DisabledByE10S;
766 }
767
768 // Win32k lockdown is available on Win8+, but we are initially limiting it to
769 // Windows 10 v1709 (build 16299) or later. Before this COM initialization
770 // currently fails if user32.dll has loaded before it is called.
771 if (!IsWin10FallCreatorsUpdateOrLater()) {
772 return nsIXULRuntime::ContentWin32kLockdownState::
773 OperatingSystemNotSupported;
774 }
775
776 {
777 ConflictingMitigationStatus conflictingMitigationStatus = {};
778 if (!detect_win32k_conflicting_mitigations(&conflictingMitigationStatus)) {
779 return nsIXULRuntime::ContentWin32kLockdownState::
780 IncompatibleMitigationPolicy;
781 }
782 if (conflictingMitigationStatus.caller_check ||
783 conflictingMitigationStatus.sim_exec ||
784 conflictingMitigationStatus.stack_pivot) {
785 return nsIXULRuntime::ContentWin32kLockdownState::
786 IncompatibleMitigationPolicy;
787 }
788 }
789
790 // Win32k Lockdown requires Remote WebGL, but it may be disabled on
791 // certain hardware or virtual machines.
792 if (!gfx::gfxVars::AllowWebglOop() || !StaticPrefs::webgl_out_of_process()) {
793 return nsIXULRuntime::ContentWin32kLockdownState::MissingRemoteWebGL;
794 }
795
796 // Some (not sure exactly which) decoders are not compatible
797 if (!PDMFactory::AllDecodersAreRemote()) {
798 return nsIXULRuntime::ContentWin32kLockdownState::DecodersArentRemote;
799 }
800
801 bool prefSetByUser =
802 Preferences::HasUserValue("security.sandbox.content.win32k-disable");
803 bool prefValue = Preferences::GetBool(
804 "security.sandbox.content.win32k-disable", false, PrefValueKind::User);
805 bool defaultValue = Preferences::GetBool(
806 "security.sandbox.content.win32k-disable", false, PrefValueKind::Default);
807
808 if (prefSetByUser) {
809 if (prefValue) {
810 return nsIXULRuntime::ContentWin32kLockdownState::EnabledByUserPref;
811 } else {
812 return nsIXULRuntime::ContentWin32kLockdownState::DisabledByUserPref;
813 }
814 }
815
816 if (gWin32kExperimentStatus ==
817 nsIXULRuntime::ExperimentStatus::eExperimentStatusControl) {
818 return nsIXULRuntime::ContentWin32kLockdownState::DisabledByControlGroup;
819 } else if (gWin32kExperimentStatus ==
820 nsIXULRuntime::ExperimentStatus::eExperimentStatusTreatment) {
821 return nsIXULRuntime::ContentWin32kLockdownState::EnabledByTreatmentGroup;
822 }
823
824 if (defaultValue) {
825 return nsIXULRuntime::ContentWin32kLockdownState::EnabledByDefault;
826 } else {
827 return nsIXULRuntime::ContentWin32kLockdownState::DisabledByDefault;
828 }
829
830#else
831
832 return nsIXULRuntime::ContentWin32kLockdownState::OperatingSystemNotSupported;
833
834#endif
835}
836
837namespace mozilla {
838
839void EnsureWin32kInitialized() {
840 if (gWin32kInitialized) {
841 return;
842 }
843 gWin32kInitialized = true;
844
845#ifdef XP_WIN
846
847 // Initialize the Win32k experiment, configuring win32k's
848 // default, before checking other overrides. This allows opting-out of a
849 // Win32k experiment through about:preferences or about:config from a
850 // safemode session.
851 uint32_t experimentRaw =
852 Preferences::GetUint(kPrefWin32kExperimentStartupEnrollmentStatus,
853 nsIXULRuntime::eExperimentStatusUnenrolled);
854 gWin32kExperimentStatus =
855 experimentRaw < nsIXULRuntime::eExperimentStatusCount
856 ? nsIXULRuntime::ExperimentStatus(experimentRaw)
857 : nsIXULRuntime::eExperimentStatusDisqualified;
858
859 // Watch the experiment enrollment status pref to detect experiment
860 // disqualification, and ensure it is propagated for the next restart.
861 Preferences::RegisterCallback(&OnWin32kEnrollmentStatusChanged,
862 kPrefWin32kExperimentEnrollmentStatus);
863 if (nsCOMPtr<nsIObserverService> observerService =
864 mozilla::services::GetObserverService()) {
865 nsCOMPtr<nsIObserver> shutdownObserver =
866 new Win32kEnrollmentStatusShutdownObserver();
867 observerService->AddObserver(shutdownObserver, "profile-before-change",
868 false);
869 }
870
871 // If the user no longer qualifies because they edited a required pref, check
872 // that. [B] [E]
873 auto tmpStatus = GetLiveWin32kLockdownState();
874 if (Win32kExperimentEnrolled() && Win32kRequirementsUnsatisfied(tmpStatus)) {
875 Win32kExperimentDisqualify();
876 gWin32kExperimentStatus = nsIXULRuntime::eExperimentStatusDisqualified;
877 }
878
879 // If the user has overridden an active experiment by setting a user value for
880 // "security.sandbox.content.win32k-disable", disqualify the user from the
881 // experiment. [A] [F]
882 if (Preferences::HasUserValue(kPrefWin32k) && Win32kExperimentEnrolled()) {
883 Win32kExperimentDisqualify();
884 gWin32kExperimentStatus = nsIXULRuntime::eExperimentStatusDisqualified;
885 }
886
887 // Unlike Fission, we do not configure the default branch based on experiment
888 // enrollment status. Instead we check the startupEnrollmentPref in
889 // GetContentWin32kLockdownState()
890
891 Preferences::RegisterCallback(&OnWin32kChanged, kPrefWin32k);
892
893 // Set the state
894 gWin32kStatus = GetLiveWin32kLockdownState();
895
896#else
897 gWin32kStatus =
898 nsIXULRuntime::ContentWin32kLockdownState::OperatingSystemNotSupported;
899 gWin32kExperimentStatus = nsIXULRuntime::eExperimentStatusUnenrolled;
900
901#endif // XP_WIN
902}
903
904nsIXULRuntime::ContentWin32kLockdownState GetWin32kLockdownState() {
905#ifdef XP_WIN
906
907 mozilla::EnsureWin32kInitialized();
908 return gWin32kStatus;
909
910#else
911
912 return nsIXULRuntime::ContentWin32kLockdownState::OperatingSystemNotSupported;
913
914#endif
915}
916
917} // namespace mozilla
918
919// End Win32k Infrastructure ==========================================
920
921// Fission Infrastructure =============================================
922
923// Fission enablement for the current session is determined once, at startup,
924// and then remains the same for the duration of the session.
925//
926// The following factors determine whether or not Fission is enabled for a
927// session, in order of precedence:
928//
929// - Safe mode: In safe mode, Fission is never enabled.
930//
931// - The MOZ_FORCE_ENABLE_FISSION environment variable: If set to any value,
932// Fission will be enabled.
933//
934// - The 'fission.autostart' preference, if it has been configured by the user.
935static const char kPrefFissionAutostart[] = "fission.autostart";
936
937// The computed FissionAutostart value for the session, read by content
938// processes to initialize gFissionAutostart.
939//
940// This pref is locked, and only configured on the default branch, so should
941// never be persisted in a profile.
942static const char kPrefFissionAutostartSession[] = "fission.autostart.session";
943
944//
945// The computed FissionAutostart value for the session, read by content
946// processes to initialize gFissionAutostart.
947
948static bool gFissionAutostart = false;
949static bool gFissionAutostartInitialized = false;
950static nsIXULRuntime::FissionDecisionStatus gFissionDecisionStatus;
951static void EnsureFissionAutostartInitialized() {
952 if (gFissionAutostartInitialized) {
953 return;
954 }
955 gFissionAutostartInitialized = true;
956
957 if (!XRE_IsParentProcess()) {
958 // This pref is configured for the current session by the parent process.
959 gFissionAutostart = Preferences::GetBool(kPrefFissionAutostartSession,
960 false, PrefValueKind::Default);
961 return;
962 }
963
964 if (!BrowserTabsRemoteAutostart()) {
965 gFissionAutostart = false;
966 if (gBrowserTabsRemoteStatus == kE10sForceDisabled) {
967 gFissionDecisionStatus = nsIXULRuntime::eFissionDisabledByE10sEnv;
968 } else {
969 gFissionDecisionStatus = nsIXULRuntime::eFissionDisabledByE10sOther;
970 }
971 } else if (EnvHasValue("MOZ_FORCE_ENABLE_FISSION")) {
972 gFissionAutostart = true;
973 gFissionDecisionStatus = nsIXULRuntime::eFissionEnabledByEnv;
974 } else if (EnvHasValue("MOZ_FORCE_DISABLE_FISSION")) {
975 gFissionAutostart = false;
976 gFissionDecisionStatus = nsIXULRuntime::eFissionDisabledByEnv;
977 } else {
978 // NOTE: This will take into account changes to the default due to
979 // `InitializeFissionExperimentStatus`.
980 gFissionAutostart = Preferences::GetBool(kPrefFissionAutostart, false);
981 if (Preferences::HasUserValue(kPrefFissionAutostart)) {
982 gFissionDecisionStatus = gFissionAutostart
983 ? nsIXULRuntime::eFissionEnabledByUserPref
984 : nsIXULRuntime::eFissionDisabledByUserPref;
985 } else {
986 gFissionDecisionStatus = gFissionAutostart
987 ? nsIXULRuntime::eFissionEnabledByDefault
988 : nsIXULRuntime::eFissionDisabledByDefault;
989 }
990 }
991
992 // Content processes cannot run the same logic as we're running in the parent
993 // process, as the current value of various preferences may have changed
994 // between launches. Instead, the content process will read the default branch
995 // of the locked `fission.autostart.session` preference to determine the value
996 // determined by this method.
997 Preferences::Unlock(kPrefFissionAutostartSession);
998 Preferences::ClearUser(kPrefFissionAutostartSession);
999 Preferences::SetBool(kPrefFissionAutostartSession, gFissionAutostart,
1000 PrefValueKind::Default);
1001 Preferences::Lock(kPrefFissionAutostartSession);
1002}
1003
1004namespace mozilla {
1005
1006bool FissionAutostart() {
1007 EnsureFissionAutostartInitialized();
1008 return gFissionAutostart;
1009}
1010
1011} // namespace mozilla
1012
1013// End Fission Infrastructure =========================================
1014
1015namespace mozilla {
1016
1017bool SessionHistoryInParent() {
1018 return FissionAutostart() ||
1019 !StaticPrefs::
1020 fission_disableSessionHistoryInParent_AtStartup_DoNotUseDirectly();
1021}
1022
1023bool SessionStorePlatformCollection() {
1024 return SessionHistoryInParent() &&
1025 !StaticPrefs::
1026 browser_sessionstore_disable_platform_collection_AtStartup_DoNotUseDirectly();
1027}
1028
1029bool BFCacheInParent() {
1030 return SessionHistoryInParent() &&
1031 StaticPrefs::fission_bfcacheInParent_DoNotUseDirectly();
1032}
1033
1034} // namespace mozilla
1035
1036/**
1037 * The nsXULAppInfo object implements nsIFactory so that it can be its own
1038 * singleton.
1039 */
1040class nsXULAppInfo : public nsIXULAppInfo,
1041#ifdef XP_WIN
1042 public nsIWinAppHelper,
1043#endif
1044 public nsICrashReporter,
1045 public nsIFinishDumpingCallback,
1046 public nsIXULRuntime
1047
1048{
1049 public:
1050 constexpr nsXULAppInfo() = default;
1051 NS_DECL_ISUPPORTS_INHERITEDpublic: virtual nsresult QueryInterface(const nsIID& aIID
, void** aInstancePtr) override; virtual MozExternalRefCountType
AddRef(void) override; virtual MozExternalRefCountType Release
(void) override;
1052 NS_DECL_NSIPLATFORMINFOvirtual nsresult GetPlatformVersion(nsACString& aPlatformVersion
) override; virtual nsresult GetPlatformBuildID(nsACString&
aPlatformBuildID) override;
1053 NS_DECL_NSIXULAPPINFOvirtual nsresult GetVendor(nsACString& aVendor) override;
virtual nsresult GetName(nsACString& aName) override; virtual
nsresult GetID(nsACString& aID) override; virtual nsresult
GetVersion(nsACString& aVersion) override; virtual nsresult
GetAppBuildID(nsACString& aAppBuildID) override; virtual
nsresult GetUAName(nsACString& aUAName) override; virtual
nsresult GetSourceURL(nsACString& aSourceURL) override; virtual
nsresult GetUpdateURL(nsACString& aUpdateURL) override;
1054 NS_DECL_NSIXULRUNTIMEvirtual nsresult GetInSafeMode(bool *aInSafeMode) override; virtual
nsresult GetWin32kExperimentStatus(nsIXULRuntime::ExperimentStatus
*aWin32kExperimentStatus) override; virtual nsresult GetWin32kLiveStatusTestingOnly
(nsIXULRuntime::ContentWin32kLockdownState *aWin32kLiveStatusTestingOnly
) override; virtual nsresult GetWin32kSessionStatus(nsIXULRuntime
::ContentWin32kLockdownState *aWin32kSessionStatus) override;
virtual nsresult GetFissionAutostart(bool *aFissionAutostart
) override; virtual nsresult GetFissionDecisionStatus(nsIXULRuntime
::FissionDecisionStatus *aFissionDecisionStatus) override; virtual
nsresult GetFissionDecisionStatusString(nsACString& aFissionDecisionStatusString
) override; virtual nsresult GetSessionHistoryInParent(bool *
aSessionHistoryInParent) override; virtual nsresult GetSessionStorePlatformCollection
(bool *aSessionStorePlatformCollection) override; virtual nsresult
GetLogConsoleErrors(bool *aLogConsoleErrors) override; virtual
nsresult SetLogConsoleErrors(bool aLogConsoleErrors) override
; virtual nsresult GetOS(nsACString& aOS) override; virtual
nsresult GetXPCOMABI(nsACString& aXPCOMABI) override; virtual
nsresult GetWidgetToolkit(nsACString& aWidgetToolkit) override
; virtual nsresult GetProcessType(uint32_t *aProcessType) override
; virtual nsresult GetProcessID(uint32_t *aProcessID) override
; virtual nsresult GetUniqueProcessID(uint64_t *aUniqueProcessID
) override; virtual nsresult GetRemoteType(nsACString& aRemoteType
) override; virtual nsresult GetBrowserTabsRemoteAutostart(bool
*aBrowserTabsRemoteAutostart) override; virtual nsresult GetMaxWebProcessCount
(uint32_t *aMaxWebProcessCount) override; virtual nsresult GetAccessibilityEnabled
(bool *aAccessibilityEnabled) override; virtual nsresult GetAccessibilityInstantiator
(nsAString& aAccessibilityInstantiator) override; virtual
nsresult GetIs64Bit(bool *aIs64Bit) override; virtual nsresult
GetIsTextRecognitionSupported(bool *aIsTextRecognitionSupported
) override; virtual nsresult InvalidateCachesOnRestart(void) override
; virtual nsresult EnsureContentProcess(void) override; virtual
nsresult GetReplacedLockTime(PRTime *aReplacedLockTime) override
; virtual nsresult GetDefaultUpdateChannel(nsACString& aDefaultUpdateChannel
) override; virtual nsresult GetDistributionID(nsACString&
aDistributionID) override; virtual nsresult GetWindowsDLLBlocklistStatus
(bool *aWindowsDLLBlocklistStatus) override; virtual nsresult
GetRestartedByOS(bool *aRestartedByOS) override; virtual nsresult
GetChromeColorSchemeIsDark(bool *aChromeColorSchemeIsDark) override
; virtual nsresult GetContentThemeDerivedColorSchemeIsDark(bool
*aContentThemeDerivedColorSchemeIsDark) override; virtual nsresult
GetPrefersReducedMotion(bool *aPrefersReducedMotion) override
; virtual nsresult GetDrawInTitlebar(bool *aDrawInTitlebar) override
; virtual nsresult GetDesktopEnvironment(nsACString& aDesktopEnvironment
) override; virtual nsresult GetIsWayland(bool *aIsWayland) override
; virtual nsresult GetProcessStartupShortcut(nsAString& aProcessStartupShortcut
) override; virtual nsresult GetLauncherProcessState(uint32_t
*aLauncherProcessState) override; virtual nsresult GetLastAppVersion
(nsACString& aLastAppVersion) override; virtual nsresult GetLastAppBuildID
(nsACString& aLastAppBuildID) override;
1055 NS_DECL_NSICRASHREPORTERvirtual nsresult GetCrashReporterEnabled(bool *aCrashReporterEnabled
) override; virtual nsresult SetEnabled(bool enabled) override
; virtual nsresult GetServerURL(nsIURL **aServerURL) override
; virtual nsresult SetServerURL(nsIURL *aServerURL) override;
virtual nsresult GetMinidumpPath(nsIFile **aMinidumpPath) override
; virtual nsresult SetMinidumpPath(nsIFile *aMinidumpPath) override
; virtual nsresult GetMinidumpForID(const nsAString& id, nsIFile
**_retval) override; virtual nsresult GetExtraFileForID(const
nsAString& id, nsIFile **_retval) override; virtual nsresult
AnnotateCrashReport(const nsACString& key, const nsACString
& data) override; virtual nsresult RemoveCrashReportAnnotation
(const nsACString& key) override; virtual nsresult IsAnnotationAllowedForPing
(const nsACString& value, bool *_retval) override; virtual
nsresult AppendAppNotesToCrashReport(const nsACString& data
) override; virtual nsresult RegisterAppMemory(uint64_t ptr, uint64_t
size) override; virtual nsresult WriteMinidumpForException(void
* aExceptionInfo) override; virtual nsresult AppendObjCExceptionInfoToAppNotes
(void * aException) override; virtual nsresult GetSubmitReports
(bool *aSubmitReports) override; virtual nsresult SetSubmitReports
(bool aSubmitReports) override; virtual nsresult UpdateCrashEventsDir
(void) override; virtual nsresult SaveMemoryReport(void) override
;
1056 NS_DECL_NSIFINISHDUMPINGCALLBACKvirtual nsresult Callback(nsISupports *data) override;
1057#ifdef XP_WIN
1058 NS_DECL_NSIWINAPPHELPER
1059#endif
1060};
1061
1062NS_INTERFACE_MAP_BEGIN(nsXULAppInfo)nsresult nsXULAppInfo::QueryInterface(const nsIID& aIID, void
** aInstancePtr) { do { if (!(aInstancePtr)) { NS_DebugBreak(
NS_DEBUG_ASSERTION, "QueryInterface requires a non-NULL destination!"
, "aInstancePtr", "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 1062); MOZ_PretendNoReturn(); } } while (0); nsISupports* foundInterface
;
1063 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIXULRuntime)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsISupports>)) foundInterface = static_cast
<nsISupports*>(static_cast<nsIXULRuntime*>(this))
; else
1064 NS_INTERFACE_MAP_ENTRY(nsIXULRuntime)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIXULRuntime>)) foundInterface =
static_cast<nsIXULRuntime*>(this); else
1065#ifdef XP_WIN
1066 NS_INTERFACE_MAP_ENTRY(nsIWinAppHelper)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIWinAppHelper>)) foundInterface
= static_cast<nsIWinAppHelper*>(this); else
1067#endif
1068 NS_INTERFACE_MAP_ENTRY(nsICrashReporter)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsICrashReporter>)) foundInterface
= static_cast<nsICrashReporter*>(this); else
1069 NS_INTERFACE_MAP_ENTRY(nsIFinishDumpingCallback)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIFinishDumpingCallback>)) foundInterface
= static_cast<nsIFinishDumpingCallback*>(this); else
1070 NS_INTERFACE_MAP_ENTRY(nsIPlatformInfo)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIPlatformInfo>)) foundInterface
= static_cast<nsIPlatformInfo*>(this); else
1071 NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIXULAppInfo,if ((gAppData || XRE_IsContentProcess()) && aIID.Equals
(mozilla::detail::kImplementedIID<std::remove_reference_t<
decltype(*this)>, nsIXULAppInfo>)) foundInterface = static_cast
<nsIXULAppInfo*>(this); else
1072 gAppData || XRE_IsContentProcess())if ((gAppData || XRE_IsContentProcess()) && aIID.Equals
(mozilla::detail::kImplementedIID<std::remove_reference_t<
decltype(*this)>, nsIXULAppInfo>)) foundInterface = static_cast
<nsIXULAppInfo*>(this); else
1073NS_INTERFACE_MAP_ENDfoundInterface = 0; nsresult status; if (!foundInterface) { do
{ static_assert( mozilla::detail::AssertionConditionType<
decltype(!aIID.Equals((nsISupports::COMTypeInfo<nsISupports
, void>::kIID)))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!aIID.Equals((nsISupports::COMTypeInfo
<nsISupports, void>::kIID))))), 0))) { do { } while (false
); MOZ_ReportAssertionFailure("!aIID.Equals((nsISupports::COMTypeInfo<nsISupports, void>::kIID))"
, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 1073); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!aIID.Equals((nsISupports::COMTypeInfo<nsISupports, void>::kIID))"
")"); do { *((volatile int*)__null) = 1073; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); status = NS_NOINTERFACE
; } else { (foundInterface)->AddRef(); status = NS_OK; } *
aInstancePtr = foundInterface; return status; }
1074
1075NS_IMETHODIMP_(MozExternalRefCountType)MozExternalRefCountType
1076nsXULAppInfo::AddRef() { return 1; }
1077
1078NS_IMETHODIMP_(MozExternalRefCountType)MozExternalRefCountType
1079nsXULAppInfo::Release() { return 1; }
1080
1081NS_IMETHODIMPnsresult
1082nsXULAppInfo::GetVendor(nsACString& aResult) {
1083 if (XRE_IsContentProcess()) {
1084 ContentChild* cc = ContentChild::GetSingleton();
1085 aResult = cc->GetAppInfo().vendor;
1086 return NS_OK;
1087 }
1088 aResult.Assign(gAppData->vendor);
1089
1090 return NS_OK;
1091}
1092
1093NS_IMETHODIMPnsresult
1094nsXULAppInfo::GetName(nsACString& aResult) {
1095 if (XRE_IsContentProcess()) {
1096 ContentChild* cc = ContentChild::GetSingleton();
1097 aResult = cc->GetAppInfo().name;
1098 return NS_OK;
1099 }
1100
1101#ifdef MOZ_WIDGET_ANDROID
1102 nsCString name = java::GeckoAppShell::GetAppName()->ToCString();
1103 aResult.Assign(std::move(name));
1104#else
1105 aResult.Assign(gAppData->name);
1106#endif
1107
1108 return NS_OK;
1109}
1110
1111NS_IMETHODIMPnsresult
1112nsXULAppInfo::GetID(nsACString& aResult) {
1113 if (XRE_IsContentProcess()) {
1114 ContentChild* cc = ContentChild::GetSingleton();
1115 aResult = cc->GetAppInfo().ID;
1116 return NS_OK;
1117 }
1118 aResult.Assign(gAppData->ID);
1119
1120 return NS_OK;
1121}
1122
1123NS_IMETHODIMPnsresult
1124nsXULAppInfo::GetVersion(nsACString& aResult) {
1125 if (XRE_IsContentProcess()) {
1126 ContentChild* cc = ContentChild::GetSingleton();
1127 aResult = cc->GetAppInfo().version;
1128 return NS_OK;
1129 }
1130 aResult.Assign(gAppData->version);
1131
1132 return NS_OK;
1133}
1134
1135NS_IMETHODIMPnsresult
1136nsXULAppInfo::GetPlatformVersion(nsACString& aResult) {
1137 aResult.Assign(gToolkitVersion);
1138
1139 return NS_OK;
1140}
1141
1142NS_IMETHODIMPnsresult
1143nsXULAppInfo::GetAppBuildID(nsACString& aResult) {
1144 if (XRE_IsContentProcess()) {
1145 ContentChild* cc = ContentChild::GetSingleton();
1146 aResult = cc->GetAppInfo().buildID;
1147 return NS_OK;
1148 }
1149 aResult.Assign(gAppData->buildID);
1150
1151 return NS_OK;
1152}
1153
1154NS_IMETHODIMPnsresult
1155nsXULAppInfo::GetPlatformBuildID(nsACString& aResult) {
1156 aResult.Assign(gToolkitBuildID);
1157
1158 return NS_OK;
1159}
1160
1161NS_IMETHODIMPnsresult
1162nsXULAppInfo::GetUAName(nsACString& aResult) {
1163 if (XRE_IsContentProcess()) {
1164 ContentChild* cc = ContentChild::GetSingleton();
1165 aResult = cc->GetAppInfo().UAName;
1166 return NS_OK;
1167 }
1168 aResult.Assign(gAppData->UAName);
1169
1170 return NS_OK;
1171}
1172
1173NS_IMETHODIMPnsresult
1174nsXULAppInfo::GetSourceURL(nsACString& aResult) {
1175 if (XRE_IsContentProcess()) {
1176 ContentChild* cc = ContentChild::GetSingleton();
1177 aResult = cc->GetAppInfo().sourceURL;
1178 return NS_OK;
1179 }
1180 aResult.Assign(gAppData->sourceURL);
1181
1182 return NS_OK;
1183}
1184
1185NS_IMETHODIMPnsresult
1186nsXULAppInfo::GetUpdateURL(nsACString& aResult) {
1187 if (XRE_IsContentProcess()) {
1188 ContentChild* cc = ContentChild::GetSingleton();
1189 aResult = cc->GetAppInfo().updateURL;
1190 return NS_OK;
1191 }
1192 aResult.Assign(gAppData->updateURL);
1193
1194 return NS_OK;
1195}
1196
1197NS_IMETHODIMPnsresult
1198nsXULAppInfo::GetLogConsoleErrors(bool* aResult) {
1199 *aResult = gLogConsoleErrors;
1200 return NS_OK;
1201}
1202
1203NS_IMETHODIMPnsresult
1204nsXULAppInfo::SetLogConsoleErrors(bool aValue) {
1205 gLogConsoleErrors = aValue;
1206 return NS_OK;
1207}
1208
1209NS_IMETHODIMPnsresult
1210nsXULAppInfo::GetInSafeMode(bool* aResult) {
1211 *aResult = gSafeMode;
1212 return NS_OK;
1213}
1214
1215NS_IMETHODIMPnsresult
1216nsXULAppInfo::GetOS(nsACString& aResult) {
1217 aResult.AssignLiteral(OS_TARGET"Linux");
1218 return NS_OK;
1219}
1220
1221NS_IMETHODIMPnsresult
1222nsXULAppInfo::GetXPCOMABI(nsACString& aResult) {
1223#ifdef TARGET_XPCOM_ABI"x86_64-gcc3"
1224 aResult.AssignLiteral(TARGET_XPCOM_ABI"x86_64-gcc3");
1225 return NS_OK;
1226#else
1227 return NS_ERROR_NOT_AVAILABLE;
1228#endif
1229}
1230
1231NS_IMETHODIMPnsresult
1232nsXULAppInfo::GetWidgetToolkit(nsACString& aResult) {
1233 aResult.AssignLiteral(MOZ_WIDGET_TOOLKIT"gtk");
1234 return NS_OK;
1235}
1236
1237// Ensure that the GeckoProcessType enum, defined in xpcom/build/nsXULAppAPI.h,
1238// is synchronized with the const unsigned longs defined in
1239// xpcom/system/nsIXULRuntime.idl.
1240#define GECKO_PROCESS_TYPE(enum_value, enum_name, string_name, proc_typename, \
1241 process_bin_type, procinfo_typename, \
1242 webidl_typename, allcaps_name) \
1243 static_assert(nsIXULRuntime::PROCESS_TYPE_##allcaps_name == \
1244 static_cast<int>(GeckoProcessType_##enum_name), \
1245 "GeckoProcessType in nsXULAppAPI.h not synchronized with " \
1246 "nsIXULRuntime.idl");
1247#include "mozilla/GeckoProcessTypes.h"
1248#undef GECKO_PROCESS_TYPE
1249
1250// .. and ensure that that is all of them:
1251static_assert(GeckoProcessType_Utility + 1 == GeckoProcessType_End,
1252 "Did not find the final GeckoProcessType");
1253
1254NS_IMETHODIMPnsresult
1255nsXULAppInfo::GetProcessType(uint32_t* aResult) {
1256 NS_ENSURE_ARG_POINTER(aResult)do { if ((__builtin_expect(!!(!(aResult)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aResult" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 1256); return NS_ERROR_INVALID_POINTER; } } while (false)
;
1257 *aResult = XRE_GetProcessType();
1258 return NS_OK;
1259}
1260
1261NS_IMETHODIMPnsresult
1262nsXULAppInfo::GetProcessID(uint32_t* aResult) {
1263#ifdef XP_WIN
1264 *aResult = GetCurrentProcessId();
1265#else
1266 *aResult = getpid();
1267#endif
1268 return NS_OK;
1269}
1270
1271NS_IMETHODIMPnsresult
1272nsXULAppInfo::GetUniqueProcessID(uint64_t* aResult) {
1273 if (XRE_IsContentProcess()) {
1274 ContentChild* cc = ContentChild::GetSingleton();
1275 *aResult = cc->GetID();
1276 } else {
1277 *aResult = 0;
1278 }
1279 return NS_OK;
1280}
1281
1282NS_IMETHODIMPnsresult
1283nsXULAppInfo::GetRemoteType(nsACString& aRemoteType) {
1284 if (XRE_IsContentProcess()) {
1285 aRemoteType = ContentChild::GetSingleton()->GetRemoteType();
1286 } else {
1287 aRemoteType = NOT_REMOTE_TYPEVoidCString();
1288 }
1289
1290 return NS_OK;
1291}
1292
1293static nsCString gLastAppVersion;
1294static nsCString gLastAppBuildID;
1295
1296NS_IMETHODIMPnsresult
1297nsXULAppInfo::GetLastAppVersion(nsACString& aResult) {
1298 if (XRE_IsContentProcess()) {
1299 return NS_ERROR_NOT_AVAILABLE;
1300 }
1301
1302 if (!gLastAppVersion.IsVoid() && gLastAppVersion.IsEmpty()) {
1303 NS_WARNING("Attempt to retrieve lastAppVersion before it has been set.")NS_DebugBreak(NS_DEBUG_WARNING, "Attempt to retrieve lastAppVersion before it has been set."
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 1303)
;
1304 return NS_ERROR_NOT_AVAILABLE;
1305 }
1306
1307 aResult.Assign(gLastAppVersion);
1308 return NS_OK;
1309}
1310
1311NS_IMETHODIMPnsresult
1312nsXULAppInfo::GetLastAppBuildID(nsACString& aResult) {
1313 if (XRE_IsContentProcess()) {
1314 return NS_ERROR_NOT_AVAILABLE;
1315 }
1316
1317 if (!gLastAppBuildID.IsVoid() && gLastAppBuildID.IsEmpty()) {
1318 NS_WARNING("Attempt to retrieve lastAppBuildID before it has been set.")NS_DebugBreak(NS_DEBUG_WARNING, "Attempt to retrieve lastAppBuildID before it has been set."
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 1318)
;
1319 return NS_ERROR_NOT_AVAILABLE;
1320 }
1321
1322 aResult.Assign(gLastAppBuildID);
1323 return NS_OK;
1324}
1325
1326NS_IMETHODIMPnsresult
1327nsXULAppInfo::GetFissionAutostart(bool* aResult) {
1328 *aResult = FissionAutostart();
1329 return NS_OK;
1330}
1331
1332NS_IMETHODIMPnsresult
1333nsXULAppInfo::GetWin32kExperimentStatus(ExperimentStatus* aResult) {
1334 if (!XRE_IsParentProcess()) {
1335 return NS_ERROR_NOT_AVAILABLE;
1336 }
1337
1338 EnsureWin32kInitialized();
1339 *aResult = gWin32kExperimentStatus;
1340 return NS_OK;
1341}
1342
1343NS_IMETHODIMPnsresult
1344nsXULAppInfo::GetWin32kLiveStatusTestingOnly(
1345 nsIXULRuntime::ContentWin32kLockdownState* aResult) {
1346 if (!XRE_IsParentProcess()) {
1347 return NS_ERROR_NOT_AVAILABLE;
1348 }
1349
1350 EnsureWin32kInitialized();
1351 *aResult = GetLiveWin32kLockdownState();
1352 return NS_OK;
1353}
1354
1355NS_IMETHODIMPnsresult
1356nsXULAppInfo::GetWin32kSessionStatus(
1357 nsIXULRuntime::ContentWin32kLockdownState* aResult) {
1358 if (!XRE_IsParentProcess()) {
1359 return NS_ERROR_NOT_AVAILABLE;
1360 }
1361
1362 EnsureWin32kInitialized();
1363 *aResult = gWin32kStatus;
1364 return NS_OK;
1365}
1366
1367NS_IMETHODIMPnsresult
1368nsXULAppInfo::GetFissionDecisionStatus(FissionDecisionStatus* aResult) {
1369 if (!XRE_IsParentProcess()) {
1370 return NS_ERROR_NOT_AVAILABLE;
1371 }
1372
1373 EnsureFissionAutostartInitialized();
1374
1375 MOZ_ASSERT(gFissionDecisionStatus != eFissionStatusUnknown)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(gFissionDecisionStatus != eFissionStatusUnknown)>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(gFissionDecisionStatus != eFissionStatusUnknown))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("gFissionDecisionStatus != eFissionStatusUnknown"
, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 1375); AnnotateMozCrashReason("MOZ_ASSERT" "(" "gFissionDecisionStatus != eFissionStatusUnknown"
")"); do { *((volatile int*)__null) = 1375; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1376 *aResult = gFissionDecisionStatus;
1377 return NS_OK;
1378}
1379
1380NS_IMETHODIMPnsresult
1381nsXULAppInfo::GetFissionDecisionStatusString(nsACString& aResult) {
1382 if (!XRE_IsParentProcess()) {
1383 return NS_ERROR_NOT_AVAILABLE;
1384 }
1385
1386 EnsureFissionAutostartInitialized();
1387 switch (gFissionDecisionStatus) {
1388 case eFissionExperimentControl:
1389 aResult = "experimentControl";
1390 break;
1391 case eFissionExperimentTreatment:
1392 aResult = "experimentTreatment";
1393 break;
1394 case eFissionDisabledByE10sEnv:
1395 aResult = "disabledByE10sEnv";
1396 break;
1397 case eFissionEnabledByEnv:
1398 aResult = "enabledByEnv";
1399 break;
1400 case eFissionDisabledByEnv:
1401 aResult = "disabledByEnv";
1402 break;
1403 case eFissionEnabledByDefault:
1404 aResult = "enabledByDefault";
1405 break;
1406 case eFissionDisabledByDefault:
1407 aResult = "disabledByDefault";
1408 break;
1409 case eFissionEnabledByUserPref:
1410 aResult = "enabledByUserPref";
1411 break;
1412 case eFissionDisabledByUserPref:
1413 aResult = "disabledByUserPref";
1414 break;
1415 case eFissionDisabledByE10sOther:
1416 aResult = "disabledByE10sOther";
1417 break;
1418 case eFissionEnabledByRollout:
1419 aResult = "enabledByRollout";
1420 break;
1421 default:
1422 MOZ_ASSERT_UNREACHABLE("Unexpected enum value")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(false)>::isValid, "invalid assertion condition");
if ((__builtin_expect(!!(!(!!(false))), 0))) { do { } while (
false); MOZ_ReportAssertionFailure("false" " (" "MOZ_ASSERT_UNREACHABLE: "
"Unexpected enum value" ")", "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 1422); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ") ("
"MOZ_ASSERT_UNREACHABLE: " "Unexpected enum value" ")"); do {
*((volatile int*)__null) = 1422; __attribute__((nomerge)) ::
abort(); } while (false); } } while (false)
;
1423 }
1424 return NS_OK;
1425}
1426
1427NS_IMETHODIMPnsresult
1428nsXULAppInfo::GetSessionHistoryInParent(bool* aResult) {
1429 *aResult = SessionHistoryInParent();
1430 return NS_OK;
1431}
1432
1433NS_IMETHODIMPnsresult
1434nsXULAppInfo::GetSessionStorePlatformCollection(bool* aResult) {
1435 *aResult = SessionStorePlatformCollection();
1436 return NS_OK;
1437}
1438
1439NS_IMETHODIMPnsresult
1440nsXULAppInfo::GetBrowserTabsRemoteAutostart(bool* aResult) {
1441 *aResult = BrowserTabsRemoteAutostart();
1442 return NS_OK;
1443}
1444
1445NS_IMETHODIMPnsresult
1446nsXULAppInfo::GetMaxWebProcessCount(uint32_t* aResult) {
1447 *aResult = mozilla::GetMaxWebProcessCount();
1448 return NS_OK;
1449}
1450
1451NS_IMETHODIMPnsresult
1452nsXULAppInfo::GetAccessibilityEnabled(bool* aResult) {
1453#ifdef ACCESSIBILITY1
1454 *aResult = GetAccService() != nullptr;
1455#else
1456 *aResult = false;
1457#endif
1458 return NS_OK;
1459}
1460
1461NS_IMETHODIMPnsresult
1462nsXULAppInfo::GetAccessibilityInstantiator(nsAString& aInstantiator) {
1463#if defined(ACCESSIBILITY1) && defined(XP_WIN)
1464 if (!GetAccService()) {
1465 aInstantiator.Truncate();
1466 return NS_OK;
1467 }
1468 nsAutoString ipClientInfo;
1469 a11y::Compatibility::GetHumanReadableConsumersStr(ipClientInfo);
1470 aInstantiator.Append(ipClientInfo);
1471 aInstantiator.AppendLiteral("|");
1472
1473 nsCOMPtr<nsIFile> oopClientExe;
1474 if (a11y::GetInstantiator(getter_AddRefs(oopClientExe))) {
1475 nsAutoString oopClientInfo;
1476 if (NS_SUCCEEDED(oopClientExe->GetPath(oopClientInfo))((bool)(__builtin_expect(!!(!NS_FAILED_impl(oopClientExe->
GetPath(oopClientInfo))), 1)))
) {
1477 aInstantiator.Append(oopClientInfo);
1478 }
1479 }
1480#else
1481 aInstantiator.Truncate();
1482#endif
1483 return NS_OK;
1484}
1485
1486NS_IMETHODIMPnsresult
1487nsXULAppInfo::GetIs64Bit(bool* aResult) {
1488#ifdef HAVE_64BIT_BUILD1
1489 *aResult = true;
1490#else
1491 *aResult = false;
1492#endif
1493 return NS_OK;
1494}
1495
1496NS_IMETHODIMPnsresult
1497nsXULAppInfo::GetIsTextRecognitionSupported(bool* aResult) {
1498 *aResult = widget::TextRecognition::IsSupported();
1499 return NS_OK;
1500}
1501
1502NS_IMETHODIMPnsresult
1503nsXULAppInfo::EnsureContentProcess() {
1504 if (!XRE_IsParentProcess()) return NS_ERROR_NOT_AVAILABLE;
1505
1506 RefPtr<ContentParent> unused =
1507 ContentParent::GetNewOrUsedBrowserProcess(DEFAULT_REMOTE_TYPE"web"_ns);
1508 return NS_OK;
1509}
1510
1511NS_IMETHODIMPnsresult
1512nsXULAppInfo::InvalidateCachesOnRestart() {
1513 nsCOMPtr<nsIFile> file;
1514 nsresult rv =
1515 NS_GetSpecialDirectory(NS_APP_PROFILE_DIR_STARTUP"ProfDS", getter_AddRefs(file));
1516 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return rv;
1517 if (!file) return NS_ERROR_NOT_AVAILABLE;
1518
1519 file->AppendNative(FILE_COMPATIBILITY_INFO"compatibility.ini"_ns);
1520
1521 nsINIParsernsINIParser_internal parser;
1522 rv = parser.Init(file);
1523 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
1524 // This fails if compatibility.ini is not there, so we'll
1525 // flush the caches on the next restart anyways.
1526 return NS_OK;
1527 }
1528
1529 nsAutoCString buf;
1530 rv = parser.GetString("Compatibility", "InvalidateCaches", buf);
1531
1532 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
1533 PRFileDesc* fd;
1534 rv = file->OpenNSPRFileDesc(PR_RDWR0x04 | PR_APPEND0x10, 0600, &fd);
1535 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
1536 NS_ERROR("could not create output stream")do { NS_DebugBreak(NS_DEBUG_ASSERTION, "could not create output stream"
, "Error", "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 1536); MOZ_PretendNoReturn(); } while (0)
;
1537 return NS_ERROR_NOT_AVAILABLE;
1538 }
1539 static const char kInvalidationHeader[] =
1540 NS_LINEBREAK"\012" "InvalidateCaches=1" NS_LINEBREAK"\012";
1541 PR_Write(fd, kInvalidationHeader, sizeof(kInvalidationHeader) - 1);
1542 PR_Close(fd);
1543 }
1544 return NS_OK;
1545}
1546
1547NS_IMETHODIMPnsresult
1548nsXULAppInfo::GetReplacedLockTime(PRTime* aReplacedLockTime) {
1549 if (!gProfileLock) return NS_ERROR_NOT_AVAILABLE;
1550 gProfileLock->GetReplacedLockTime(aReplacedLockTime);
1551 return NS_OK;
1552}
1553
1554NS_IMETHODIMPnsresult
1555nsXULAppInfo::GetDefaultUpdateChannel(nsACString& aResult) {
1556 aResult.AssignLiteral(MOZ_STRINGIFY(MOZ_UPDATE_CHANNEL)"default");
1557 return NS_OK;
1558}
1559
1560NS_IMETHODIMPnsresult
1561nsXULAppInfo::GetDistributionID(nsACString& aResult) {
1562 aResult.AssignLiteral(MOZ_DISTRIBUTION_ID"org.mozilla");
1563 return NS_OK;
1564}
1565
1566NS_IMETHODIMPnsresult
1567nsXULAppInfo::GetWindowsDLLBlocklistStatus(bool* aResult) {
1568#if defined(HAS_DLL_BLOCKLIST)
1569 *aResult = DllBlocklist_CheckStatus();
1570#else
1571 *aResult = false;
1572#endif
1573 return NS_OK;
1574}
1575
1576NS_IMETHODIMPnsresult
1577nsXULAppInfo::GetRestartedByOS(bool* aResult) {
1578 *aResult = gRestartedByOS;
1579 return NS_OK;
1580}
1581
1582NS_IMETHODIMPnsresult
1583nsXULAppInfo::GetChromeColorSchemeIsDark(bool* aResult) {
1584 PreferenceSheet::EnsureInitialized();
1585 *aResult = PreferenceSheet::ColorSchemeForChrome() == ColorScheme::Dark;
1586 return NS_OK;
1587}
1588
1589NS_IMETHODIMPnsresult
1590nsXULAppInfo::GetContentThemeDerivedColorSchemeIsDark(bool* aResult) {
1591 *aResult =
1592 PreferenceSheet::ThemeDerivedColorSchemeForContent() == ColorScheme::Dark;
1593 return NS_OK;
1594}
1595
1596NS_IMETHODIMPnsresult
1597nsXULAppInfo::GetPrefersReducedMotion(bool* aResult) {
1598 *aResult =
1599 LookAndFeel::GetInt(LookAndFeel::IntID::PrefersReducedMotion, 0) == 1;
1600 return NS_OK;
1601}
1602
1603NS_IMETHODIMPnsresult
1604nsXULAppInfo::GetDrawInTitlebar(bool* aResult) {
1605 *aResult = LookAndFeel::DrawInTitlebar();
1606 return NS_OK;
1607}
1608
1609NS_IMETHODIMPnsresult
1610nsXULAppInfo::GetDesktopEnvironment(nsACString& aDesktopEnvironment) {
1611#ifdef MOZ_WIDGET_GTK1
1612 aDesktopEnvironment.Assign(GetDesktopEnvironmentIdentifier());
1613#endif
1614 return NS_OK;
1615}
1616
1617NS_IMETHODIMPnsresult
1618nsXULAppInfo::GetIsWayland(bool* aResult) {
1619#ifdef MOZ_WIDGET_GTK1
1620 *aResult = GdkIsWaylandDisplay();
1621#else
1622 *aResult = false;
1623#endif
1624 return NS_OK;
1625}
1626
1627NS_IMETHODIMPnsresult
1628nsXULAppInfo::GetProcessStartupShortcut(nsAString& aShortcut) {
1629#if defined(XP_WIN)
1630 if (XRE_IsParentProcess()) {
1631 aShortcut.Assign(gProcessStartupShortcut);
1632 return NS_OK;
1633 }
1634#endif
1635 return NS_ERROR_NOT_AVAILABLE;
1636}
1637
1638#if defined(XP_WIN) && defined(MOZ_LAUNCHER_PROCESS)
1639// Forward declaration
1640void SetupLauncherProcessPref();
1641
1642static Maybe<LauncherRegistryInfo::EnabledState> gLauncherProcessState;
1643#endif // defined(XP_WIN) && defined(MOZ_LAUNCHER_PROCESS)
1644
1645NS_IMETHODIMPnsresult
1646nsXULAppInfo::GetLauncherProcessState(uint32_t* aResult) {
1647#if defined(XP_WIN) && defined(MOZ_LAUNCHER_PROCESS)
1648 SetupLauncherProcessPref();
1649
1650 if (!gLauncherProcessState) {
1651 return NS_ERROR_UNEXPECTED;
1652 }
1653
1654 *aResult = static_cast<uint32_t>(gLauncherProcessState.value());
1655 return NS_OK;
1656#else
1657 return NS_ERROR_NOT_AVAILABLE;
1658#endif
1659}
1660
1661#ifdef XP_WIN
1662NS_IMETHODIMPnsresult
1663nsXULAppInfo::GetUserCanElevate(bool* aUserCanElevate) {
1664 HANDLE rawToken;
1665 if (!::OpenProcessToken(::GetCurrentProcess(), TOKEN_QUERY, &rawToken)) {
1666 *aUserCanElevate = false;
1667 return NS_OK;
1668 }
1669
1670 nsAutoHandle token(rawToken);
1671 LauncherResult<TOKEN_ELEVATION_TYPE> elevationType = GetElevationType(token);
1672 if (elevationType.isErr()) {
1673 *aUserCanElevate = false;
1674 return NS_OK;
1675 }
1676
1677 // The possible values returned for elevationType and their meanings are:
1678 // TokenElevationTypeDefault: The token does not have a linked token
1679 // (e.g. UAC disabled or a standard user, so they can't be elevated)
1680 // TokenElevationTypeFull: The token is linked to an elevated token
1681 // (e.g. UAC is enabled and the user is already elevated so they can't
1682 // be elevated again)
1683 // TokenElevationTypeLimited: The token is linked to a limited token
1684 // (e.g. UAC is enabled and the user is not elevated, so they can be
1685 // elevated)
1686 *aUserCanElevate = (elevationType.inspect() == TokenElevationTypeLimited);
1687 return NS_OK;
1688}
1689#endif
1690
1691NS_IMETHODIMPnsresult
1692nsXULAppInfo::GetCrashReporterEnabled(bool* aEnabled) {
1693 *aEnabled = CrashReporter::GetEnabled();
1694 return NS_OK;
1695}
1696
1697NS_IMETHODIMPnsresult
1698nsXULAppInfo::SetEnabled(bool aEnabled) {
1699 if (aEnabled) {
1700 if (CrashReporter::GetEnabled()) {
1701 // no point in erroring for double-enabling
1702 return NS_OK;
1703 }
1704
1705 nsCOMPtr<nsIFile> greBinDir;
1706 NS_GetSpecialDirectory(NS_GRE_BIN_DIR"GreBinD", getter_AddRefs(greBinDir));
1707 if (!greBinDir) {
1708 return NS_ERROR_FAILURE;
1709 }
1710
1711 nsCOMPtr<nsIFile> xreBinDirectory = greBinDir;
1712 if (!xreBinDirectory) {
1713 return NS_ERROR_FAILURE;
1714 }
1715
1716 return CrashReporter::SetExceptionHandler(xreBinDirectory, true);
1717 }
1718
1719 if (!CrashReporter::GetEnabled()) {
1720 // no point in erroring for double-disabling
1721 return NS_OK;
1722 }
1723
1724 return CrashReporter::UnsetExceptionHandler();
1725}
1726
1727NS_IMETHODIMPnsresult
1728nsXULAppInfo::GetServerURL(nsIURL** aServerURL) {
1729 NS_ENSURE_ARG_POINTER(aServerURL)do { if ((__builtin_expect(!!(!(aServerURL)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aServerURL" ") failed",
nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 1729); return NS_ERROR_INVALID_POINTER; } } while (false)
;
1730 if (!CrashReporter::GetEnabled()) return NS_ERROR_NOT_INITIALIZED;
1731
1732 nsAutoCString data;
1733 if (!CrashReporter::GetServerURL(data)) {
1734 return NS_ERROR_FAILURE;
1735 }
1736 nsCOMPtr<nsIURI> uri;
1737 NS_NewURI(getter_AddRefs(uri), data);
1738 if (!uri) return NS_ERROR_FAILURE;
1739
1740 nsCOMPtr<nsIURL> url;
1741 url = do_QueryInterface(uri);
1742 NS_ADDREF(*aServerURL = url)(*aServerURL = url)->AddRef();
1743
1744 return NS_OK;
1745}
1746
1747NS_IMETHODIMPnsresult
1748nsXULAppInfo::SetServerURL(nsIURL* aServerURL) {
1749 // Only allow https or http URLs
1750 if (!aServerURL->SchemeIs("http") && !aServerURL->SchemeIs("https")) {
1751 return NS_ERROR_INVALID_ARG;
1752 }
1753
1754 nsAutoCString spec;
1755 nsresult rv = aServerURL->GetSpec(spec);
1756 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 1756); return rv; } } while (false)
;
1757
1758 return CrashReporter::SetServerURL(spec);
1759}
1760
1761NS_IMETHODIMPnsresult
1762nsXULAppInfo::GetMinidumpPath(nsIFile** aMinidumpPath) {
1763 if (!CrashReporter::GetEnabled()) return NS_ERROR_NOT_INITIALIZED;
1764
1765 nsAutoString path;
1766 if (!CrashReporter::GetMinidumpPath(path)) return NS_ERROR_FAILURE;
1767
1768 nsresult rv = NS_NewLocalFile(path, false, aMinidumpPath);
1769 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 1769); return rv; } } while (false)
;
1770 return NS_OK;
1771}
1772
1773NS_IMETHODIMPnsresult
1774nsXULAppInfo::SetMinidumpPath(nsIFile* aMinidumpPath) {
1775 nsAutoString path;
1776 nsresult rv = aMinidumpPath->GetPath(path);
1777 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 1777); return rv; } } while (false)
;
1778 return CrashReporter::SetMinidumpPath(path);
1779}
1780
1781NS_IMETHODIMPnsresult
1782nsXULAppInfo::GetMinidumpForID(const nsAString& aId, nsIFile** aMinidump) {
1783 if (!CrashReporter::GetMinidumpForID(aId, aMinidump)) {
1784 return NS_ERROR_FILE_NOT_FOUND;
1785 }
1786
1787 return NS_OK;
1788}
1789
1790NS_IMETHODIMPnsresult
1791nsXULAppInfo::GetExtraFileForID(const nsAString& aId, nsIFile** aExtraFile) {
1792 if (!CrashReporter::GetExtraFileForID(aId, aExtraFile)) {
1793 return NS_ERROR_FILE_NOT_FOUND;
1794 }
1795
1796 return NS_OK;
1797}
1798
1799NS_IMETHODIMPnsresult
1800nsXULAppInfo::AnnotateCrashReport(const nsACString& key,
1801 const nsACString& data) {
1802 CrashReporter::Annotation annotation;
1803
1804 if (!AnnotationFromString(annotation, PromiseFlatCStringTPromiseFlatString<char>(key).get())) {
1805 return NS_ERROR_INVALID_ARG;
1806 }
1807
1808 CrashReporter::RecordAnnotationNSCString(annotation, data);
1809 return NS_OK;
1810}
1811
1812NS_IMETHODIMPnsresult
1813nsXULAppInfo::RemoveCrashReportAnnotation(const nsACString& key) {
1814 CrashReporter::Annotation annotation;
1815
1816 if (!AnnotationFromString(annotation, PromiseFlatCStringTPromiseFlatString<char>(key).get())) {
1817 return NS_ERROR_INVALID_ARG;
1818 }
1819
1820 CrashReporter::UnrecordAnnotation(annotation);
1821 return NS_OK;
1822}
1823
1824NS_IMETHODIMPnsresult
1825nsXULAppInfo::IsAnnotationAllowedForPing(const nsACString& aValue,
1826 bool* aIsAllowed) {
1827 CrashReporter::Annotation annotation;
1828
1829 if (!AnnotationFromString(annotation, PromiseFlatCStringTPromiseFlatString<char>(aValue).get())) {
1830 return NS_ERROR_INVALID_ARG;
1831 }
1832
1833 *aIsAllowed = CrashReporter::IsAnnotationAllowedForPing(annotation);
1834
1835 return NS_OK;
1836}
1837
1838NS_IMETHODIMPnsresult
1839nsXULAppInfo::AppendAppNotesToCrashReport(const nsACString& data) {
1840 return CrashReporter::AppendAppNotesToCrashReport(data);
1841}
1842
1843NS_IMETHODIMPnsresult
1844nsXULAppInfo::RegisterAppMemory(uint64_t pointer, uint64_t len) {
1845 return CrashReporter::RegisterAppMemory((void*)pointer, len);
1846}
1847
1848NS_IMETHODIMPnsresult
1849nsXULAppInfo::WriteMinidumpForException(void* aExceptionInfo) {
1850#ifdef XP_WIN
1851 return CrashReporter::WriteMinidumpForException(
1852 static_cast<EXCEPTION_POINTERS*>(aExceptionInfo));
1853#else
1854 return NS_ERROR_NOT_IMPLEMENTED;
1855#endif
1856}
1857
1858NS_IMETHODIMPnsresult
1859nsXULAppInfo::AppendObjCExceptionInfoToAppNotes(void* aException) {
1860#ifdef XP_MACOSX
1861 return CrashReporter::AppendObjCExceptionInfoToAppNotes(aException);
1862#else
1863 return NS_ERROR_NOT_IMPLEMENTED;
1864#endif
1865}
1866
1867NS_IMETHODIMPnsresult
1868nsXULAppInfo::GetSubmitReports(bool* aEnabled) {
1869 return CrashReporter::GetSubmitReports(aEnabled);
1870}
1871
1872NS_IMETHODIMPnsresult
1873nsXULAppInfo::SetSubmitReports(bool aEnabled) {
1874 return CrashReporter::SetSubmitReports(aEnabled);
1875}
1876
1877NS_IMETHODIMPnsresult
1878nsXULAppInfo::UpdateCrashEventsDir() {
1879 CrashReporter::UpdateCrashEventsDir();
1880 return NS_OK;
1881}
1882
1883NS_IMETHODIMPnsresult
1884nsXULAppInfo::SaveMemoryReport() {
1885 if (!CrashReporter::GetEnabled()) {
1886 return NS_ERROR_NOT_INITIALIZED;
1887 }
1888 nsCOMPtr<nsIFile> file;
1889 nsresult rv = CrashReporter::GetDefaultMemoryReportFile(getter_AddRefs(file));
1890 if (NS_WARN_IF(NS_FAILED(rv))NS_warn_if_impl(((bool)(__builtin_expect(!!(NS_FAILED_impl(rv
)), 0))), "NS_FAILED(rv)", "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 1890)
) {
1891 return rv;
1892 }
1893
1894 nsString path;
1895 file->GetPath(path);
1896
1897 nsCOMPtr<nsIMemoryInfoDumper> dumper =
1898 do_GetService("@mozilla.org/memory-info-dumper;1");
1899 if (NS_WARN_IF(!dumper)NS_warn_if_impl(!dumper, "!dumper", "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 1899)
) {
1900 return NS_ERROR_UNEXPECTED;
1901 }
1902
1903 rv = dumper->DumpMemoryReportsToNamedFile(
1904 path, this, file, true /* anonymize */, false /* minimizeMemoryUsage */);
1905 if (NS_WARN_IF(NS_FAILED(rv))NS_warn_if_impl(((bool)(__builtin_expect(!!(NS_FAILED_impl(rv
)), 0))), "NS_FAILED(rv)", "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 1905)
) {
1906 return rv;
1907 }
1908 return NS_OK;
1909}
1910
1911// This method is from nsIFInishDumpingCallback.
1912NS_IMETHODIMPnsresult
1913nsXULAppInfo::Callback(nsISupports* aData) {
1914 nsCOMPtr<nsIFile> file = do_QueryInterface(aData);
1915 MOZ_ASSERT(file)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(file)>::isValid, "invalid assertion condition"); if
((__builtin_expect(!!(!(!!(file))), 0))) { do { } while (false
); MOZ_ReportAssertionFailure("file", "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 1915); AnnotateMozCrashReason("MOZ_ASSERT" "(" "file" ")");
do { *((volatile int*)__null) = 1915; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1916
1917 CrashReporter::SetMemoryReportFile(file);
1918 return NS_OK;
1919}
1920
1921static const nsXULAppInfo kAppInfo;
1922namespace mozilla {
1923nsresult AppInfoConstructor(REFNSIIDconst nsIID& aIID, void** aResult) {
1924 return const_cast<nsXULAppInfo*>(&kAppInfo)->QueryInterface(aIID, aResult);
1925}
1926} // namespace mozilla
1927
1928bool gLogConsoleErrors = false;
1929
1930#define NS_ENSURE_TRUE_LOG(x, ret)do { if ((__builtin_expect(!!(!(x)), 0))) { NS_DebugBreak(NS_DEBUG_WARNING
, "NS_ENSURE_TRUE(" "x" ") failed", nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 1930); gLogConsoleErrors = true; return ret; } } while (0)
\
1931 PR_BEGIN_MACROdo { \
1932 if (MOZ_UNLIKELY(!(x))(__builtin_expect(!!(!(x)), 0))) { \
1933 NS_WARNING("NS_ENSURE_TRUE(" #x ") failed")NS_DebugBreak(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" #x ") failed"
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 1933)
; \
1934 gLogConsoleErrors = true; \
1935 return ret; \
1936 } \
1937 PR_END_MACRO} while (0)
1938
1939#define NS_ENSURE_SUCCESS_LOG(res, ret)do { if ((__builtin_expect(!!(!(((bool)(__builtin_expect(!!(!
NS_FAILED_impl(res)), 1))))), 0))) { NS_DebugBreak(NS_DEBUG_WARNING
, "NS_ENSURE_TRUE(" "NS_SUCCEEDED(res)" ") failed", nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 1939); gLogConsoleErrors = true; return ret; } } while (0)
\
1940 NS_ENSURE_TRUE_LOG(NS_SUCCEEDED(res), ret)do { if ((__builtin_expect(!!(!(((bool)(__builtin_expect(!!(!
NS_FAILED_impl(res)), 1))))), 0))) { NS_DebugBreak(NS_DEBUG_WARNING
, "NS_ENSURE_TRUE(" "NS_SUCCEEDED(res)" ") failed", nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 1940); gLogConsoleErrors = true; return ret; } } while (0)
1941
1942/**
1943 * Because we're starting/stopping XPCOM several times in different scenarios,
1944 * this class is a stack-based critter that makes sure that XPCOM is shut down
1945 * during early returns.
1946 */
1947
1948class ScopedXPCOMStartup {
1949 public:
1950 ScopedXPCOMStartup() : mServiceManager(nullptr) {}
1951 ~ScopedXPCOMStartup();
1952
1953 nsresult Initialize(bool aInitJSContext = true);
1954 nsresult SetWindowCreator(nsINativeAppSupport* native);
1955
1956 private:
1957 nsIServiceManager* mServiceManager;
1958 static nsINativeAppSupport* gNativeAppSupport;
1959
1960 friend already_AddRefed<nsINativeAppSupport> NS_GetNativeAppSupport();
1961};
1962
1963ScopedXPCOMStartup::~ScopedXPCOMStartup() {
1964 NS_IF_RELEASE(gNativeAppSupport)do { if (gNativeAppSupport) { (gNativeAppSupport)->Release
(); (gNativeAppSupport) = 0; } } while (0)
;
1965
1966 if (mServiceManager) {
1967#ifdef XP_MACOSX
1968 // On OS X, we need a pool to catch cocoa objects that are autoreleased
1969 // during teardown.
1970 mozilla::MacAutoreleasePool pool;
1971#endif
1972
1973 nsCOMPtr<nsIAppStartup> appStartup(components::AppStartup::Service());
1974 if (appStartup) appStartup->DestroyHiddenWindow();
1975
1976 gDirServiceProvider->DoShutdown();
1977 PROFILER_MARKER_UNTYPED("Shutdown early", OTHER)do { ; do { if (profiler_is_collecting_markers()) { ::profiler_add_marker_impl
("Shutdown early", ::geckoprofiler::category::OTHER); } } while
(false); } while (false)
;
1978
1979 WriteConsoleLog();
1980
1981 NS_ShutdownXPCOM(mServiceManager);
1982 mServiceManager = nullptr;
1983 }
1984}
1985
1986nsresult ScopedXPCOMStartup::Initialize(bool aInitJSContext) {
1987 NS_ASSERTION(gDirServiceProvider, "Should not get here!")do { if (!(gDirServiceProvider)) { NS_DebugBreak(NS_DEBUG_ASSERTION
, "Should not get here!", "gDirServiceProvider", "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 1987); MOZ_PretendNoReturn(); } } while (0)
;
1988
1989 nsresult rv;
1990
1991 rv = NS_InitXPCOM(&mServiceManager, gDirServiceProvider->GetAppDir(),
1992 gDirServiceProvider, aInitJSContext);
1993 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
1994 NS_ERROR("Couldn't start xpcom!")do { NS_DebugBreak(NS_DEBUG_ASSERTION, "Couldn't start xpcom!"
, "Error", "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 1994); MOZ_PretendNoReturn(); } while (0)
;
1995 mServiceManager = nullptr;
1996 } else {
1997#ifdef DEBUG1
1998 nsCOMPtr<nsIComponentRegistrar> reg = do_QueryInterface(mServiceManager);
1999 NS_ASSERTION(reg, "Service Manager doesn't QI to Registrar.")do { if (!(reg)) { NS_DebugBreak(NS_DEBUG_ASSERTION, "Service Manager doesn't QI to Registrar."
, "reg", "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 1999); MOZ_PretendNoReturn(); } } while (0)
;
2000#endif
2001 }
2002
2003 return rv;
2004}
2005
2006/**
2007 * This is a little factory class that serves as a singleton-service-factory
2008 * for the nativeappsupport object.
2009 */
2010class nsSingletonFactory final : public nsIFactory {
2011 public:
2012 NS_DECL_ISUPPORTSpublic: virtual nsresult QueryInterface(const nsIID& aIID
, void** aInstancePtr) override; virtual MozExternalRefCountType
AddRef(void) override; virtual MozExternalRefCountType Release
(void) override; using HasThreadSafeRefCnt = std::false_type;
protected: nsAutoRefCnt mRefCnt; nsAutoOwningThread _mOwningThread
; public:
2013 NS_DECL_NSIFACTORYvirtual nsresult CreateInstance(const nsIID & iid, void *
* result) override;
2014
2015 explicit nsSingletonFactory(nsISupports* aSingleton);
2016
2017 private:
2018 ~nsSingletonFactory() = default;
2019 nsCOMPtr<nsISupports> mSingleton;
2020};
2021
2022nsSingletonFactory::nsSingletonFactory(nsISupports* aSingleton)
2023 : mSingleton(aSingleton) {
2024 NS_ASSERTION(mSingleton, "Singleton was null!")do { if (!(mSingleton)) { NS_DebugBreak(NS_DEBUG_ASSERTION, "Singleton was null!"
, "mSingleton", "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 2024); MOZ_PretendNoReturn(); } } while (0)
;
2025}
2026
2027NS_IMPL_ISUPPORTS(nsSingletonFactory, nsIFactory)MozExternalRefCountType nsSingletonFactory::AddRef(void) { static_assert
(!std::is_destructible_v<nsSingletonFactory>, "Reference-counted class "
"nsSingletonFactory" " should not have a public destructor. "
"Make this class's destructor non-public"); do { static_assert
( mozilla::detail::AssertionConditionType<decltype(int32_t
(mRefCnt) >= 0)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(int32_t(mRefCnt) >= 0))),
0))) { do { } while (false); MOZ_ReportAssertionFailure("int32_t(mRefCnt) >= 0"
" (" "illegal refcnt" ")", "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 2027); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) >= 0"
") (" "illegal refcnt" ")"); do { *((volatile int*)__null) =
2027; __attribute__((nomerge)) ::abort(); } while (false); }
} while (false); do { static_assert( mozilla::detail::AssertionConditionType
<decltype("nsSingletonFactory" != nullptr)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!("nsSingletonFactory" != nullptr
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"\"nsSingletonFactory\" != nullptr" " (" "Must specify a name"
")", "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 2027); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"nsSingletonFactory\" != nullptr"
") (" "Must specify a name" ")"); do { *((volatile int*)__null
) = 2027; __attribute__((nomerge)) ::abort(); } while (false)
; } } while (false); if (!mRefCnt.isThreadSafe) _mOwningThread
.AssertOwnership("nsSingletonFactory" " not thread-safe"); nsrefcnt
count = ++mRefCnt; NS_LogAddRef((this), (count), ("nsSingletonFactory"
), (uint32_t)(sizeof(*this))); return count; } MozExternalRefCountType
nsSingletonFactory::Release(void) { do { static_assert( mozilla
::detail::AssertionConditionType<decltype(int32_t(mRefCnt)
> 0)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(int32_t(mRefCnt) > 0))), 0))) { do { } while (false
); MOZ_ReportAssertionFailure("int32_t(mRefCnt) > 0" " (" "dup release"
")", "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 2027); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) > 0"
") (" "dup release" ")"); do { *((volatile int*)__null) = 2027
; __attribute__((nomerge)) ::abort(); } while (false); } } while
(false); do { static_assert( mozilla::detail::AssertionConditionType
<decltype("nsSingletonFactory" != nullptr)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!("nsSingletonFactory" != nullptr
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"\"nsSingletonFactory\" != nullptr" " (" "Must specify a name"
")", "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 2027); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"nsSingletonFactory\" != nullptr"
") (" "Must specify a name" ")"); do { *((volatile int*)__null
) = 2027; __attribute__((nomerge)) ::abort(); } while (false)
; } } while (false); if (!mRefCnt.isThreadSafe) _mOwningThread
.AssertOwnership("nsSingletonFactory" " not thread-safe"); const
char* const nametmp = "nsSingletonFactory"; nsrefcnt count =
--mRefCnt; NS_LogRelease((this), (count), (nametmp)); if (count
== 0) { mRefCnt = 1; delete (this); return 0; } return count
; } nsresult nsSingletonFactory::QueryInterface(const nsIID&
aIID, void** aInstancePtr) { do { if (!(aInstancePtr)) { NS_DebugBreak
(NS_DEBUG_ASSERTION, "QueryInterface requires a non-NULL destination!"
, "aInstancePtr", "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 2027); MOZ_PretendNoReturn(); } } while (0); nsresult rv = NS_ERROR_FAILURE
; static_assert(1 > 0, "Need more arguments to NS_INTERFACE_TABLE"
); static const QITableEntry table[] = { {&mozilla::detail
::kImplementedIID<nsSingletonFactory, nsIFactory>, int32_t
( reinterpret_cast<char*>(static_cast<nsIFactory*>
((nsSingletonFactory*)0x1000)) - reinterpret_cast<char*>
((nsSingletonFactory*)0x1000))}, {&mozilla::detail::kImplementedIID
<nsSingletonFactory, nsISupports>, int32_t(reinterpret_cast
<char*>(static_cast<nsISupports*>( static_cast<
nsIFactory*>((nsSingletonFactory*)0x1000))) - reinterpret_cast
<char*>((nsSingletonFactory*)0x1000))}, { nullptr, 0 } }
; static_assert((sizeof(table) / sizeof(table[0])) > 1, "need at least 1 interface"
); rv = NS_TableDrivenQI(static_cast<void*>(this), aIID
, aInstancePtr, table); return rv; }
2028
2029NS_IMETHODIMPnsresult
2030nsSingletonFactory::CreateInstance(const nsIID& aIID, void** aResult) {
2031 return mSingleton->QueryInterface(aIID, aResult);
2032}
2033
2034/**
2035 * Set our windowcreator on the WindowWatcher service.
2036 */
2037nsresult ScopedXPCOMStartup::SetWindowCreator(nsINativeAppSupport* native) {
2038 nsresult rv;
2039
2040 NS_IF_ADDREF(gNativeAppSupport = native)ns_if_addref(gNativeAppSupport = native);
2041
2042 nsCOMPtr<nsIWindowCreator> creator(components::AppStartup::Service());
2043 if (!creator) return NS_ERROR_UNEXPECTED;
2044
2045 nsCOMPtr<nsIWindowWatcher> wwatch(
2046 do_GetService(NS_WINDOWWATCHER_CONTRACTID"@mozilla.org/embedcomp/window-watcher;1", &rv));
2047 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 2047); return rv; } } while (false)
;
2048
2049 return wwatch->SetWindowCreator(creator);
2050}
2051
2052/* static */ already_AddRefed<nsINativeAppSupport> NS_GetNativeAppSupport() {
2053 if (!ScopedXPCOMStartup::gNativeAppSupport) {
2054 return nullptr;
2055 }
2056
2057 return do_AddRef(ScopedXPCOMStartup::gNativeAppSupport);
2058}
2059
2060nsINativeAppSupport* ScopedXPCOMStartup::gNativeAppSupport;
2061
2062static void DumpArbitraryHelp() {
2063 nsresult rv;
2064
2065 ScopedLogging log;
2066
2067 {
2068 ScopedXPCOMStartup xpcom;
2069 xpcom.Initialize();
2070
2071 nsCOMPtr<nsICommandLineRunner> cmdline(new nsCommandLine());
2072
2073 nsCString text;
2074 rv = cmdline->GetHelpText(text);
2075 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) printf("%s", text.get());
2076 }
2077}
2078
2079// English text needs to go into a dtd file.
2080// But when this is called we have no components etc. These strings must either
2081// be here, or in a native resource file.
2082static void DumpHelp() {
2083 printf(
2084 "Usage: %s [ options ... ] [URL]\n"
2085 " where options include:\n\n",
2086 gArgv[0]);
2087
2088#ifdef MOZ_X111
2089 printf(
2090 "X11 options\n"
2091 " --display=DISPLAY X display to use\n"
2092 " --sync Make X calls synchronous\n");
2093#endif
2094#ifdef XP_UNIX1
2095 printf(
2096 " --g-fatal-warnings Make all warnings fatal\n"
2097 "\n%s options\n",
2098 (const char*)gAppData->name);
2099#endif
2100
2101 printf(
2102 " -h or --help Print this message.\n"
2103 " -v or --version Print %s version.\n"
2104 " --full-version Print %s version, build and platform build ids.\n"
2105 " -P <profile> Start with <profile>.\n"
2106 " --profile <path> Start with profile at <path>.\n"
2107 " --migration Start with migration wizard.\n"
2108 " --ProfileManager Start with ProfileManager.\n"
2109#ifdef MOZ_HAS_REMOTE1
2110 " --no-remote Do not accept or send remote commands; implies\n"
2111 " --new-instance.\n"
2112 " --new-instance Open new instance, not a new window in running "
2113 "instance.\n"
2114#endif
2115 " --safe-mode Disables extensions and themes for this session.\n"
2116#ifdef MOZ_BLOCK_PROFILE_DOWNGRADE1
2117 " --allow-downgrade Allows downgrading a profile.\n"
2118#endif
2119 " --MOZ_LOG=<modules> Treated as MOZ_LOG=<modules> environment "
2120 "variable,\n"
2121 " overrides it.\n"
2122 " --MOZ_LOG_FILE=<file> Treated as MOZ_LOG_FILE=<file> environment "
2123 "variable,\n"
2124 " overrides it. If MOZ_LOG_FILE is not specified as "
2125 "an\n"
2126 " argument or as an environment variable, logging "
2127 "will be\n"
2128 " written to stdout.\n",
2129 (const char*)gAppData->name, (const char*)gAppData->name);
2130
2131#if defined(XP_WIN)
2132 printf(" --console Start %s with a debugging console.\n",
2133 (const char*)gAppData->name);
2134#endif
2135
2136#if defined(XP_WIN) || defined(MOZ_WIDGET_GTK1) || defined(XP_MACOSX)
2137 printf(" --headless Run without a GUI.\n");
2138#endif
2139
2140#if defined(MOZ_ENABLE_DBUS1)
2141 printf(
2142 " --dbus-service <launcher> Run as DBus service for "
2143 "org.freedesktop.Application and\n"
2144 " set a launcher (usually /usr/bin/appname "
2145 "script) for it.");
2146#endif
2147
2148 // this works, but only after the components have registered. so if you drop
2149 // in a new command line handler, --help won't not until the second run. out
2150 // of the bug, because we ship a component.reg file, it works correctly.
2151 DumpArbitraryHelp();
2152}
2153
2154static inline void DumpVersion() {
2155 if (gAppData->vendor && *gAppData->vendor) {
2156 printf("%s ", (const char*)gAppData->vendor);
2157 }
2158 printf("%s ", (const char*)gAppData->name);
2159
2160 // Use the displayed version
2161 // For example, for beta, we would display 42.0b2 instead of 42.0
2162 printf("%s", MOZ_STRINGIFY(MOZ_APP_VERSION_DISPLAY)"128.0a1");
2163
2164 if (gAppData->copyright && *gAppData->copyright) {
2165 printf(", %s", (const char*)gAppData->copyright);
2166 }
2167 printf("\n");
2168}
2169
2170static inline void DumpFullVersion() {
2171 if (gAppData->vendor && *gAppData->vendor) {
2172 printf("%s ", (const char*)gAppData->vendor);
2173 }
2174 printf("%s ", (const char*)gAppData->name);
2175
2176 // Use the displayed version
2177 // For example, for beta, we would display 42.0b2 instead of 42.0
2178 printf("%s ", MOZ_STRINGIFY(MOZ_APP_VERSION_DISPLAY)"128.0a1");
2179
2180 printf("%s ", (const char*)gAppData->buildID);
2181 printf("%s ", (const char*)PlatformBuildID());
2182 if (gAppData->copyright && *gAppData->copyright) {
2183 printf(", %s", (const char*)gAppData->copyright);
2184 }
2185 printf("\n");
2186}
2187
2188void XRE_InitOmnijar(nsIFile* greOmni, nsIFile* appOmni) {
2189 mozilla::Omnijar::Init(greOmni, appOmni);
2190}
2191
2192nsresult XRE_GetBinaryPath(nsIFile** aResult) {
2193 return mozilla::BinaryPath::GetFile(aResult);
2194}
2195
2196#ifdef XP_WIN
2197# include "nsWindowsRestart.cpp"
2198# include <shellapi.h>
2199
2200typedef BOOL(WINAPI* SetProcessDEPPolicyFunc)(DWORD dwFlags);
2201
2202static void RegisterApplicationRestartChanged(const char* aPref, void* aData) {
2203 DWORD cchCmdLine = 0;
2204 HRESULT rc = ::GetApplicationRestartSettings(::GetCurrentProcess(), nullptr,
2205 &cchCmdLine, nullptr);
2206 bool wasRegistered = false;
2207 if (rc == S_OK) {
2208 wasRegistered = true;
2209 }
2210
2211 if (Preferences::GetBool(PREF_WIN_REGISTER_APPLICATION_RESTART, false) &&
2212 !wasRegistered) {
2213 // Make the command line to use when restarting.
2214 // Excludes argv[0] because RegisterApplicationRestart adds the
2215 // executable name, replace that temporarily with -os-restarted
2216 char* exeName = gRestartArgv[0];
2217 gRestartArgv[0] = const_cast<char*>("-os-restarted");
2218 wchar_t** restartArgvConverted =
2219 AllocConvertUTF8toUTF16Strings(gRestartArgc, gRestartArgv);
2220 gRestartArgv[0] = exeName;
2221
2222 mozilla::UniquePtr<wchar_t[]> restartCommandLine;
2223 if (restartArgvConverted) {
2224 restartCommandLine =
2225 mozilla::MakeCommandLine(gRestartArgc, restartArgvConverted);
2226 FreeAllocStrings(gRestartArgc, restartArgvConverted);
2227 }
2228
2229 if (restartCommandLine) {
2230 // Flags RESTART_NO_PATCH and RESTART_NO_REBOOT are not set, so we
2231 // should be restarted if terminated by an update or restart.
2232 ::RegisterApplicationRestart(restartCommandLine.get(),
2233 RESTART_NO_CRASH | RESTART_NO_HANG);
2234 }
2235 } else if (wasRegistered) {
2236 ::UnregisterApplicationRestart();
2237 }
2238}
2239
2240static void OnAlteredPrefetchPrefChanged(const char* aPref, void* aData) {
2241 int32_t prefVal = Preferences::GetInt(PREF_WIN_ALTERED_DLL_PREFETCH, 0);
2242
2243 mozilla::DllPrefetchExperimentRegistryInfo prefetchRegInfo;
2244 mozilla::DebugOnly<mozilla::Result<Ok, nsresult>> reflectResult =
2245 prefetchRegInfo.ReflectPrefToRegistry(prefVal);
2246
2247 MOZ_ASSERT(reflectResult.value.isOk())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(reflectResult.value.isOk())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(reflectResult.value.isOk()))
), 0))) { do { } while (false); MOZ_ReportAssertionFailure("reflectResult.value.isOk()"
, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 2247); AnnotateMozCrashReason("MOZ_ASSERT" "(" "reflectResult.value.isOk()"
")"); do { *((volatile int*)__null) = 2247; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2248}
2249
2250static void SetupAlteredPrefetchPref() {
2251 mozilla::DllPrefetchExperimentRegistryInfo prefetchRegInfo;
2252
2253 mozilla::DebugOnly<mozilla::Result<Ok, nsresult>> reflectResult =
2254 prefetchRegInfo.ReflectPrefToRegistry(
2255 Preferences::GetInt(PREF_WIN_ALTERED_DLL_PREFETCH, 0));
2256 MOZ_ASSERT(reflectResult.value.isOk())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(reflectResult.value.isOk())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(reflectResult.value.isOk()))
), 0))) { do { } while (false); MOZ_ReportAssertionFailure("reflectResult.value.isOk()"
, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 2256); AnnotateMozCrashReason("MOZ_ASSERT" "(" "reflectResult.value.isOk()"
")"); do { *((volatile int*)__null) = 2256; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2257
2258 Preferences::RegisterCallback(&OnAlteredPrefetchPrefChanged,
2259 PREF_WIN_ALTERED_DLL_PREFETCH);
2260}
2261
2262static void ReflectSkeletonUIPrefToRegistry(const char* aPref, void* aData) {
2263 Unused << aPref;
2264 Unused << aData;
2265
2266 bool shouldBeEnabled =
2267 Preferences::GetBool(kPrefPreXulSkeletonUI, false) &&
2268 Preferences::GetBool(kPrefBrowserStartupBlankWindow, false) &&
2269 LookAndFeel::DrawInTitlebar();
2270 if (shouldBeEnabled && Preferences::HasUserValue(kPrefThemeId)) {
2271 nsCString themeId;
2272 Preferences::GetCString(kPrefThemeId, themeId);
2273 if (themeId.EqualsLiteral("default-theme@mozilla.org")) {
2274 Unused << SetPreXULSkeletonUIThemeId(ThemeMode::Default);
2275 } else if (themeId.EqualsLiteral("firefox-compact-dark@mozilla.org")) {
2276 Unused << SetPreXULSkeletonUIThemeId(ThemeMode::Dark);
2277 } else if (themeId.EqualsLiteral("firefox-compact-light@mozilla.org")) {
2278 Unused << SetPreXULSkeletonUIThemeId(ThemeMode::Light);
2279 } else {
2280 shouldBeEnabled = false;
2281 }
2282 } else if (shouldBeEnabled) {
2283 Unused << SetPreXULSkeletonUIThemeId(ThemeMode::Default);
2284 }
2285
2286 if (GetPreXULSkeletonUIEnabled() != shouldBeEnabled) {
2287 Unused << SetPreXULSkeletonUIEnabledIfAllowed(shouldBeEnabled);
2288 }
2289}
2290
2291static void SetupSkeletonUIPrefs() {
2292 ReflectSkeletonUIPrefToRegistry(nullptr, nullptr);
2293 Preferences::RegisterCallback(&ReflectSkeletonUIPrefToRegistry,
2294 kPrefPreXulSkeletonUI);
2295 Preferences::RegisterCallback(&ReflectSkeletonUIPrefToRegistry,
2296 kPrefBrowserStartupBlankWindow);
2297 Preferences::RegisterCallback(&ReflectSkeletonUIPrefToRegistry, kPrefThemeId);
2298 Preferences::RegisterCallback(
2299 &ReflectSkeletonUIPrefToRegistry,
2300 nsDependentCString(StaticPrefs::GetPrefName_browser_tabs_inTitlebar()));
2301}
2302
2303# if defined(MOZ_LAUNCHER_PROCESS)
2304
2305static void OnLauncherPrefChanged(const char* aPref, void* aData) {
2306 bool prefVal = Preferences::GetBool(PREF_WIN_LAUNCHER_PROCESS_ENABLED, true);
2307
2308 mozilla::LauncherRegistryInfo launcherRegInfo;
2309 mozilla::DebugOnly<mozilla::LauncherVoidResult> reflectResult =
2310 launcherRegInfo.ReflectPrefToRegistry(prefVal);
2311 MOZ_ASSERT(reflectResult.inspect().isOk())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(reflectResult.inspect().isOk())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(reflectResult.inspect().isOk
()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("reflectResult.inspect().isOk()", "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 2311); AnnotateMozCrashReason("MOZ_ASSERT" "(" "reflectResult.inspect().isOk()"
")"); do { *((volatile int*)__null) = 2311; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2312}
2313
2314static void OnLauncherTelemetryPrefChanged(const char* aPref, void* aData) {
2315 bool prefVal = Preferences::GetBool(kPrefHealthReportUploadEnabled, true);
2316
2317 mozilla::LauncherRegistryInfo launcherRegInfo;
2318 mozilla::DebugOnly<mozilla::LauncherVoidResult> reflectResult =
2319 launcherRegInfo.ReflectTelemetryPrefToRegistry(prefVal);
2320 MOZ_ASSERT(reflectResult.inspect().isOk())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(reflectResult.inspect().isOk())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(reflectResult.inspect().isOk
()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("reflectResult.inspect().isOk()", "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 2320); AnnotateMozCrashReason("MOZ_ASSERT" "(" "reflectResult.inspect().isOk()"
")"); do { *((volatile int*)__null) = 2320; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2321}
2322
2323static void SetupLauncherProcessPref() {
2324 if (gLauncherProcessState) {
2325 // We've already successfully run
2326 return;
2327 }
2328
2329 mozilla::LauncherRegistryInfo launcherRegInfo;
2330
2331 mozilla::LauncherResult<mozilla::LauncherRegistryInfo::EnabledState>
2332 enabledState = launcherRegInfo.IsEnabled();
2333
2334 if (enabledState.isOk()) {
2335 gLauncherProcessState = Some(enabledState.unwrap());
2336
2337 CrashReporter::RecordAnnotationU32(
2338 CrashReporter::Annotation::LauncherProcessState,
2339 static_cast<uint32_t>(enabledState.unwrap()));
2340
2341 // Reflect the launcher process registry state into user prefs
2342 Preferences::SetBool(
2343 PREF_WIN_LAUNCHER_PROCESS_ENABLED,
2344 enabledState.unwrap() !=
2345 mozilla::LauncherRegistryInfo::EnabledState::ForceDisabled);
2346 }
2347
2348 mozilla::DebugOnly<mozilla::LauncherVoidResult> reflectResult =
2349 launcherRegInfo.ReflectTelemetryPrefToRegistry(
2350 Preferences::GetBool(kPrefHealthReportUploadEnabled, true));
2351 MOZ_ASSERT(reflectResult.inspect().isOk())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(reflectResult.inspect().isOk())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(reflectResult.inspect().isOk
()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("reflectResult.inspect().isOk()", "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 2351); AnnotateMozCrashReason("MOZ_ASSERT" "(" "reflectResult.inspect().isOk()"
")"); do { *((volatile int*)__null) = 2351; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2352
2353 Preferences::RegisterCallback(&OnLauncherPrefChanged,
2354 PREF_WIN_LAUNCHER_PROCESS_ENABLED);
2355 Preferences::RegisterCallback(&OnLauncherTelemetryPrefChanged,
2356 kPrefHealthReportUploadEnabled);
2357}
2358
2359# endif // defined(MOZ_LAUNCHER_PROCESS)
2360
2361# if defined(MOZ_DEFAULT_BROWSER_AGENT)
2362
2363# define DEFAULT_BROWSER_AGENT_KEY_NAME \
2364 "SOFTWARE\\" MOZ_APP_VENDOR"Mozilla" "\\" MOZ_APP_NAME"firefox" "\\Default Browser Agent"
2365
2366static nsresult PrependRegistryValueName(nsAutoString& aValueName) {
2367 nsresult rv;
2368
2369 nsCOMPtr<nsIFile> binaryPath;
2370 rv = XRE_GetBinaryPath(getter_AddRefs(binaryPath));
2371 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 2371); return rv; } } while (false)
;
2372
2373 nsCOMPtr<nsIFile> binaryDir;
2374 rv = binaryPath->GetParent(getter_AddRefs(binaryDir));
2375 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 2375); return rv; } } while (false)
;
2376
2377 nsAutoString prefix;
2378 rv = binaryDir->GetPath(prefix);
2379 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 2379); return rv; } } while (false)
;
2380
2381 prefix.AppendLiteral("|");
2382 aValueName.Insert(prefix, 0);
2383
2384 return NS_OK;
2385}
2386
2387static void OnDefaultAgentTelemetryPrefChanged(const char* aPref, void* aData) {
2388 nsresult rv;
2389 nsAutoString valueName;
2390 if (strcmp(aPref, kPrefHealthReportUploadEnabled) == 0) {
2391 valueName.AssignLiteral("DisableTelemetry");
2392 } else if (strcmp(aPref, kPrefDefaultAgentEnabled) == 0) {
2393 valueName.AssignLiteral("DisableDefaultBrowserAgent");
2394 } else {
2395 return;
2396 }
2397 rv = PrependRegistryValueName(valueName);
2398 NS_ENSURE_SUCCESS_VOID(rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS_VOID(%s) failed with "
"result 0x%" "X" "%s%s%s", "rv", static_cast<uint32_t>
(__rv), name ? " (" : "", name ? name : "", name ? ")" : "");
NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 2398); return; } } while (false)
;
2399
2400 nsCOMPtr<nsIWindowsRegKey> regKey =
2401 do_CreateInstance("@mozilla.org/windows-registry-key;1", &rv);
2402 NS_ENSURE_SUCCESS_VOID(rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS_VOID(%s) failed with "
"result 0x%" "X" "%s%s%s", "rv", static_cast<uint32_t>
(__rv), name ? " (" : "", name ? name : "", name ? ")" : "");
NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 2402); return; } } while (false)
;
2403
2404 nsAutoString keyName;
2405 keyName.AppendLiteral(DEFAULT_BROWSER_AGENT_KEY_NAME);
2406 rv = regKey->Create(nsIWindowsRegKey::ROOT_KEY_CURRENT_USER, keyName,
2407 nsIWindowsRegKey::ACCESS_WRITE);
2408
2409 bool prefVal = Preferences::GetBool(aPref, true);
2410
2411 // We're recording whether the pref is *disabled*, so invert the value.
2412 rv = regKey->WriteIntValue(valueName, prefVal ? 0 : 1);
2413 NS_ENSURE_SUCCESS_VOID(rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS_VOID(%s) failed with "
"result 0x%" "X" "%s%s%s", "rv", static_cast<uint32_t>
(__rv), name ? " (" : "", name ? name : "", name ? ")" : "");
NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 2413); return; } } while (false)
;
2414}
2415
2416static void OnSetDefaultBrowserUserChoicePrefChanged(const char* aPref,
2417 void* aData) {
2418 nsresult rv;
2419 if (strcmp(aPref, kPrefSetDefaultBrowserUserChoicePref) != 0) {
2420 return;
2421 }
2422 nsAutoString valueName;
2423 valueName.AssignLiteral("SetDefaultBrowserUserChoice");
2424 rv = PrependRegistryValueName(valueName);
2425 NS_ENSURE_SUCCESS_VOID(rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS_VOID(%s) failed with "
"result 0x%" "X" "%s%s%s", "rv", static_cast<uint32_t>
(__rv), name ? " (" : "", name ? name : "", name ? ")" : "");
NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 2425); return; } } while (false)
;
2426
2427 nsCOMPtr<nsIWindowsRegKey> regKey =
2428 do_CreateInstance("@mozilla.org/windows-registry-key;1", &rv);
2429 NS_ENSURE_SUCCESS_VOID(rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS_VOID(%s) failed with "
"result 0x%" "X" "%s%s%s", "rv", static_cast<uint32_t>
(__rv), name ? " (" : "", name ? name : "", name ? ")" : "");
NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 2429); return; } } while (false)
;
2430
2431 nsAutoString keyName;
2432 keyName.AppendLiteral(DEFAULT_BROWSER_AGENT_KEY_NAME);
2433 rv = regKey->Create(nsIWindowsRegKey::ROOT_KEY_CURRENT_USER, keyName,
2434 nsIWindowsRegKey::ACCESS_WRITE);
2435
2436 bool prefVal = Preferences::GetBool(aPref, true);
2437
2438 rv = regKey->WriteIntValue(valueName, prefVal);
2439 NS_ENSURE_SUCCESS_VOID(rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS_VOID(%s) failed with "
"result 0x%" "X" "%s%s%s", "rv", static_cast<uint32_t>
(__rv), name ? " (" : "", name ? name : "", name ? ")" : "");
NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 2439); return; } } while (false)
;
2440}
2441
2442static void OnDefaultAgentRemoteSettingsPrefChanged(const char* aPref,
2443 void* aData) {
2444 nsresult rv;
2445 nsAutoString valueName;
2446 if (strcmp(aPref, kPrefServicesSettingsServer) == 0) {
2447 valueName.AssignLiteral("ServicesSettingsServer");
2448 } else {
2449 return;
2450 }
2451 rv = PrependRegistryValueName(valueName);
2452 NS_ENSURE_SUCCESS_VOID(rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS_VOID(%s) failed with "
"result 0x%" "X" "%s%s%s", "rv", static_cast<uint32_t>
(__rv), name ? " (" : "", name ? name : "", name ? ")" : "");
NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 2452); return; } } while (false)
;
2453
2454 nsCOMPtr<nsIWindowsRegKey> regKey =
2455 do_CreateInstance("@mozilla.org/windows-registry-key;1", &rv);
2456 NS_ENSURE_SUCCESS_VOID(rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS_VOID(%s) failed with "
"result 0x%" "X" "%s%s%s", "rv", static_cast<uint32_t>
(__rv), name ? " (" : "", name ? name : "", name ? ")" : "");
NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 2456); return; } } while (false)
;
2457
2458 nsAutoString keyName;
2459 keyName.AppendLiteral(DEFAULT_BROWSER_AGENT_KEY_NAME);
2460 rv = regKey->Create(nsIWindowsRegKey::ROOT_KEY_CURRENT_USER, keyName,
2461 nsIWindowsRegKey::ACCESS_WRITE);
2462
2463 NS_ENSURE_SUCCESS_VOID(rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS_VOID(%s) failed with "
"result 0x%" "X" "%s%s%s", "rv", static_cast<uint32_t>
(__rv), name ? " (" : "", name ? name : "", name ? ")" : "");
NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 2463); return; } } while (false)
;
2464
2465 nsAutoString prefVal;
2466 rv = Preferences::GetString(aPref, prefVal);
2467 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
2468 return;
2469 }
2470
2471 if (prefVal.IsEmpty()) {
2472 rv = regKey->RemoveValue(valueName);
2473 } else {
2474 rv = regKey->WriteStringValue(valueName, prefVal);
2475 }
2476 NS_ENSURE_SUCCESS_VOID(rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS_VOID(%s) failed with "
"result 0x%" "X" "%s%s%s", "rv", static_cast<uint32_t>
(__rv), name ? " (" : "", name ? name : "", name ? ")" : "");
NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 2476); return; } } while (false)
;
2477}
2478
2479static void SetDefaultAgentLastRunTime() {
2480 nsresult rv;
2481 nsAutoString valueName;
2482 valueName.AppendLiteral("AppLastRunTime");
2483 rv = PrependRegistryValueName(valueName);
2484 NS_ENSURE_SUCCESS_VOID(rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS_VOID(%s) failed with "
"result 0x%" "X" "%s%s%s", "rv", static_cast<uint32_t>
(__rv), name ? " (" : "", name ? name : "", name ? ")" : "");
NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 2484); return; } } while (false)
;
2485
2486 nsCOMPtr<nsIWindowsRegKey> regKey =
2487 do_CreateInstance("@mozilla.org/windows-registry-key;1", &rv);
2488 NS_ENSURE_SUCCESS_VOID(rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS_VOID(%s) failed with "
"result 0x%" "X" "%s%s%s", "rv", static_cast<uint32_t>
(__rv), name ? " (" : "", name ? name : "", name ? ")" : "");
NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 2488); return; } } while (false)
;
2489
2490 nsAutoString keyName;
2491 keyName.AppendLiteral(DEFAULT_BROWSER_AGENT_KEY_NAME);
2492 rv = regKey->Create(nsIWindowsRegKey::ROOT_KEY_CURRENT_USER, keyName,
2493 nsIWindowsRegKey::ACCESS_WRITE);
2494 NS_ENSURE_SUCCESS_VOID(rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS_VOID(%s) failed with "
"result 0x%" "X" "%s%s%s", "rv", static_cast<uint32_t>
(__rv), name ? " (" : "", name ? name : "", name ? ")" : "");
NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 2494); return; } } while (false)
;
2495
2496 FILETIME fileTime;
2497 GetSystemTimeAsFileTime(&fileTime);
2498
2499 ULARGE_INTEGER integerTime;
2500 integerTime.u.LowPart = fileTime.dwLowDateTime;
2501 integerTime.u.HighPart = fileTime.dwHighDateTime;
2502
2503 rv = regKey->WriteInt64Value(valueName, integerTime.QuadPart);
2504 NS_ENSURE_SUCCESS_VOID(rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS_VOID(%s) failed with "
"result 0x%" "X" "%s%s%s", "rv", static_cast<uint32_t>
(__rv), name ? " (" : "", name ? name : "", name ? ")" : "");
NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 2504); return; } } while (false)
;
2505}
2506
2507# endif // defined(MOZ_DEFAULT_BROWSER_AGENT)
2508
2509#endif // XP_WIN
2510
2511void UnlockProfile() {
2512 if (gProfileLock) {
2513 gProfileLock->Unlock();
2514 }
2515}
2516
2517nsresult LaunchChild(bool aBlankCommandLine, bool aTryExec) {
2518 // Restart this process by exec'ing it into the current process
2519 // if supported by the platform. Otherwise, use NSPR.
2520
2521#ifdef MOZ_JPROF
2522 // make sure JPROF doesn't think we're E10s
2523 unsetenv("JPROF_ISCHILD");
2524#endif
2525
2526 if (aBlankCommandLine) {
1
Assuming 'aBlankCommandLine' is false
2
Taking false branch
2527 gRestartArgc = 1;
2528 gRestartArgv[gRestartArgc] = nullptr;
2529 }
2530
2531#if defined(MOZ_HAS_REMOTE1)
2532 if (gRestartWithoutRemote) {
3
Assuming 'gRestartWithoutRemote' is false
4
Taking false branch
2533 SaveToEnv("MOZ_NO_REMOTE=1");
2534 }
2535#endif
2536
2537 SaveToEnv("MOZ_LAUNCHED_CHILD=1");
5
Calling 'SaveToEnv'
2538#if defined(MOZ_LAUNCHER_PROCESS)
2539 SaveToEnv("MOZ_LAUNCHER_PROCESS=1");
2540#endif // defined(MOZ_LAUNCHER_PROCESS)
2541
2542#if !defined(MOZ_WIDGET_ANDROID) // Android has separate restart code.
2543# if defined(XP_MACOSX)
2544 InitializeMacApp();
2545 CommandLineServiceMac::SetupMacCommandLine(gRestartArgc, gRestartArgv, true);
2546 LaunchChildMac(gRestartArgc, gRestartArgv);
2547# else
2548 nsCOMPtr<nsIFile> lf;
2549 nsresult rv = XRE_GetBinaryPath(getter_AddRefs(lf));
2550 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return rv;
2551
2552# if defined(XP_WIN)
2553 nsAutoString exePath;
2554 rv = lf->GetPath(exePath);
2555 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return rv;
2556
2557 HANDLE hProcess;
2558 if (!WinLaunchChild(exePath.get(), gRestartArgc, gRestartArgv, nullptr,
2559 &hProcess))
2560 return NS_ERROR_FAILURE;
2561 // Keep the current process around until the restarted process has created
2562 // its message queue, to avoid the launched process's windows being forced
2563 // into the background.
2564 mozilla::WaitForInputIdle(hProcess);
2565 ::CloseHandle(hProcess);
2566
2567# else
2568 nsAutoCString exePath;
2569 rv = lf->GetNativePath(exePath);
2570 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return rv;
2571
2572# if defined(XP_UNIX1)
2573 if (aTryExec) {
2574 execv(exePath.get(), gRestartArgv);
2575
2576 // If execv returns we know it's because it failed.
2577 return NS_ERROR_FAILURE;
2578 }
2579# endif
2580 if (PR_CreateProcessDetached(exePath.get(), gRestartArgv, nullptr, nullptr) ==
2581 PR_FAILURE) {
2582 return NS_ERROR_FAILURE;
2583 }
2584
2585 // Note that we don't know if the child process starts okay, if it
2586 // immediately returns non-zero then we may mask that by returning a zero
2587 // exit status.
2588
2589# endif // WP_WIN
2590# endif // WP_MACOSX
2591#endif // MOZ_WIDGET_ANDROID
2592
2593 return NS_ERROR_LAUNCHED_CHILD_PROCESS;
2594}
2595
2596static const char kProfileProperties[] =
2597 "chrome://mozapps/locale/profile/profileSelection.properties";
2598
2599namespace {
2600
2601/**
2602 * This class, instead of a raw nsresult, should be the return type of any
2603 * function called by SelectProfile that initializes XPCOM.
2604 */
2605class ReturnAbortOnError {
2606 public:
2607 MOZ_IMPLICIT ReturnAbortOnError(nsresult aRv) { mRv = ConvertRv(aRv); }
2608
2609 operator nsresult() { return mRv; }
2610
2611 private:
2612 inline nsresult ConvertRv(nsresult aRv) {
2613 if (NS_SUCCEEDED(aRv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(aRv)), 1))) || aRv == NS_ERROR_LAUNCHED_CHILD_PROCESS) {
2614 return aRv;
2615 }
2616#ifdef MOZ_BACKGROUNDTASKS1
2617 // A background task that fails to lock its profile will return
2618 // NS_ERROR_UNEXPECTED and this will allow the task to exit with a
2619 // non-zero exit code.
2620 if (aRv == NS_ERROR_UNEXPECTED && BackgroundTasks::IsBackgroundTaskMode()) {
2621 return aRv;
2622 }
2623#endif
2624 return NS_ERROR_ABORT;
2625 }
2626
2627 nsresult mRv;
2628};
2629
2630} // namespace
2631
2632static nsresult ProfileMissingDialog(nsINativeAppSupport* aNative) {
2633#ifdef MOZ_WIDGET_ANDROID
2634 // We cannot really do anything this early during initialization, so we just
2635 // return as this is likely the effect of misconfiguration on the test side.
2636 // Non-test code paths cannot set the profile folder, which is always the
2637 // default one.
2638 Output(true, "Could not find profile folder.\n");
2639 return NS_ERROR_ABORT;
2640#else
2641# ifdef MOZ_BACKGROUNDTASKS1
2642 if (BackgroundTasks::IsBackgroundTaskMode()) {
2643 // We should never get to this point in background task mode.
2644 printf_stderr(
2645 "Could not determine any profile running in backgroundtask mode!\n");
2646 return NS_ERROR_ABORT;
2647 }
2648# endif // MOZ_BACKGROUNDTASKS
2649
2650 nsresult rv;
2651
2652 ScopedXPCOMStartup xpcom;
2653 rv = xpcom.Initialize();
2654 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 2654); return rv; } } while (false)
;
2655
2656 rv = xpcom.SetWindowCreator(aNative);
2657 NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "NS_ERROR_FAILURE", static_cast
<uint32_t>(__rv), name ? " (" : "", name ? name : "", name
? ")" : ""); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 2657); return NS_ERROR_FAILURE; } } while (false)
;
2658
2659 { // extra scoping is needed so we release these components before xpcom
2660 // shutdown
2661 nsCOMPtr<nsIStringBundleService> sbs =
2662 mozilla::components::StringBundle::Service();
2663 NS_ENSURE_TRUE(sbs, NS_ERROR_FAILURE)do { if ((__builtin_expect(!!(!(sbs)), 0))) { NS_DebugBreak(NS_DEBUG_WARNING
, "NS_ENSURE_TRUE(" "sbs" ") failed", nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 2663); return NS_ERROR_FAILURE; } } while (false)
;
2664
2665 nsCOMPtr<nsIStringBundle> sb;
2666 sbs->CreateBundle(kProfileProperties, getter_AddRefs(sb));
2667 NS_ENSURE_TRUE_LOG(sbs, NS_ERROR_FAILURE)do { if ((__builtin_expect(!!(!(sbs)), 0))) { NS_DebugBreak(NS_DEBUG_WARNING
, "NS_ENSURE_TRUE(" "sbs" ") failed", nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 2667); gLogConsoleErrors = true; return NS_ERROR_FAILURE; }
} while (0)
;
2668
2669 NS_ConvertUTF8toUTF16 appName(gAppData->name);
2670 AutoTArray<nsString, 2> params = {appName, appName};
2671
2672 // profileMissing
2673 nsAutoString missingMessage;
2674 rv = sb->FormatStringFromName("profileMissing", params, missingMessage);
2675 NS_ENSURE_SUCCESS(rv, NS_ERROR_ABORT)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "NS_ERROR_ABORT", static_cast
<uint32_t>(__rv), name ? " (" : "", name ? name : "", name
? ")" : ""); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 2675); return NS_ERROR_ABORT; } } while (false)
;
2676
2677 nsAutoString missingTitle;
2678 params.SetLength(1);
2679 rv = sb->FormatStringFromName("profileMissingTitle", params, missingTitle);
2680 NS_ENSURE_SUCCESS(rv, NS_ERROR_ABORT)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "NS_ERROR_ABORT", static_cast
<uint32_t>(__rv), name ? " (" : "", name ? name : "", name
? ")" : ""); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 2680); return NS_ERROR_ABORT; } } while (false)
;
2681
2682 nsCOMPtr<nsIPromptService> ps(do_GetService(NS_PROMPTSERVICE_CONTRACTID"@mozilla.org/prompter;1"));
2683 NS_ENSURE_TRUE(ps, NS_ERROR_FAILURE)do { if ((__builtin_expect(!!(!(ps)), 0))) { NS_DebugBreak(NS_DEBUG_WARNING
, "NS_ENSURE_TRUE(" "ps" ") failed", nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 2683); return NS_ERROR_FAILURE; } } while (false)
;
2684
2685 ps->Alert(nullptr, missingTitle.get(), missingMessage.get());
2686
2687 return NS_ERROR_ABORT;
2688 }
2689#endif // MOZ_WIDGET_ANDROID
2690}
2691
2692static ReturnAbortOnError ProfileLockedDialog(nsIFile* aProfileDir,
2693 nsIFile* aProfileLocalDir,
2694 nsIProfileUnlocker* aUnlocker,
2695 nsINativeAppSupport* aNative,
2696 nsIProfileLock** aResult) {
2697 nsresult rv;
2698
2699 bool exists;
2700 aProfileDir->Exists(&exists);
2701 if (!exists) {
2702 return ProfileMissingDialog(aNative);
2703 }
2704
2705 ScopedXPCOMStartup xpcom;
2706 rv = xpcom.Initialize();
2707 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 2707); return rv; } } while (false)
;
2708
2709#if defined(MOZ_TELEMETRY_REPORTING)
2710 // We cannot check if telemetry has been disabled by the user, yet.
2711 // So, rely on the build time settings, instead.
2712 mozilla::Telemetry::WriteFailedProfileLock(aProfileDir);
2713#endif
2714
2715 rv = xpcom.SetWindowCreator(aNative);
2716 NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "NS_ERROR_FAILURE", static_cast
<uint32_t>(__rv), name ? " (" : "", name ? name : "", name
? ")" : ""); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 2716); return NS_ERROR_FAILURE; } } while (false)
;
2717
2718 { // extra scoping is needed so we release these components before xpcom
2719 // shutdown
2720 nsCOMPtr<nsIStringBundleService> sbs =
2721 mozilla::components::StringBundle::Service();
2722 NS_ENSURE_TRUE(sbs, NS_ERROR_FAILURE)do { if ((__builtin_expect(!!(!(sbs)), 0))) { NS_DebugBreak(NS_DEBUG_WARNING
, "NS_ENSURE_TRUE(" "sbs" ") failed", nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 2722); return NS_ERROR_FAILURE; } } while (false)
;
2723
2724 nsCOMPtr<nsIStringBundle> sb;
2725 sbs->CreateBundle(kProfileProperties, getter_AddRefs(sb));
2726 NS_ENSURE_TRUE_LOG(sbs, NS_ERROR_FAILURE)do { if ((__builtin_expect(!!(!(sbs)), 0))) { NS_DebugBreak(NS_DEBUG_WARNING
, "NS_ENSURE_TRUE(" "sbs" ") failed", nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 2726); gLogConsoleErrors = true; return NS_ERROR_FAILURE; }
} while (0)
;
2727
2728 NS_ConvertUTF8toUTF16 appName(gAppData->name);
2729 AutoTArray<nsString, 3> params = {appName, appName, appName};
2730
2731 nsAutoString killMessage;
2732#ifndef XP_MACOSX
2733 rv = sb->FormatStringFromName(
2734 aUnlocker ? "restartMessageUnlocker" : "restartMessageNoUnlocker2",
2735 params, killMessage);
2736#else
2737 rv = sb->FormatStringFromName(
2738 aUnlocker ? "restartMessageUnlockerMac" : "restartMessageNoUnlockerMac",
2739 params, killMessage);
2740#endif
2741 NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "NS_ERROR_FAILURE", static_cast
<uint32_t>(__rv), name ? " (" : "", name ? name : "", name
? ")" : ""); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 2741); return NS_ERROR_FAILURE; } } while (false)
;
2742
2743 params.SetLength(1);
2744 nsAutoString killTitle;
2745 rv = sb->FormatStringFromName("restartTitle", params, killTitle);
2746 NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "NS_ERROR_FAILURE", static_cast
<uint32_t>(__rv), name ? " (" : "", name ? name : "", name
? ")" : ""); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 2746); return NS_ERROR_FAILURE; } } while (false)
;
2747
2748#ifdef MOZ_BACKGROUNDTASKS1
2749 if (BackgroundTasks::IsBackgroundTaskMode()) {
2750 // This error is handled specially to exit with a non-zero exit code.
2751 printf_stderr("%s\n", NS_LossyConvertUTF16toASCII(killMessage).get());
2752 return NS_ERROR_UNEXPECTED;
2753 }
2754#endif
2755
2756 if (gfxPlatform::IsHeadless()) {
2757 // TODO: make a way to turn off all dialogs when headless.
2758 Output(true, "%s\n", NS_LossyConvertUTF16toASCII(killMessage).get());
2759 return NS_ERROR_FAILURE;
2760 }
2761
2762 nsCOMPtr<nsIPromptService> ps(do_GetService(NS_PROMPTSERVICE_CONTRACTID"@mozilla.org/prompter;1"));
2763 NS_ENSURE_TRUE(ps, NS_ERROR_FAILURE)do { if ((__builtin_expect(!!(!(ps)), 0))) { NS_DebugBreak(NS_DEBUG_WARNING
, "NS_ENSURE_TRUE(" "ps" ") failed", nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 2763); return NS_ERROR_FAILURE; } } while (false)
;
2764
2765 if (aUnlocker) {
2766 int32_t button;
2767#ifdef MOZ_WIDGET_ANDROID
2768 // On Android we always kill the process if the lock is still being held
2769 button = 0;
2770#else
2771 const uint32_t flags = (nsIPromptService::BUTTON_TITLE_IS_STRING *
2772 nsIPromptService::BUTTON_POS_0) +
2773 (nsIPromptService::BUTTON_TITLE_CANCEL *
2774 nsIPromptService::BUTTON_POS_1);
2775
2776 bool checkState = false;
2777 rv = ps->ConfirmEx(nullptr, killTitle.get(), killMessage.get(), flags,
2778 killTitle.get(), nullptr, nullptr, nullptr,
2779 &checkState, &button);
2780 NS_ENSURE_SUCCESS_LOG(rv, rv)do { if ((__builtin_expect(!!(!(((bool)(__builtin_expect(!!(!
NS_FAILED_impl(rv)), 1))))), 0))) { NS_DebugBreak(NS_DEBUG_WARNING
, "NS_ENSURE_TRUE(" "NS_SUCCEEDED(rv)" ") failed", nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 2780); gLogConsoleErrors = true; return rv; } } while (0)
;
2781#endif
2782
2783 if (button == 0) {
2784 rv = aUnlocker->Unlock(nsIProfileUnlocker::FORCE_QUIT);
2785 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
2786 return rv;
2787 }
2788
2789 SaveFileToEnv("XRE_PROFILE_PATH", aProfileDir);
2790 SaveFileToEnv("XRE_PROFILE_LOCAL_PATH", aProfileLocalDir);
2791
2792#if defined(MOZ_HAS_REMOTE1)
2793 if (gRemoteService) {
2794 gRemoteService->UnlockStartup();
2795 gRemoteService = nullptr;
2796 }
2797#endif
2798 return LaunchChild(false, true);
2799 }
2800 } else {
2801 rv = ps->Alert(nullptr, killTitle.get(), killMessage.get());
2802 NS_ENSURE_SUCCESS_LOG(rv, rv)do { if ((__builtin_expect(!!(!(((bool)(__builtin_expect(!!(!
NS_FAILED_impl(rv)), 1))))), 0))) { NS_DebugBreak(NS_DEBUG_WARNING
, "NS_ENSURE_TRUE(" "NS_SUCCEEDED(rv)" ") failed", nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 2802); gLogConsoleErrors = true; return rv; } } while (0)
;
2803 }
2804
2805 return NS_ERROR_ABORT;
2806 }
2807}
2808
2809static const char kProfileManagerURL[] =
2810 "chrome://mozapps/content/profile/profileSelection.xhtml";
2811
2812static ReturnAbortOnError ShowProfileManager(
2813 nsIToolkitProfileService* aProfileSvc, nsINativeAppSupport* aNative) {
2814 nsresult rv;
2815
2816 nsCOMPtr<nsIFile> profD, profLD;
2817 bool offline = false;
2818 int32_t dialogReturn;
2819
2820 {
2821 ScopedXPCOMStartup xpcom;
2822 rv = xpcom.Initialize();
2823 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 2823); return rv; } } while (false)
;
2824
2825 rv = xpcom.SetWindowCreator(aNative);
2826 NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "NS_ERROR_FAILURE", static_cast
<uint32_t>(__rv), name ? " (" : "", name ? name : "", name
? ")" : ""); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 2826); return NS_ERROR_FAILURE; } } while (false)
;
2827
2828#ifdef XP_MACOSX
2829 InitializeMacApp();
2830 CommandLineServiceMac::SetupMacCommandLine(gRestartArgc, gRestartArgv,
2831 true);
2832#endif
2833
2834 { // extra scoping is needed so we release these components before xpcom
2835 // shutdown
2836 nsCOMPtr<nsIWindowWatcher> windowWatcher(
2837 do_GetService(NS_WINDOWWATCHER_CONTRACTID"@mozilla.org/embedcomp/window-watcher;1"));
2838 nsCOMPtr<nsIDialogParamBlock> ioParamBlock(
2839 do_CreateInstance(NS_DIALOGPARAMBLOCK_CONTRACTID"@mozilla.org/embedcomp/dialogparam;1"));
2840 nsCOMPtr<nsIMutableArray> dlgArray(
2841 do_CreateInstance(NS_ARRAY_CONTRACTID"@mozilla.org/array;1"));
2842 NS_ENSURE_TRUE(windowWatcher && ioParamBlock && dlgArray,do { if ((__builtin_expect(!!(!(windowWatcher && ioParamBlock
&& dlgArray)), 0))) { NS_DebugBreak(NS_DEBUG_WARNING
, "NS_ENSURE_TRUE(" "windowWatcher && ioParamBlock && dlgArray"
") failed", nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 2843); return NS_ERROR_FAILURE; } } while (false)
2843 NS_ERROR_FAILURE)do { if ((__builtin_expect(!!(!(windowWatcher && ioParamBlock
&& dlgArray)), 0))) { NS_DebugBreak(NS_DEBUG_WARNING
, "NS_ENSURE_TRUE(" "windowWatcher && ioParamBlock && dlgArray"
") failed", nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 2843); return NS_ERROR_FAILURE; } } while (false)
;
2844
2845 ioParamBlock->SetObjects(dlgArray);
2846
2847 nsCOMPtr<nsIAppStartup> appStartup(components::AppStartup::Service());
2848 NS_ENSURE_TRUE(appStartup, NS_ERROR_FAILURE)do { if ((__builtin_expect(!!(!(appStartup)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "appStartup" ") failed",
nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 2848); return NS_ERROR_FAILURE; } } while (false)
;
2849
2850 nsAutoCString features("centerscreen,chrome,modal,titlebar");
2851 // If we're launching a private browsing window make sure to set that
2852 // feature for the Profile Manager window as well, so it groups correctly
2853 // on the Windows taskbar.
2854 if (CheckArgExists("private-window") == ARG_FOUND) {
2855 features.AppendLiteral(",private");
2856 }
2857 nsCOMPtr<mozIDOMWindowProxy> newWindow;
2858 rv = windowWatcher->OpenWindow(
2859 nullptr, nsDependentCString(kProfileManagerURL), "_blank"_ns,
2860 features, ioParamBlock, getter_AddRefs(newWindow));
2861
2862 NS_ENSURE_SUCCESS_LOG(rv, rv)do { if ((__builtin_expect(!!(!(((bool)(__builtin_expect(!!(!
NS_FAILED_impl(rv)), 1))))), 0))) { NS_DebugBreak(NS_DEBUG_WARNING
, "NS_ENSURE_TRUE(" "NS_SUCCEEDED(rv)" ") failed", nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 2862); gLogConsoleErrors = true; return rv; } } while (0)
;
2863
2864 rv = ioParamBlock->GetInt(0, &dialogReturn);
2865 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0))) || dialogReturn == nsIToolkitProfileService::exit) {
2866 return NS_ERROR_ABORT;
2867 }
2868
2869 int32_t startOffline;
2870 rv = ioParamBlock->GetInt(1, &startOffline);
2871 offline = NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1))) && startOffline == 1;
2872
2873 rv = dlgArray->QueryElementAt(0, NS_GET_IID(nsIFile)(nsIFile::COMTypeInfo<nsIFile, void>::kIID),
2874 getter_AddRefs(profD));
2875 NS_ENSURE_SUCCESS_LOG(rv, rv)do { if ((__builtin_expect(!!(!(((bool)(__builtin_expect(!!(!
NS_FAILED_impl(rv)), 1))))), 0))) { NS_DebugBreak(NS_DEBUG_WARNING
, "NS_ENSURE_TRUE(" "NS_SUCCEEDED(rv)" ") failed", nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 2875); gLogConsoleErrors = true; return rv; } } while (0)
;
2876
2877 rv = dlgArray->QueryElementAt(1, NS_GET_IID(nsIFile)(nsIFile::COMTypeInfo<nsIFile, void>::kIID),
2878 getter_AddRefs(profLD));
2879 NS_ENSURE_SUCCESS_LOG(rv, rv)do { if ((__builtin_expect(!!(!(((bool)(__builtin_expect(!!(!
NS_FAILED_impl(rv)), 1))))), 0))) { NS_DebugBreak(NS_DEBUG_WARNING
, "NS_ENSURE_TRUE(" "NS_SUCCEEDED(rv)" ") failed", nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 2879); gLogConsoleErrors = true; return rv; } } while (0)
;
2880 }
2881 }
2882
2883 if (offline) {
2884 SaveToEnv("XRE_START_OFFLINE=1");
2885 }
2886
2887 // User requested that we restart back into the profile manager.
2888 if (dialogReturn == nsIToolkitProfileService::restart) {
2889 SaveToEnv("XRE_RESTART_TO_PROFILE_MANAGER=1");
2890 SaveToEnv("XRE_RESTARTED_BY_PROFILE_MANAGER=1");
2891 } else {
2892 MOZ_ASSERT(dialogReturn == nsIToolkitProfileService::launchWithProfile)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(dialogReturn == nsIToolkitProfileService::launchWithProfile
)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(dialogReturn == nsIToolkitProfileService::launchWithProfile
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"dialogReturn == nsIToolkitProfileService::launchWithProfile"
, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 2892); AnnotateMozCrashReason("MOZ_ASSERT" "(" "dialogReturn == nsIToolkitProfileService::launchWithProfile"
")"); do { *((volatile int*)__null) = 2892; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2893 SaveFileToEnv("XRE_PROFILE_PATH", profD);
2894 SaveFileToEnv("XRE_PROFILE_LOCAL_PATH", profLD);
2895 SaveToEnv("XRE_RESTARTED_BY_PROFILE_MANAGER=1");
2896 }
2897
2898 if (gRestartedByOS) {
2899 // Re-add this argument when actually starting the application.
2900 char** newArgv =
2901 (char**)realloc(gRestartArgv, sizeof(char*) * (gRestartArgc + 2));
2902 NS_ENSURE_TRUE(newArgv, NS_ERROR_OUT_OF_MEMORY)do { if ((__builtin_expect(!!(!(newArgv)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "newArgv" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 2902); return NS_ERROR_OUT_OF_MEMORY; } } while (false)
;
2903 gRestartArgv = newArgv;
2904 gRestartArgv[gRestartArgc++] = const_cast<char*>("-os-restarted");
2905 gRestartArgv[gRestartArgc] = nullptr;
2906 }
2907#if defined(MOZ_HAS_REMOTE1)
2908 if (gRemoteService) {
2909 gRemoteService->UnlockStartup();
2910 gRemoteService = nullptr;
2911 }
2912#endif
2913 return LaunchChild(false, true);
2914}
2915
2916static bool gDoMigration = false;
2917static bool gDoProfileReset = false;
2918static nsCOMPtr<nsIToolkitProfile> gResetOldProfile;
2919
2920static nsresult LockProfile(nsINativeAppSupport* aNative, nsIFile* aRootDir,
2921 nsIFile* aLocalDir, nsIToolkitProfile* aProfile,
2922 nsIProfileLock** aResult) {
2923 // If you close Firefox and very quickly reopen it, the old Firefox may
2924 // still be closing down. Rather than immediately showing the
2925 // "Firefox is running but is not responding" message, we spend a few
2926 // seconds retrying first.
2927
2928 static const int kLockRetrySeconds = 5;
2929 static const int kLockRetrySleepMS = 100;
2930
2931 nsresult rv;
2932 nsCOMPtr<nsIProfileUnlocker> unlocker;
2933 const TimeStamp start = TimeStamp::Now();
2934 do {
2935 if (aProfile) {
2936 rv = aProfile->Lock(getter_AddRefs(unlocker), aResult);
2937 } else {
2938 rv = NS_LockProfilePath(aRootDir, aLocalDir, getter_AddRefs(unlocker),
2939 aResult);
2940 }
2941 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
2942 StartupTimeline::Record(StartupTimeline::AFTER_PROFILE_LOCKED);
2943 return NS_OK;
2944 }
2945 PR_Sleep(kLockRetrySleepMS);
2946 } while (TimeStamp::Now() - start <
2947 TimeDuration::FromSeconds(kLockRetrySeconds));
2948
2949 return ProfileLockedDialog(aRootDir, aLocalDir, unlocker, aNative, aResult);
2950}
2951
2952// Pick a profile. We need to end up with a profile root dir, local dir and
2953// potentially an nsIToolkitProfile instance.
2954//
2955// 1) check for --profile <path>
2956// 2) check for -P <name>
2957// 3) check for --ProfileManager
2958// 4) use the default profile, if there is one
2959// 5) if there are *no* profiles, set up profile-migration
2960// 6) display the profile-manager UI
2961static nsresult SelectProfile(nsToolkitProfileService* aProfileSvc,
2962 nsINativeAppSupport* aNative, nsIFile** aRootDir,
2963 nsIFile** aLocalDir, nsIToolkitProfile** aProfile,
2964 bool* aWasDefaultSelection) {
2965 StartupTimeline::Record(StartupTimeline::SELECT_PROFILE);
2966
2967 nsresult rv;
2968
2969 if (EnvHasValue("MOZ_RESET_PROFILE_RESTART")) {
2970 gDoProfileReset = true;
2971 gDoMigration = true;
2972 }
2973
2974 // reset-profile and migration args need to be checked before any profiles are
2975 // chosen below.
2976 ArgResult ar = CheckArg("reset-profile");
2977 if (ar == ARG_FOUND) {
2978 gDoProfileReset = true;
2979 }
2980
2981 ar = CheckArg("migration");
2982 if (ar == ARG_FOUND) {
2983 gDoMigration = true;
2984 }
2985
2986#if defined(XP_WIN)
2987 // This arg is only used to indicate to telemetry that a profile refresh
2988 // (reset+migration) was requested from the uninstaller, pass this along
2989 // via an environment variable for simplicity.
2990 ar = CheckArg("uninstaller-profile-refresh");
2991 if (ar == ARG_FOUND) {
2992 SaveToEnv("MOZ_UNINSTALLER_PROFILE_REFRESH=1");
2993 }
2994#endif
2995
2996 if (EnvHasValue("XRE_RESTART_TO_PROFILE_MANAGER")) {
2997 return ShowProfileManager(aProfileSvc, aNative);
2998 }
2999
3000 // Ask the profile manager to select the profile directories to use.
3001 bool didCreate = false;
3002 rv = aProfileSvc->SelectStartupProfile(&gArgc, gArgv, gDoProfileReset,
3003 aRootDir, aLocalDir, aProfile,
3004 &didCreate, aWasDefaultSelection);
3005
3006 if (rv == NS_ERROR_SHOW_PROFILE_MANAGER) {
3007 return ShowProfileManager(aProfileSvc, aNative);
3008 }
3009
3010 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 3010); return rv; } } while (false)
;
3011
3012 if (didCreate) {
3013 // For a fresh install, we would like to let users decide
3014 // to do profile migration on their own later after using.
3015 gDoProfileReset = false;
3016 gDoMigration = false;
3017 }
3018
3019 if (gDoProfileReset && !*aProfile) {
3020 NS_WARNING("Profile reset is only supported for named profiles.")NS_DebugBreak(NS_DEBUG_WARNING, "Profile reset is only supported for named profiles."
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 3020)
;
3021 return NS_ERROR_ABORT;
3022 }
3023
3024 // No profile could be found. This generally shouldn't happen, a new profile
3025 // should be created in all cases except for profile reset which is covered
3026 // above, but just in case...
3027 if (!*aRootDir) {
3028 NS_WARNING("Failed to select or create profile.")NS_DebugBreak(NS_DEBUG_WARNING, "Failed to select or create profile."
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 3028)
;
3029 return NS_ERROR_ABORT;
3030 }
3031
3032 return NS_OK;
3033}
3034
3035#ifdef MOZ_BLOCK_PROFILE_DOWNGRADE1
3036struct FileWriteFunc final : public JSONWriteFunc {
3037 FILE* mFile;
3038 explicit FileWriteFunc(FILE* aFile) : mFile(aFile) {}
3039
3040 void Write(const Span<const char>& aStr) final {
3041 fprintf(mFile, "%.*s", int(aStr.size()), aStr.data());
3042 }
3043};
3044
3045static void SubmitDowngradeTelemetry(const nsCString& aLastVersion,
3046 bool aHasSync, int32_t aButton) {
3047 nsCOMPtr<nsIPrefService> prefSvc =
3048 do_GetService("@mozilla.org/preferences-service;1");
3049 NS_ENSURE_TRUE_VOID(prefSvc)do { if ((__builtin_expect(!!(!(prefSvc)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "prefSvc" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 3049); return; } } while (false)
;
3050
3051 nsCOMPtr<nsIPrefBranch> prefBranch = do_QueryInterface(prefSvc);
3052 NS_ENSURE_TRUE_VOID(prefBranch)do { if ((__builtin_expect(!!(!(prefBranch)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "prefBranch" ") failed",
nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 3052); return; } } while (false)
;
3053
3054 bool enabled;
3055 nsresult rv =
3056 prefBranch->GetBoolPref(kPrefHealthReportUploadEnabled, &enabled);
3057 NS_ENSURE_SUCCESS_VOID(rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS_VOID(%s) failed with "
"result 0x%" "X" "%s%s%s", "rv", static_cast<uint32_t>
(__rv), name ? " (" : "", name ? name : "", name ? ")" : "");
NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 3057); return; } } while (false)
;
3058 if (!enabled) {
3059 return;
3060 }
3061
3062 nsCString server;
3063 rv = prefBranch->GetCharPref("toolkit.telemetry.server", server);
3064 NS_ENSURE_SUCCESS_VOID(rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS_VOID(%s) failed with "
"result 0x%" "X" "%s%s%s", "rv", static_cast<uint32_t>
(__rv), name ? " (" : "", name ? name : "", name ? ")" : "");
NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 3064); return; } } while (false)
;
3065
3066 nsCString clientId;
3067 rv = prefBranch->GetCharPref("toolkit.telemetry.cachedClientID", clientId);
3068 NS_ENSURE_SUCCESS_VOID(rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS_VOID(%s) failed with "
"result 0x%" "X" "%s%s%s", "rv", static_cast<uint32_t>
(__rv), name ? " (" : "", name ? name : "", name ? ")" : "");
NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 3068); return; } } while (false)
;
3069
3070 rv = prefSvc->GetDefaultBranch(nullptr, getter_AddRefs(prefBranch));
3071 NS_ENSURE_SUCCESS_VOID(rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS_VOID(%s) failed with "
"result 0x%" "X" "%s%s%s", "rv", static_cast<uint32_t>
(__rv), name ? " (" : "", name ? name : "", name ? ")" : "");
NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 3071); return; } } while (false)
;
3072
3073 nsCString channel("default");
3074 rv = prefBranch->GetCharPref("app.update.channel", channel);
3075 NS_ENSURE_SUCCESS_VOID(rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS_VOID(%s) failed with "
"result 0x%" "X" "%s%s%s", "rv", static_cast<uint32_t>
(__rv), name ? " (" : "", name ? name : "", name ? ")" : "");
NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 3075); return; } } while (false)
;
3076
3077 nsID uuid;
3078 rv = nsID::GenerateUUIDInPlace(uuid);
3079 NS_ENSURE_SUCCESS_VOID(rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS_VOID(%s) failed with "
"result 0x%" "X" "%s%s%s", "rv", static_cast<uint32_t>
(__rv), name ? " (" : "", name ? name : "", name ? ")" : "");
NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 3079); return; } } while (false)
;
3080
3081 nsCString arch("null");
3082 nsCOMPtr<nsIPropertyBag2> sysInfo =
3083 do_GetService("@mozilla.org/system-info;1");
3084 NS_ENSURE_TRUE_VOID(sysInfo)do { if ((__builtin_expect(!!(!(sysInfo)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "sysInfo" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 3084); return; } } while (false)
;
3085 sysInfo->GetPropertyAsACString(u"arch"_ns, arch);
3086
3087 time_t now;
3088 time(&now);
3089 char date[sizeof "YYYY-MM-DDThh:mm:ss.000Z"];
3090 strftime(date, sizeof date, "%FT%T.000Z", gmtime(&now));
3091
3092 NSID_TrimBracketsASCII pingId(uuid);
3093 constexpr auto pingType = "downgrade"_ns;
3094
3095 int32_t pos = aLastVersion.Find("_");
3096 if (pos == kNotFound) {
3097 return;
3098 }
3099
3100 const nsDependentCSubstring lastVersion = Substring(aLastVersion, 0, pos);
3101 const nsDependentCSubstring lastBuildId =
3102 Substring(aLastVersion, pos + 1, 14);
3103
3104 nsPrintfCString url("%s/submit/telemetry/%s/%s/%s/%s/%s/%s?v=%d",
3105 server.get(), PromiseFlatCStringTPromiseFlatString<char>(pingId).get(),
3106 pingType.get(), (const char*)gAppData->name,
3107 (const char*)gAppData->version, channel.get(),
3108 (const char*)gAppData->buildID,
3109 TELEMETRY_PING_FORMAT_VERSION4);
3110
3111 nsCOMPtr<nsIFile> pingFile;
3112 rv = NS_GetSpecialDirectory(XRE_USER_APP_DATA_DIR"UAppData", getter_AddRefs(pingFile));
3113 NS_ENSURE_SUCCESS_VOID(rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS_VOID(%s) failed with "
"result 0x%" "X" "%s%s%s", "rv", static_cast<uint32_t>
(__rv), name ? " (" : "", name ? name : "", name ? ")" : "");
NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 3113); return; } } while (false)
;
3114 rv = pingFile->Append(u"Pending Pings"_ns);
3115 NS_ENSURE_SUCCESS_VOID(rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS_VOID(%s) failed with "
"result 0x%" "X" "%s%s%s", "rv", static_cast<uint32_t>
(__rv), name ? " (" : "", name ? name : "", name ? ")" : "");
NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 3115); return; } } while (false)
;
3116 rv = pingFile->Create(nsIFile::DIRECTORY_TYPE, 0755);
3117 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0))) && rv != NS_ERROR_FILE_ALREADY_EXISTS) {
3118 return;
3119 }
3120 rv = pingFile->Append(NS_ConvertUTF8toUTF16(pingId));
3121 NS_ENSURE_SUCCESS_VOID(rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS_VOID(%s) failed with "
"result 0x%" "X" "%s%s%s", "rv", static_cast<uint32_t>
(__rv), name ? " (" : "", name ? name : "", name ? ")" : "");
NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 3121); return; } } while (false)
;
3122
3123 nsCOMPtr<nsIFile> pingSender;
3124 rv = NS_GetSpecialDirectory(NS_GRE_BIN_DIR"GreBinD", getter_AddRefs(pingSender));
3125 NS_ENSURE_SUCCESS_VOID(rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS_VOID(%s) failed with "
"result 0x%" "X" "%s%s%s", "rv", static_cast<uint32_t>
(__rv), name ? " (" : "", name ? name : "", name ? ")" : "");
NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 3125); return; } } while (false)
;
3126# ifdef XP_WIN
3127 pingSender->Append(u"pingsender.exe"_ns);
3128# else
3129 pingSender->Append(u"pingsender"_ns);
3130# endif
3131
3132 bool exists;
3133 rv = pingSender->Exists(&exists);
3134 NS_ENSURE_SUCCESS_VOID(rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS_VOID(%s) failed with "
"result 0x%" "X" "%s%s%s", "rv", static_cast<uint32_t>
(__rv), name ? " (" : "", name ? name : "", name ? ")" : "");
NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 3134); return; } } while (false)
;
3135 if (!exists) {
3136 return;
3137 }
3138
3139 FILE* file;
3140 rv = pingFile->OpenANSIFileDesc("w", &file);
3141 NS_ENSURE_SUCCESS_VOID(rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS_VOID(%s) failed with "
"result 0x%" "X" "%s%s%s", "rv", static_cast<uint32_t>
(__rv), name ? " (" : "", name ? name : "", name ? ")" : "");
NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 3141); return; } } while (false)
;
3142
3143 JSONWriter w(MakeUnique<FileWriteFunc>(file));
3144 w.Start();
3145 {
3146 w.StringProperty("type",
3147 Span<const char>(pingType.Data(), pingType.Length()));
3148 w.StringProperty("id", PromiseFlatCStringTPromiseFlatString<char>(pingId));
3149 w.StringProperty("creationDate", MakeStringSpan(date));
3150 w.IntProperty("version", TELEMETRY_PING_FORMAT_VERSION4);
3151 w.StringProperty("clientId", clientId);
3152 w.StartObjectProperty("application");
3153 {
3154 w.StringProperty("architecture", arch);
3155 w.StringProperty(
3156 "buildId",
3157 MakeStringSpan(static_cast<const char*>(gAppData->buildID)));
3158 w.StringProperty(
3159 "name", MakeStringSpan(static_cast<const char*>(gAppData->name)));
3160 w.StringProperty(
3161 "version",
3162 MakeStringSpan(static_cast<const char*>(gAppData->version)));
3163 w.StringProperty("displayVersion",
3164 MOZ_STRINGIFY(MOZ_APP_VERSION_DISPLAY)"128.0a1");
3165 w.StringProperty(
3166 "vendor", MakeStringSpan(static_cast<const char*>(gAppData->vendor)));
3167 w.StringProperty("platformVersion", gToolkitVersion);
3168# ifdef TARGET_XPCOM_ABI"x86_64-gcc3"
3169 w.StringProperty("xpcomAbi", TARGET_XPCOM_ABI"x86_64-gcc3");
3170# else
3171 w.StringProperty("xpcomAbi", "unknown");
3172# endif
3173 w.StringProperty("channel", channel);
3174 }
3175 w.EndObject();
3176 w.StartObjectProperty("payload");
3177 {
3178 w.StringProperty("lastVersion", PromiseFlatCStringTPromiseFlatString<char>(lastVersion));
3179 w.StringProperty("lastBuildId", PromiseFlatCStringTPromiseFlatString<char>(lastBuildId));
3180 w.BoolProperty("hasSync", aHasSync);
3181 w.IntProperty("button", aButton);
3182 }
3183 w.EndObject();
3184 }
3185 w.End();
3186
3187 fclose(file);
3188
3189 PathString filePath = pingFile->NativePath();
3190 const filesystem::Path::value_type* args[2];
3191# ifdef XP_WIN
3192 nsString urlw = NS_ConvertUTF8toUTF16(url);
3193 args[0] = urlw.get();
3194# else
3195 args[0] = url.get();
3196# endif
3197 args[1] = filePath.get();
3198
3199 nsCOMPtr<nsIProcess> process =
3200 do_CreateInstance("@mozilla.org/process/util;1");
3201 NS_ENSURE_TRUE_VOID(process)do { if ((__builtin_expect(!!(!(process)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "process" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 3201); return; } } while (false)
;
3202 process->Init(pingSender);
3203 process->SetStartHidden(true);
3204 process->SetNoShell(true);
3205
3206# ifdef XP_WIN
3207 process->Runw(false, args, 2);
3208# else
3209 process->Run(false, args, 2);
3210# endif
3211}
3212
3213static const char kProfileDowngradeURL[] =
3214 "chrome://mozapps/content/profile/profileDowngrade.xhtml";
3215
3216static ReturnAbortOnError CheckDowngrade(nsIFile* aProfileDir,
3217 nsINativeAppSupport* aNative,
3218 nsIToolkitProfileService* aProfileSvc,
3219 const nsCString& aLastVersion) {
3220 int32_t result = 0;
3221 nsresult rv;
3222
3223 {
3224 if (gfxPlatform::IsHeadless()) {
3225 // TODO: make a way to turn off all dialogs when headless.
3226 Output(true,
3227 "This profile was last used with a newer version of this "
3228 "application. Please create a new profile.\n");
3229 return NS_ERROR_ABORT;
3230 }
3231
3232 ScopedXPCOMStartup xpcom;
3233 rv = xpcom.Initialize();
3234 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 3234); return rv; } } while (false)
;
3235
3236 rv = xpcom.SetWindowCreator(aNative);
3237 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 3237); return rv; } } while (false)
;
3238
3239 { // extra scoping is needed so we release these components before xpcom
3240 // shutdown
3241 bool hasSync = false;
3242 nsCOMPtr<nsIPrefService> prefSvc =
3243 do_GetService("@mozilla.org/preferences-service;1");
3244 NS_ENSURE_TRUE(prefSvc, rv)do { if ((__builtin_expect(!!(!(prefSvc)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "prefSvc" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 3244); return rv; } } while (false)
;
3245
3246 nsCOMPtr<nsIFile> prefsFile;
3247 rv = aProfileDir->Clone(getter_AddRefs(prefsFile));
3248 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 3248); return rv; } } while (false)
;
3249
3250 rv = prefsFile->Append(u"prefs.js"_ns);
3251 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 3251); return rv; } } while (false)
;
3252
3253 rv = prefSvc->ReadUserPrefsFromFile(prefsFile);
3254 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
3255 nsCOMPtr<nsIPrefBranch> prefBranch = do_QueryInterface(prefSvc);
3256
3257 rv = prefBranch->PrefHasUserValue("services.sync.username", &hasSync);
3258 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 3258); return rv; } } while (false)
;
3259 }
3260
3261 nsCOMPtr<nsIWindowWatcher> windowWatcher =
3262 do_GetService(NS_WINDOWWATCHER_CONTRACTID"@mozilla.org/embedcomp/window-watcher;1");
3263 NS_ENSURE_TRUE(windowWatcher, NS_ERROR_ABORT)do { if ((__builtin_expect(!!(!(windowWatcher)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "windowWatcher" ") failed"
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 3263); return NS_ERROR_ABORT; } } while (false)
;
3264
3265 nsCOMPtr<nsIAppStartup> appStartup(components::AppStartup::Service());
3266 NS_ENSURE_TRUE(appStartup, NS_ERROR_FAILURE)do { if ((__builtin_expect(!!(!(appStartup)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "appStartup" ") failed",
nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 3266); return NS_ERROR_FAILURE; } } while (false)
;
3267
3268 nsCOMPtr<nsIDialogParamBlock> paramBlock =
3269 do_CreateInstance(NS_DIALOGPARAMBLOCK_CONTRACTID"@mozilla.org/embedcomp/dialogparam;1");
3270 NS_ENSURE_TRUE(paramBlock, NS_ERROR_ABORT)do { if ((__builtin_expect(!!(!(paramBlock)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "paramBlock" ") failed",
nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 3270); return NS_ERROR_ABORT; } } while (false)
;
3271
3272 uint8_t flags = 0;
3273 if (hasSync) {
3274 flags |= nsIToolkitProfileService::hasSync;
3275 }
3276
3277 paramBlock->SetInt(0, flags);
3278
3279 nsAutoCString features("centerscreen,chrome,modal,titlebar");
3280 // If we're launching a private browsing window make sure to set that
3281 // feature for the Profile Manager window as well, so it groups correctly
3282 // on the Windows taskbar.
3283 if (CheckArgExists("private-window") == ARG_FOUND) {
3284 features.AppendLiteral(",private");
3285 }
3286 nsCOMPtr<mozIDOMWindowProxy> newWindow;
3287 rv = windowWatcher->OpenWindow(
3288 nullptr, nsDependentCString(kProfileDowngradeURL), "_blank"_ns,
3289 features, paramBlock, getter_AddRefs(newWindow));
3290 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 3290); return rv; } } while (false)
;
3291
3292 paramBlock->GetInt(1, &result);
3293
3294 SubmitDowngradeTelemetry(aLastVersion, hasSync, result);
3295 }
3296 }
3297
3298 if (result == nsIToolkitProfileService::createNewProfile) {
3299 // Create a new profile and start it.
3300 nsCString profileName;
3301 profileName.AssignLiteral("default");
3302# ifdef MOZ_DEDICATED_PROFILES1
3303 profileName.Append("-" MOZ_STRINGIFY(MOZ_UPDATE_CHANNEL)"default");
3304# endif
3305 nsCOMPtr<nsIToolkitProfile> newProfile;
3306 rv = aProfileSvc->CreateUniqueProfile(nullptr, profileName,
3307 getter_AddRefs(newProfile));
3308 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 3308); return rv; } } while (false)
;
3309 rv = aProfileSvc->SetDefaultProfile(newProfile);
3310 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 3310); return rv; } } while (false)
;
3311 rv = aProfileSvc->Flush();
3312 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 3312); return rv; } } while (false)
;
3313
3314 nsCOMPtr<nsIFile> profD, profLD;
3315 rv = newProfile->GetRootDir(getter_AddRefs(profD));
3316 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 3316); return rv; } } while (false)
;
3317 rv = newProfile->GetLocalDir(getter_AddRefs(profLD));
3318 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 3318); return rv; } } while (false)
;
3319
3320 SaveFileToEnv("XRE_PROFILE_PATH", profD);
3321 SaveFileToEnv("XRE_PROFILE_LOCAL_PATH", profLD);
3322
3323 return LaunchChild(false, true);
3324 }
3325
3326 // Cancel
3327 return NS_ERROR_ABORT;
3328}
3329#endif
3330
3331/**
3332 * Extracts the various parts of a compatibility version string.
3333 *
3334 * Compatibility versions are of the form
3335 * "<appversion>_<appbuildid>/<platformbuildid>". The toolkit version comparator
3336 * can only handle 32-bit numbers and in the normal case build IDs are larger
3337 * than this. So if the build ID is numeric we split it into two version parts.
3338 */
3339static void ExtractCompatVersionInfo(const nsACString& aCompatVersion,
3340 nsACString& aAppVersion,
3341 nsACString& aAppBuildID) {
3342 int32_t underscorePos = aCompatVersion.FindChar('_');
3343 int32_t slashPos = aCompatVersion.FindChar('/');
3344
3345 if (underscorePos == kNotFound || slashPos == kNotFound ||
3346 slashPos < underscorePos) {
3347 NS_WARNING(NS_DebugBreak(NS_DEBUG_WARNING, "compatibility.ini Version string does not match the expected format."
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 3348)
3348 "compatibility.ini Version string does not match the expected format.")NS_DebugBreak(NS_DEBUG_WARNING, "compatibility.ini Version string does not match the expected format."
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 3348)
;
3349
3350 // Fall back to just using the entire string as the version.
3351 aAppVersion = aCompatVersion;
3352 aAppBuildID.Truncate(0);
3353 return;
3354 }
3355
3356 aAppVersion = Substring(aCompatVersion, 0, underscorePos);
3357 aAppBuildID = Substring(aCompatVersion, underscorePos + 1,
3358 slashPos - (underscorePos + 1));
3359}
3360
3361/**
3362 * Compares the provided compatibility versions. Returns 0 if they match,
3363 * < 0 if the new version is considered an upgrade from the old version and
3364 * > 0 if the new version is considered a downgrade from the old version.
3365 */
3366int32_t CompareCompatVersions(const nsACString& aOldCompatVersion,
3367 const nsACString& aNewCompatVersion) {
3368 // Hardcode the case where the last run was in safe mode (Bug 1556612). We
3369 // cannot tell if this is a downgrade or not so just assume it isn't and let
3370 // the user proceed.
3371 if (aOldCompatVersion.EqualsLiteral("Safe Mode")) {
3372 return -1;
3373 }
3374
3375 // Extract the major version part from the version string and only use that
3376 // for version comparison.
3377 int32_t index = aOldCompatVersion.FindChar('.');
3378 const nsACString& oldMajorVersion = Substring(
3379 aOldCompatVersion, 0, index < 0 ? aOldCompatVersion.Length() : index);
3380 index = aNewCompatVersion.FindChar('.');
3381 const nsACString& newMajorVersion = Substring(
3382 aNewCompatVersion, 0, index < 0 ? aNewCompatVersion.Length() : index);
3383
3384 return CompareVersions(PromiseFlatCStringTPromiseFlatString<char>(oldMajorVersion).get(),
3385 PromiseFlatCStringTPromiseFlatString<char>(newMajorVersion).get());
3386}
3387
3388/**
3389 * Checks the compatibility.ini file to see if we have updated our application
3390 * or otherwise invalidated our caches. If the application has been updated,
3391 * we return false; otherwise, we return true.
3392 *
3393 * We also write the status of the caches (valid/invalid) into the return param
3394 * aCachesOK. The aCachesOK is always invalid if the application has been
3395 * updated.
3396 *
3397 * Finally, aIsDowngrade is set to true if the current application is older
3398 * than that previously used by the profile.
3399 */
3400static bool CheckCompatibility(nsIFile* aProfileDir, const nsCString& aVersion,
3401 const nsCString& aOSABI, nsIFile* aXULRunnerDir,
3402 nsIFile* aAppDir, nsIFile* aFlagFile,
3403 bool* aCachesOK, bool* aIsDowngrade,
3404 nsCString& aLastVersion) {
3405 *aCachesOK = false;
3406 *aIsDowngrade = false;
3407 gLastAppVersion.SetIsVoid(true);
3408 gLastAppBuildID.SetIsVoid(true);
3409
3410 nsCOMPtr<nsIFile> file;
3411 aProfileDir->Clone(getter_AddRefs(file));
3412 if (!file) return false;
3413 file->AppendNative(FILE_COMPATIBILITY_INFO"compatibility.ini"_ns);
3414
3415 nsINIParsernsINIParser_internal parser;
3416 nsresult rv = parser.Init(file);
3417 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return false;
3418
3419 rv = parser.GetString("Compatibility", "LastVersion", aLastVersion);
3420 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
3421 return false;
3422 }
3423
3424 if (!aLastVersion.Equals(aVersion)) {
3425 // The version is not the same. Whether it's a downgrade depends on an
3426 // actual comparison:
3427 *aIsDowngrade = 0 < CompareCompatVersions(aLastVersion, aVersion);
3428 ExtractCompatVersionInfo(aLastVersion, gLastAppVersion, gLastAppBuildID);
3429 return false;
3430 }
3431
3432 // If we get here, the version matched, but there may still be other
3433 // differences between us and the build that the profile last ran under.
3434
3435 gLastAppVersion.Assign(gAppData->version);
3436 gLastAppBuildID.Assign(gAppData->buildID);
3437
3438 nsAutoCString buf;
3439 rv = parser.GetString("Compatibility", "LastOSABI", buf);
3440 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0))) || !aOSABI.Equals(buf)) return false;
3441
3442 rv = parser.GetString("Compatibility", "LastPlatformDir", buf);
3443 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return false;
3444
3445 nsCOMPtr<nsIFile> lf;
3446 rv = NS_NewNativeLocalFile(""_ns, false, getter_AddRefs(lf));
3447 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return false;
3448
3449 rv = lf->SetPersistentDescriptor(buf);
3450 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return false;
3451
3452 bool eq;
3453 rv = lf->Equals(aXULRunnerDir, &eq);
3454 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0))) || !eq) return false;
3455
3456 if (aAppDir) {
3457 rv = parser.GetString("Compatibility", "LastAppDir", buf);
3458 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return false;
3459
3460 rv = NS_NewNativeLocalFile(""_ns, false, getter_AddRefs(lf));
3461 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return false;
3462
3463 rv = lf->SetPersistentDescriptor(buf);
3464 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return false;
3465
3466 rv = lf->Equals(aAppDir, &eq);
3467 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0))) || !eq) return false;
3468 }
3469
3470 // If we see this flag, caches are invalid.
3471 rv = parser.GetString("Compatibility", "InvalidateCaches", buf);
3472 *aCachesOK = (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0))) || !buf.EqualsLiteral("1"));
3473
3474 bool purgeCaches = false;
3475 if (aFlagFile && NS_SUCCEEDED(aFlagFile->Exists(&purgeCaches))((bool)(__builtin_expect(!!(!NS_FAILED_impl(aFlagFile->Exists
(&purgeCaches))), 1)))
&&
3476 purgeCaches) {
3477 *aCachesOK = false;
3478 }
3479
3480 return true;
3481}
3482
3483void BuildCompatVersion(const char* aAppVersion, const char* aAppBuildID,
3484 const char* aToolkitBuildID, nsACString& aBuf) {
3485 aBuf.Assign(aAppVersion);
3486 aBuf.Append('_');
3487 aBuf.Append(aAppBuildID);
3488 aBuf.Append('/');
3489 aBuf.Append(aToolkitBuildID);
3490}
3491
3492static void BuildVersion(nsCString& aBuf) {
3493 BuildCompatVersion(gAppData->version, gAppData->buildID, gToolkitBuildID,
3494 aBuf);
3495}
3496
3497static void WriteVersion(nsIFile* aProfileDir, const nsCString& aVersion,
3498 const nsCString& aOSABI, nsIFile* aXULRunnerDir,
3499 nsIFile* aAppDir, bool invalidateCache) {
3500 nsCOMPtr<nsIFile> file;
3501 aProfileDir->Clone(getter_AddRefs(file));
3502 if (!file) return;
3503 file->AppendNative(FILE_COMPATIBILITY_INFO"compatibility.ini"_ns);
3504
3505 nsAutoCString platformDir;
3506 Unused << aXULRunnerDir->GetPersistentDescriptor(platformDir);
3507
3508 nsAutoCString appDir;
3509 if (aAppDir) Unused << aAppDir->GetPersistentDescriptor(appDir);
3510
3511 PRFileDesc* fd;
3512 nsresult rv = file->OpenNSPRFileDesc(PR_WRONLY0x02 | PR_CREATE_FILE0x08 | PR_TRUNCATE0x20,
3513 0600, &fd);
3514 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
3515 NS_ERROR("could not create output stream")do { NS_DebugBreak(NS_DEBUG_ASSERTION, "could not create output stream"
, "Error", "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 3515); MOZ_PretendNoReturn(); } while (0)
;
3516 return;
3517 }
3518
3519 static const char kHeader[] = "[Compatibility]" NS_LINEBREAK"\012" "LastVersion=";
3520
3521 PR_Write(fd, kHeader, sizeof(kHeader) - 1);
3522 PR_Write(fd, aVersion.get(), aVersion.Length());
3523
3524 static const char kOSABIHeader[] = NS_LINEBREAK"\012" "LastOSABI=";
3525 PR_Write(fd, kOSABIHeader, sizeof(kOSABIHeader) - 1);
3526 PR_Write(fd, aOSABI.get(), aOSABI.Length());
3527
3528 static const char kPlatformDirHeader[] = NS_LINEBREAK"\012" "LastPlatformDir=";
3529
3530 PR_Write(fd, kPlatformDirHeader, sizeof(kPlatformDirHeader) - 1);
3531 PR_Write(fd, platformDir.get(), platformDir.Length());
3532
3533 static const char kAppDirHeader[] = NS_LINEBREAK"\012" "LastAppDir=";
3534 if (aAppDir) {
3535 PR_Write(fd, kAppDirHeader, sizeof(kAppDirHeader) - 1);
3536 PR_Write(fd, appDir.get(), appDir.Length());
3537 }
3538
3539 static const char kInvalidationHeader[] = NS_LINEBREAK"\012" "InvalidateCaches=1";
3540 if (invalidateCache)
3541 PR_Write(fd, kInvalidationHeader, sizeof(kInvalidationHeader) - 1);
3542
3543 static const char kNL[] = NS_LINEBREAK"\012";
3544 PR_Write(fd, kNL, sizeof(kNL) - 1);
3545
3546 PR_Close(fd);
3547}
3548
3549/**
3550 * Returns true if the startup cache file was successfully removed.
3551 * Returns false if file->Clone fails at any point (OOM) or if unable
3552 * to remove the startup cache file. Note in particular the return value
3553 * is unaffected by a failure to remove extensions.ini
3554 */
3555static bool RemoveComponentRegistries(nsIFile* aProfileDir,
3556 nsIFile* aLocalProfileDir,
3557 bool aRemoveEMFiles) {
3558 nsCOMPtr<nsIFile> file;
3559 aProfileDir->Clone(getter_AddRefs(file));
3560 if (!file) return false;
3561
3562 if (aRemoveEMFiles) {
3563 file->SetNativeLeafName("extensions.ini"_ns);
3564 file->Remove(false);
3565 }
3566
3567 aLocalProfileDir->Clone(getter_AddRefs(file));
3568 if (!file) return false;
3569
3570 file->AppendNative("startupCache"_ns);
3571 nsresult rv = file->Remove(true);
3572 return NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1))) || rv == NS_ERROR_FILE_NOT_FOUND;
3573}
3574
3575// When we first initialize the crash reporter we don't have a profile,
3576// so we set the minidump path to $TEMP. Once we have a profile,
3577// we set it to $PROFILE/minidumps, creating the directory
3578// if needed.
3579static void MakeOrSetMinidumpPath(nsIFile* profD) {
3580 nsCOMPtr<nsIFile> dumpD;
3581 profD->Clone(getter_AddRefs(dumpD));
3582
3583 if (dumpD) {
3584 bool fileExists;
3585 // XXX: do some more error checking here
3586 dumpD->Append(u"minidumps"_ns);
3587 dumpD->Exists(&fileExists);
3588 if (!fileExists) {
3589 nsresult rv = dumpD->Create(nsIFile::DIRECTORY_TYPE, 0700);
3590 NS_ENSURE_SUCCESS_VOID(rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS_VOID(%s) failed with "
"result 0x%" "X" "%s%s%s", "rv", static_cast<uint32_t>
(__rv), name ? " (" : "", name ? name : "", name ? ")" : "");
NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 3590); return; } } while (false)
;
3591 }
3592
3593 nsAutoString pathStr;
3594 if (NS_SUCCEEDED(dumpD->GetPath(pathStr))((bool)(__builtin_expect(!!(!NS_FAILED_impl(dumpD->GetPath
(pathStr))), 1)))
)
3595 CrashReporter::SetMinidumpPath(pathStr);
3596 }
3597}
3598
3599const XREAppData* gAppData = nullptr;
3600
3601/**
3602 * NSPR will search for the "nspr_use_zone_allocator" symbol throughout
3603 * the process and use it to determine whether the application defines its own
3604 * memory allocator or not.
3605 *
3606 * Since most applications (e.g. Firefox and Thunderbird) don't use any special
3607 * allocators and therefore don't define this symbol, NSPR must search the
3608 * entire process, which reduces startup performance.
3609 *
3610 * By defining the symbol here, we can avoid the wasted lookup and hopefully
3611 * improve startup performance.
3612 */
3613NS_VISIBILITY_DEFAULT__attribute__((visibility("default"))) PRBool nspr_use_zone_allocator = PR_FALSE0;
3614
3615#ifdef CAIRO_HAS_DWRITE_FONT
3616
3617# include <dwrite.h>
3618# include "nsWindowsHelpers.h"
3619
3620# ifdef DEBUG_DWRITE_STARTUP
3621
3622# define LOGREGISTRY(msg) LogRegistryEvent(msg)
3623
3624// for use when monitoring process
3625static void LogRegistryEvent(const wchar_t* msg) {
3626 HKEY dummyKey;
3627 HRESULT hr;
3628 wchar_t buf[512];
3629
3630 wsprintf(buf, L" log %s", msg);
3631 hr = RegOpenKeyEx(HKEY_LOCAL_MACHINE, buf, 0, KEY_READ, &dummyKey);
3632 if (SUCCEEDED(hr)) {
3633 RegCloseKey(dummyKey);
3634 }
3635}
3636# else
3637
3638# define LOGREGISTRY(msg)
3639
3640# endif
3641
3642static DWORD WINAPI InitDwriteBG(LPVOID lpdwThreadParam) {
3643 SetThreadPriority(GetCurrentThread(), THREAD_MODE_BACKGROUND_BEGIN);
3644 LOGREGISTRY(L"loading dwrite.dll");
3645 HMODULE dwdll = LoadLibrarySystem32(L"dwrite.dll");
3646 if (dwdll) {
3647 decltype(DWriteCreateFactory)* createDWriteFactory =
3648 (decltype(DWriteCreateFactory)*)GetProcAddress(dwdll,
3649 "DWriteCreateFactory");
3650 if (createDWriteFactory) {
3651 LOGREGISTRY(L"creating dwrite factory");
3652 IDWriteFactory* factory;
3653 HRESULT hr = createDWriteFactory(DWRITE_FACTORY_TYPE_SHARED,
3654 __uuidof(IDWriteFactory),
3655 reinterpret_cast<IUnknown**>(&factory));
3656 if (SUCCEEDED(hr)) {
3657 LOGREGISTRY(L"dwrite factory done");
3658 factory->Release();
3659 LOGREGISTRY(L"freed factory");
3660 } else {
3661 LOGREGISTRY(L"failed to create factory");
3662 }
3663 }
3664 }
3665 SetThreadPriority(GetCurrentThread(), THREAD_MODE_BACKGROUND_END);
3666 return 0;
3667}
3668#endif
3669
3670#include "GeckoProfiler.h"
3671#include "ProfilerControl.h"
3672
3673// Encapsulates startup and shutdown state for XRE_main
3674class XREMain {
3675 public:
3676 XREMain() = default;
3677
3678 ~XREMain() {
3679 mScopedXPCOM = nullptr;
3680 mAppData = nullptr;
3681 }
3682
3683 int XRE_main(int argc, char* argv[], const BootstrapConfig& aConfig);
3684 int XRE_mainInit(bool* aExitFlag);
3685 int XRE_mainStartup(bool* aExitFlag);
3686 nsresult XRE_mainRun();
3687
3688 bool CheckLastStartupWasCrash();
3689
3690 nsCOMPtr<nsINativeAppSupport> mNativeApp;
3691 RefPtr<nsToolkitProfileService> mProfileSvc;
3692 nsCOMPtr<nsIFile> mProfD;
3693 nsCOMPtr<nsIFile> mProfLD;
3694 nsCOMPtr<nsIProfileLock> mProfileLock;
3695#if defined(MOZ_HAS_REMOTE1)
3696 RefPtr<nsRemoteService> mRemoteService;
3697#endif
3698
3699 UniquePtr<ScopedXPCOMStartup> mScopedXPCOM;
3700 UniquePtr<XREAppData> mAppData;
3701
3702 nsXREDirProvider mDirProvider;
3703
3704#ifdef MOZ_WIDGET_GTK1
3705 nsAutoCString mXDGActivationToken;
3706 nsAutoCString mDesktopStartupID;
3707#endif
3708
3709 bool mStartOffline = false;
3710#if defined(MOZ_HAS_REMOTE1)
3711 bool mDisableRemoteClient = false;
3712 bool mDisableRemoteServer = false;
3713#endif
3714};
3715
3716#if defined(XP_UNIX1) && !defined(ANDROID)
3717static SmprintfPointer FormatUid(uid_t aId) {
3718 if (const auto pw = getpwuid(aId)) {
3719 return mozilla::Smprintf("%s", pw->pw_name);
3720 }
3721 return mozilla::Smprintf("uid %d", static_cast<int>(aId));
3722}
3723
3724// Bug 1323302: refuse to run under sudo or similar.
3725static bool CheckForUserMismatch() {
3726 static char const* const kVars[] = {
3727 "HOME",
3728# ifdef MOZ_WIDGET_GTK1
3729 "XDG_RUNTIME_DIR",
3730# endif
3731# ifdef MOZ_X111
3732 "XAUTHORITY",
3733# endif
3734 };
3735
3736 const uid_t euid = geteuid();
3737 if (euid != 0) {
3738 // On Linux it's possible to have superuser capabilities with a
3739 // nonzero uid, but anyone who knows enough to make that happen
3740 // probably knows enough to debug the resulting problems.
3741 // Otherwise, a non-root user can't cause the problems we're
3742 // concerned about.
3743 return false;
3744 }
3745
3746 for (const auto var : kVars) {
3747 if (const auto path = PR_GetEnv(var)) {
3748 struct stat st;
3749 if (stat(path, &st) == 0) {
3750 if (st.st_uid != euid) {
3751 const auto owner = FormatUid(st.st_uid);
3752 Output(true,
3753 "Running " MOZ_APP_DISPLAYNAME"Nightly"
3754 " as root in a regular"
3755 " user's session is not supported. ($%s is %s which is"
3756 " owned by %s.)\n",
3757 var, path, owner.get());
3758 return true;
3759 }
3760 }
3761 }
3762 }
3763 return false;
3764}
3765#else // !XP_UNIX || ANDROID
3766static bool CheckForUserMismatch() { return false; }
3767#endif
3768
3769void mozilla::startup::IncreaseDescriptorLimits() {
3770#ifdef XP_UNIX1
3771 // Increase the fd limit to accomodate IPC resources like shared memory.
3772 // See also the Darwin case in config/external/nspr/pr/moz.build
3773 static const rlim_t kFDs = 4096;
3774 struct rlimit rlim;
3775
3776 if (getrlimit(RLIMIT_NOFILERLIMIT_NOFILE, &rlim) != 0) {
3777 Output(false, "getrlimit: %s\n", strerror(errno(*__errno_location ())));
3778 return;
3779 }
3780 // Don't decrease the limit if it's already high enough, but don't
3781 // try to go over the hard limit. (RLIM_INFINITY isn't required to
3782 // be the numerically largest rlim_t, so don't assume that.)
3783 if (rlim.rlim_cur != RLIM_INFINITY((__rlim_t) -1) && rlim.rlim_cur < kFDs &&
3784 rlim.rlim_cur < rlim.rlim_max) {
3785 if (rlim.rlim_max != RLIM_INFINITY((__rlim_t) -1) && rlim.rlim_max < kFDs) {
3786 rlim.rlim_cur = rlim.rlim_max;
3787 } else {
3788 rlim.rlim_cur = kFDs;
3789 }
3790 if (setrlimit(RLIMIT_NOFILERLIMIT_NOFILE, &rlim) != 0) {
3791 Output(false, "setrlimit: %s\n", strerror(errno(*__errno_location ())));
3792 }
3793 }
3794#endif
3795}
3796
3797#ifdef XP_WIN
3798
3799static uint32_t GetMicrocodeVersionByVendor(HKEY key, DWORD upper,
3800 DWORD lower) {
3801 WCHAR data[13]; // The CPUID vendor string is 12 characters long plus null
3802 DWORD len = sizeof(data);
3803 DWORD vtype;
3804
3805 if (RegQueryValueExW(key, L"VendorIdentifier", nullptr, &vtype,
3806 reinterpret_cast<LPBYTE>(data), &len) == ERROR_SUCCESS) {
3807 if (wcscmp(L"GenuineIntel", data) == 0) {
3808 // Intel reports the microcode version in the upper 32 bits of the MSR
3809 return upper;
3810 }
3811
3812 if (wcscmp(L"AuthenticAMD", data) == 0) {
3813 // AMD reports the microcode version in the lower 32 bits of the MSR
3814 return lower;
3815 }
3816
3817 // Unknown CPU vendor, return whatever half is non-zero
3818 return lower ? lower : upper;
3819 }
3820
3821 return 0; // No clue
3822}
3823
3824#endif // XP_WIN
3825
3826static void MaybeAddCPUMicrocodeCrashAnnotation() {
3827#ifdef XP_WIN
3828 // Add CPU microcode version to the crash report as "CPUMicrocodeVersion".
3829 // It feels like this code may belong in nsSystemInfo instead.
3830 uint32_t cpuUpdateRevision = 0;
3831 HKEY key;
3832 static const WCHAR keyName[] =
3833 L"HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0";
3834
3835 if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, keyName, 0, KEY_QUERY_VALUE, &key) ==
3836 ERROR_SUCCESS) {
3837 DWORD updateRevision[2];
3838 DWORD len = sizeof(updateRevision);
3839 DWORD vtype;
3840
3841 // Windows 7 uses "Update Signature", 8 uses "Update Revision".
3842 // For AMD CPUs, "CurrentPatchLevel" is sometimes used.
3843 // Take the first one we find.
3844 LPCWSTR choices[] = {L"Update Signature", L"Update Revision",
3845 L"CurrentPatchLevel"};
3846 for (const auto& oneChoice : choices) {
3847 if (RegQueryValueExW(key, oneChoice, nullptr, &vtype,
3848 reinterpret_cast<LPBYTE>(updateRevision),
3849 &len) == ERROR_SUCCESS) {
3850 if (vtype == REG_BINARY && len == sizeof(updateRevision)) {
3851 cpuUpdateRevision = GetMicrocodeVersionByVendor(
3852 key, updateRevision[1], updateRevision[0]);
3853 break;
3854 }
3855
3856 if (vtype == REG_DWORD && len == sizeof(updateRevision[0])) {
3857 cpuUpdateRevision = static_cast<int>(updateRevision[0]);
3858 break;
3859 }
3860 }
3861 }
3862 }
3863
3864 if (cpuUpdateRevision > 0) {
3865 CrashReporter::RecordAnnotationNSCString(
3866 CrashReporter::Annotation::CPUMicrocodeVersion,
3867 nsPrintfCString("0x%" PRIx32"x", cpuUpdateRevision));
3868 }
3869#endif
3870}
3871
3872#if defined(MOZ_BACKGROUNDTASKS1)
3873static void SetupConsoleForBackgroundTask(
3874 const nsCString& aBackgroundTaskName) {
3875 // We do not suppress output on Windows because:
3876 // 1. Background task subprocesses launched via LaunchApp() does not attach to
3877 // the console.
3878 // 2. Suppressing output intermittently causes failures on when running
3879 // multiple tasks (see bug 1831631)
3880# ifndef XP_WIN
3881 if (BackgroundTasks::IsNoOutputTaskName(aBackgroundTaskName) &&
3882 !CheckArg("attach-console") &&
3883 !EnvHasValue("MOZ_BACKGROUNDTASKS_IGNORE_NO_OUTPUT")) {
3884 // Suppress output, somewhat crudely. We need to suppress stderr as well
3885 // as stdout because assertions, of which there are many, write to stderr.
3886 Unused << freopen("/dev/null", "w", stdoutstdout);
3887 Unused << freopen("/dev/null", "w", stderrstderr);
3888 return;
3889 }
3890# endif
3891 printf_stderr("*** You are running in background task mode. ***\n");
3892}
3893#endif
3894
3895/*
3896 * XRE_mainInit - Initial setup and command line parameter processing.
3897 * Main() will exit early if either return value != 0 or if aExitFlag is
3898 * true.
3899 */
3900int XREMain::XRE_mainInit(bool* aExitFlag) {
3901 if (!aExitFlag) return 1;
3902 *aExitFlag = false;
3903
3904 atexit(UnexpectedExit);
3905 auto expectedShutdown = mozilla::MakeScopeExit([&] { MozExpectedExit(); });
3906
3907 StartupTimeline::Record(StartupTimeline::MAIN);
3908
3909 if (CheckForUserMismatch()) {
3910 return 1;
3911 }
3912
3913#ifdef XP_MACOSX
3914 mozilla::MacAutoreleasePool pool;
3915
3916 DisableAppNap();
3917#endif
3918
3919#ifdef MOZ_BACKGROUNDTASKS1
3920 Maybe<nsCString> backgroundTask = Nothing();
3921 const char* backgroundTaskName = nullptr;
3922 if (ARG_FOUND ==
3923 CheckArg("backgroundtask", &backgroundTaskName, CheckArgFlag::None)) {
3924 backgroundTask = Some(backgroundTaskName);
3925
3926 SetupConsoleForBackgroundTask(backgroundTask.ref());
3927 }
3928
3929 BackgroundTasks::Init(backgroundTask);
3930#endif
3931
3932#ifndef ANDROID
3933 if (PR_GetEnv("MOZ_RUN_GTEST")
3934# ifdef FUZZING
3935 || PR_GetEnv("FUZZER")
3936# endif
3937# ifdef MOZ_BACKGROUNDTASKS1
3938 || BackgroundTasks::IsBackgroundTaskMode()
3939# endif
3940 ) {
3941 // Enable headless mode and assert that it worked, since gfxPlatform
3942 // uses a static bool set after the first call to `IsHeadless`.
3943 // Note: Android gtests seem to require an Activity and fail to start
3944 // with headless mode enabled.
3945 PR_SetEnv("MOZ_HEADLESS=1");
3946 MOZ_ASSERT(gfxPlatform::IsHeadless())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(gfxPlatform::IsHeadless())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(gfxPlatform::IsHeadless())))
, 0))) { do { } while (false); MOZ_ReportAssertionFailure("gfxPlatform::IsHeadless()"
, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 3946); AnnotateMozCrashReason("MOZ_ASSERT" "(" "gfxPlatform::IsHeadless()"
")"); do { *((volatile int*)__null) = 3946; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3947 }
3948#endif // ANDROID
3949
3950 if (PR_GetEnv("MOZ_CHAOSMODE")) {
3951 ChaosFeature feature = ChaosFeature::Any;
3952 long featureInt = strtol(PR_GetEnv("MOZ_CHAOSMODE"), nullptr, 16);
3953 if (featureInt) {
3954 // NOTE: MOZ_CHAOSMODE=0 or a non-hex value maps to Any feature.
3955 feature = static_cast<ChaosFeature>(featureInt);
3956 }
3957 ChaosMode::SetChaosFeature(feature);
3958 }
3959
3960 if (CheckArgExists("fxr")) {
3961 gFxREmbedded = true;
3962 }
3963
3964 if (ChaosMode::isActive(ChaosFeature::Any)) {
3965 printf_stderr(
3966 "*** You are running in chaos test mode. See ChaosMode.h. ***\n");
3967 }
3968
3969 if (CheckArg("headless") || CheckArgExists("screenshot")) {
3970 PR_SetEnv("MOZ_HEADLESS=1");
3971 }
3972
3973 if (gfxPlatform::IsHeadless()) {
3974#if defined(XP_WIN) || defined(MOZ_WIDGET_GTK1) || defined(XP_MACOSX)
3975 printf_stderr("*** You are running in headless mode.\n");
3976#else
3977 Output(
3978 true,
3979 "Error: headless mode is not currently supported on this platform.\n");
3980 return 1;
3981#endif
3982
3983#ifdef XP_MACOSX
3984 // To avoid taking focus when running in headless mode immediately
3985 // transition Firefox to a background application.
3986 ProcessSerialNumber psn = {0, kCurrentProcess};
3987 OSStatus transformStatus =
3988 TransformProcessType(&psn, kProcessTransformToBackgroundApplication);
3989 if (transformStatus != noErr) {
3990 NS_ERROR("Failed to make process a background application.")do { NS_DebugBreak(NS_DEBUG_ASSERTION, "Failed to make process a background application."
, "Error", "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 3990); MOZ_PretendNoReturn(); } while (0)
;
3991 return 1;
3992 }
3993#endif
3994 }
3995
3996 gKioskMode = CheckArg("kiosk", nullptr, CheckArgFlag::None);
3997 const char* kioskMonitorNumber = nullptr;
3998 if (CheckArg("kiosk-monitor", &kioskMonitorNumber, CheckArgFlag::None)) {
3999 gKioskMode = true;
4000 gKioskMonitor = atoi(kioskMonitorNumber);
4001 }
4002
4003 gAllowContentAnalysisArgPresent =
4004 CheckArg("allow-content-analysis", nullptr, CheckArgFlag::RemoveArg) ==
4005 ARG_FOUND;
4006
4007 nsresult rv;
4008 ArgResult ar;
4009
4010#ifdef DEBUG1
4011 if (PR_GetEnv("XRE_MAIN_BREAK")) NS_BREAK()do { NS_DebugBreak(NS_DEBUG_BREAK, nullptr, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 4011); MOZ_PretendNoReturn(); } while (0)
;
4012#endif
4013
4014 mozilla::startup::IncreaseDescriptorLimits();
4015
4016 SetupErrorHandling(gArgv[0]);
4017
4018#ifdef CAIRO_HAS_DWRITE_FONT
4019 {
4020 // Bug 602792 - when DWriteCreateFactory is called the dwrite client dll
4021 // starts the FntCache service if it isn't already running (it's set
4022 // to manual startup by default in Windows 7 RTM). Subsequent DirectWrite
4023 // calls cause the IDWriteFactory object to communicate with the FntCache
4024 // service with a timeout; if there's no response after the timeout, the
4025 // DirectWrite client library will assume the service isn't around and do
4026 // manual font file I/O on _all_ system fonts. To avoid this, load the
4027 // dwrite library and create a factory as early as possible so that the
4028 // FntCache service is ready by the time it's needed.
4029
4030 CreateThread(nullptr, 0, &InitDwriteBG, nullptr, 0, nullptr);
4031 }
4032#endif
4033
4034#ifdef XP_UNIX1
4035 const char* home = PR_GetEnv("HOME");
4036 if (!home || !*home) {
4037 struct passwd* pw = getpwuid(geteuid());
4038 if (!pw || !pw->pw_dir) {
4039 Output(true, "Could not determine HOME directory");
4040 return 1;
4041 }
4042 SaveWordToEnv("HOME", nsDependentCString(pw->pw_dir));
4043 }
4044#endif
4045
4046#ifdef MOZ_ACCESSIBILITY_ATK1
4047 // Suppress atk-bridge init at startup, until mozilla accessibility is
4048 // initialized. This works after gnome 2.24.2.
4049 SaveToEnv("NO_AT_BRIDGE=1");
4050#endif
4051
4052 // Check for application.ini overrides
4053 const char* override = nullptr;
4054 ar = CheckArg("override", &override);
4055 if (ar == ARG_BAD) {
4056 Output(true, "Incorrect number of arguments passed to --override");
4057 return 1;
4058 }
4059 if (ar == ARG_FOUND) {
4060 nsCOMPtr<nsIFile> overrideLF;
4061 rv = XRE_GetFileFromPath(override, getter_AddRefs(overrideLF));
4062 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
4063 Output(true, "Error: unrecognized override.ini path.\n");
4064 return 1;
4065 }
4066
4067 rv = XRE_ParseAppData(overrideLF, *mAppData);
4068 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
4069 Output(true, "Couldn't read override.ini");
4070 return 1;
4071 }
4072 }
4073
4074 // Check sanity and correctness of app data.
4075
4076 if (!mAppData->name) {
4077 Output(true, "Error: App:Name not specified in application.ini\n");
4078 return 1;
4079 }
4080 if (!mAppData->buildID) {
4081 Output(true, "Error: App:BuildID not specified in application.ini\n");
4082 return 1;
4083 }
4084
4085 // XXX Originally ScopedLogging was here? Now it's in XRE_main above
4086 // XRE_mainInit.
4087
4088 if (!mAppData->minVersion) {
4089 Output(true, "Error: Gecko:MinVersion not specified in application.ini\n");
4090 return 1;
4091 }
4092
4093 if (!mAppData->maxVersion) {
4094 // If no maxVersion is specified, we assume the app is only compatible
4095 // with the initial preview release. Do not increment this number ever!
4096 mAppData->maxVersion = "1.*";
4097 }
4098
4099 if (mozilla::Version(mAppData->minVersion) > gToolkitVersion ||
4100 mozilla::Version(mAppData->maxVersion) < gToolkitVersion) {
4101 Output(true,
4102 "Error: Platform version '%s' is not compatible with\n"
4103 "minVersion >= %s\nmaxVersion <= %s\n",
4104 (const char*)gToolkitVersion, (const char*)mAppData->minVersion,
4105 (const char*)mAppData->maxVersion);
4106 return 1;
4107 }
4108
4109 rv = mDirProvider.Initialize(mAppData->directory, mAppData->xreDirectory);
4110 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return 1;
4111
4112 if (EnvHasValue("MOZ_CRASHREPORTER")) {
4113 mAppData->flags |= NS_XRE_ENABLE_CRASH_REPORTER(1 << 3);
4114 }
4115
4116 nsCOMPtr<nsIFile> xreBinDirectory;
4117 xreBinDirectory = mDirProvider.GetGREBinDir();
4118
4119 if ((mAppData->flags & NS_XRE_ENABLE_CRASH_REPORTER(1 << 3)) &&
4120 NS_SUCCEEDED(CrashReporter::SetExceptionHandler(xreBinDirectory))((bool)(__builtin_expect(!!(!NS_FAILED_impl(CrashReporter::SetExceptionHandler
(xreBinDirectory))), 1)))
) {
4121 nsCOMPtr<nsIFile> file;
4122 rv = nsXREDirProvider::GetUserAppDataDirectory(getter_AddRefs(file));
4123 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
4124 CrashReporter::SetUserAppDataDirectory(file);
4125 }
4126 if (mAppData->crashReporterURL) {
4127 CrashReporter::SetServerURL(
4128 nsDependentCString(mAppData->crashReporterURL));
4129 }
4130
4131 // We overwrite this once we finish starting up.
4132 CrashReporter::RecordAnnotationBool(CrashReporter::Annotation::StartupCrash,
4133 true);
4134
4135 // pass some basic info from the app data
4136 if (mAppData->vendor) {
4137 CrashReporter::RecordAnnotationCString(CrashReporter::Annotation::Vendor,
4138 mAppData->vendor);
4139 }
4140 if (mAppData->name) {
4141 CrashReporter::RecordAnnotationCString(
4142 CrashReporter::Annotation::ProductName, mAppData->name);
4143 }
4144 if (mAppData->ID) {
4145 CrashReporter::RecordAnnotationCString(
4146 CrashReporter::Annotation::ProductID, mAppData->ID);
4147 }
4148 if (mAppData->version) {
4149 CrashReporter::RecordAnnotationCString(CrashReporter::Annotation::Version,
4150 mAppData->version);
4151 }
4152 if (mAppData->buildID) {
4153 CrashReporter::RecordAnnotationCString(CrashReporter::Annotation::BuildID,
4154 mAppData->buildID);
4155 }
4156
4157 nsDependentCString releaseChannel(MOZ_STRINGIFY(MOZ_UPDATE_CHANNEL)"default");
4158 CrashReporter::RecordAnnotationNSCString(
4159 CrashReporter::Annotation::ReleaseChannel, releaseChannel);
4160
4161#ifdef XP_WIN
4162 nsAutoString appInitDLLs;
4163 if (widget::WinUtils::GetAppInitDLLs(appInitDLLs)) {
4164 CrashReporter::RecordAnnotationNSString(
4165 CrashReporter::Annotation::AppInitDLLs, appInitDLLs);
4166 }
4167
4168 nsString packageFamilyName = widget::WinUtils::GetPackageFamilyName();
4169 if (StringBeginsWith(packageFamilyName, u"Mozilla."_ns) ||
4170 StringBeginsWith(packageFamilyName, u"MozillaCorporation."_ns)) {
4171 CrashReporter::RecordAnnotationNSCString(
4172 CrashReporter::Annotation::WindowsPackageFamilyName,
4173 NS_ConvertUTF16toUTF8(packageFamilyName));
4174 }
4175#endif
4176
4177 bool isBackgroundTaskMode = false;
4178#ifdef MOZ_BACKGROUNDTASKS1
4179 Maybe<nsCString> backgroundTasks = BackgroundTasks::GetBackgroundTasks();
4180 if (backgroundTasks.isSome()) {
4181 isBackgroundTaskMode = true;
4182 CrashReporter::RecordAnnotationNSCString(
4183 CrashReporter::Annotation::BackgroundTaskName, backgroundTasks.ref());
4184 }
4185#endif
4186 CrashReporter::RecordAnnotationBool(
4187 CrashReporter::Annotation::BackgroundTaskMode, isBackgroundTaskMode);
4188
4189 CrashReporter::RecordAnnotationBool(CrashReporter::Annotation::HeadlessMode,
4190 gfxPlatform::IsHeadless());
4191
4192 CrashReporter::SetRestartArgs(gArgc, gArgv);
4193
4194 // annotate other data (user id etc)
4195 nsCOMPtr<nsIFile> userAppDataDir;
4196 if (NS_SUCCEEDED(mDirProvider.GetUserAppDataDirectory(((bool)(__builtin_expect(!!(!NS_FAILED_impl(mDirProvider.GetUserAppDataDirectory
( getter_AddRefs(userAppDataDir)))), 1)))
4197 getter_AddRefs(userAppDataDir)))((bool)(__builtin_expect(!!(!NS_FAILED_impl(mDirProvider.GetUserAppDataDirectory
( getter_AddRefs(userAppDataDir)))), 1)))
) {
4198 CrashReporter::SetupExtraData(userAppDataDir,
4199 nsDependentCString(mAppData->buildID));
4200
4201 // see if we have a crashreporter-override.ini in the application
4202 // directory
4203 nsCOMPtr<nsIFile> overrideini;
4204 if (NS_SUCCEEDED(((bool)(__builtin_expect(!!(!NS_FAILED_impl(mDirProvider.GetAppDir
()->Clone(getter_AddRefs(overrideini)))), 1)))
4205 mDirProvider.GetAppDir()->Clone(getter_AddRefs(overrideini)))((bool)(__builtin_expect(!!(!NS_FAILED_impl(mDirProvider.GetAppDir
()->Clone(getter_AddRefs(overrideini)))), 1)))
&&
4206 NS_SUCCEEDED(((bool)(__builtin_expect(!!(!NS_FAILED_impl(overrideini->AppendNative
("crashreporter-override.ini"_ns))), 1)))
4207 overrideini->AppendNative("crashreporter-override.ini"_ns))((bool)(__builtin_expect(!!(!NS_FAILED_impl(overrideini->AppendNative
("crashreporter-override.ini"_ns))), 1)))
) {
4208#ifdef XP_WIN
4209 nsAutoString overridePathW;
4210 overrideini->GetPath(overridePathW);
4211 NS_ConvertUTF16toUTF8 overridePath(overridePathW);
4212#else
4213 nsAutoCString overridePath;
4214 overrideini->GetNativePath(overridePath);
4215#endif
4216
4217 SaveWordToEnv("MOZ_CRASHREPORTER_STRINGS_OVERRIDE", overridePath);
4218 }
4219 }
4220 } else {
4221 // We might have registered a runtime exception module very early in process
4222 // startup to catch early crashes. This is before we have access to ini file
4223 // data, so unregister here if it turns out the crash reporter is disabled.
4224 CrashReporter::UnregisterRuntimeExceptionModule();
4225 }
4226
4227#if defined(MOZ_SANDBOX1) && defined(XP_WIN)
4228 if (mAppData->sandboxBrokerServices) {
4229 nsAutoString binDirPath;
4230 MOZ_ALWAYS_SUCCEEDS(xreBinDirectory->GetPath(binDirPath))do { if ((__builtin_expect(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl
(xreBinDirectory->GetPath(binDirPath))), 1)))), 1))) { } else
{ do { static_assert( mozilla::detail::AssertionConditionType
<decltype(false)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(false))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("false" " (" "NS_SUCCEEDED(xreBinDirectory->GetPath(binDirPath))"
")", "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 4230); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "false"
") (" "NS_SUCCEEDED(xreBinDirectory->GetPath(binDirPath))"
")"); do { *((volatile int*)__null) = 4230; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
4231 SandboxBroker::Initialize(mAppData->sandboxBrokerServices, binDirPath);
4232 } else {
4233# if defined(MOZ_SANDBOX1)
4234 // If we're sandboxing content and we fail to initialize, then crashing here
4235 // seems like the sensible option.
4236 if (BrowserTabsRemoteAutostart()) {
4237 MOZ_CRASH("Failed to initialize broker services, can't continue.")do { do { } while (false); MOZ_ReportCrash("" "Failed to initialize broker services, can't continue."
, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 4237); AnnotateMozCrashReason("MOZ_CRASH(" "Failed to initialize broker services, can't continue."
")"); do { *((volatile int*)__null) = 4237; __attribute__((nomerge
)) ::abort(); } while (false); } while (false)
;
4238 }
4239# endif
4240 // Otherwise just warn for the moment, as most things will work.
4241 NS_WARNING(NS_DebugBreak(NS_DEBUG_WARNING, "Failed to initialize broker services, sandboxed processes will "
"fail to start.", nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 4243)
4242 "Failed to initialize broker services, sandboxed processes will "NS_DebugBreak(NS_DEBUG_WARNING, "Failed to initialize broker services, sandboxed processes will "
"fail to start.", nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 4243)
4243 "fail to start.")NS_DebugBreak(NS_DEBUG_WARNING, "Failed to initialize broker services, sandboxed processes will "
"fail to start.", nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 4243)
;
4244 }
4245#endif
4246
4247#ifdef XP_MACOSX
4248 // Set up ability to respond to system (Apple) events. This must occur before
4249 // ProcessUpdates to ensure that links clicked in external applications aren't
4250 // lost when updates are pending.
4251 SetupMacApplicationDelegate(&gRestartedByOS);
4252
4253 if (EnvHasValue("MOZ_LAUNCHED_CHILD")) {
4254 // This is needed, on relaunch, to force the OS to use the "Cocoa Dock
4255 // API". Otherwise the call to ReceiveNextEvent() below will make it
4256 // use the "Carbon Dock API". For more info see bmo bug 377166.
4257 EnsureUseCocoaDockAPI();
4258
4259 // When the app relaunches, the original process exits. This causes
4260 // the dock tile to stop bouncing, lose the "running" triangle, and
4261 // if the tile does not permanently reside in the Dock, even disappear.
4262 // This can be confusing to the user, who is expecting the app to launch.
4263 // Calling ReceiveNextEvent without requesting any event is enough to
4264 // cause a dock tile for the child process to appear.
4265 const EventTypeSpec kFakeEventList[] = {{INT_MAX2147483647, INT_MAX2147483647}};
4266 EventRef event;
4267 ::ReceiveNextEvent(GetEventTypeCount(kFakeEventList), kFakeEventList,
4268 kEventDurationNoWait, false, &event);
4269 }
4270
4271 if (CheckArg("foreground")) {
4272 // The original process communicates that it was in the foreground by
4273 // adding this argument. This new process, which is taking over for
4274 // the old one, should make itself the active application.
4275 ProcessSerialNumber psn;
4276 if (::GetCurrentProcess(&psn) == noErr) ::SetFrontProcess(&psn);
4277 }
4278#endif
4279
4280 SaveToEnv("MOZ_LAUNCHED_CHILD=");
4281
4282 // On Windows, the -os-restarted command line switch lets us know when we are
4283 // restarted via RegisterApplicationRestart. May be used for other OSes later.
4284 if (CheckArg("os-restarted", nullptr, CheckArgFlag::RemoveArg) == ARG_FOUND) {
4285 gRestartedByOS = true;
4286 }
4287
4288 gRestartArgc = gArgc;
4289 gRestartArgv =
4290 (char**)malloc(sizeof(char*) * (gArgc + 1 + (override ? 2 : 0)));
4291 if (!gRestartArgv) {
4292 return 1;
4293 }
4294
4295 int i;
4296 for (i = 0; i < gArgc; ++i) {
4297 gRestartArgv[i] = gArgv[i];
4298 }
4299
4300 // Add the -override argument back (it is removed automatically be CheckArg)
4301 // if there is one
4302 if (override) {
4303 gRestartArgv[gRestartArgc++] = const_cast<char*>("-override");
4304 gRestartArgv[gRestartArgc++] = const_cast<char*>(override);
4305 }
4306
4307 gRestartArgv[gRestartArgc] = nullptr;
4308
4309 Maybe<bool> safeModeRequested = IsSafeModeRequested(gArgc, gArgv);
4310 if (!safeModeRequested) {
4311 return 1;
4312 }
4313#ifdef MOZ_BACKGROUNDTASKS1
4314 if (BackgroundTasks::IsBackgroundTaskMode()) {
4315 safeModeRequested = Some(false);
4316
4317 // Remove the --backgroundtask arg now that it has been saved in
4318 // gRestartArgv.
4319 const char* tmpBackgroundTaskName = nullptr;
4320 Unused << CheckArg("backgroundtask", &tmpBackgroundTaskName,
4321 CheckArgFlag::RemoveArg);
4322 }
4323#endif
4324
4325 gSafeMode = safeModeRequested.value();
4326
4327 MaybeAddCPUMicrocodeCrashAnnotation();
4328 CrashReporter::RegisterAnnotationBool(CrashReporter::Annotation::SafeMode,
4329 &gSafeMode);
4330
4331#if defined(MOZ_HAS_REMOTE1)
4332 // Handle --no-remote and --new-instance command line arguments. Setup
4333 // the environment to better accommodate other components and various
4334 // restart scenarios.
4335 ar = CheckArg("no-remote");
4336 if (ar == ARG_FOUND || EnvHasValue("MOZ_NO_REMOTE")) {
4337 mDisableRemoteClient = true;
4338 mDisableRemoteServer = true;
4339 gRestartWithoutRemote = true;
4340 // We don't want to propagate MOZ_NO_REMOTE to potential child
4341 // process.
4342 SaveToEnv("MOZ_NO_REMOTE=");
4343 }
4344
4345 ar = CheckArg("new-instance");
4346 if (ar == ARG_FOUND || EnvHasValue("MOZ_NEW_INSTANCE")) {
4347 mDisableRemoteClient = true;
4348 }
4349#else
4350 // These arguments do nothing in platforms with no remoting support but we
4351 // should remove them from the command line anyway.
4352 CheckArg("no-remote");
4353 CheckArg("new-instance");
4354#endif
4355
4356 ar = CheckArg("offline");
4357 if (ar || EnvHasValue("XRE_START_OFFLINE")) {
4358 mStartOffline = true;
4359 }
4360
4361 // On Windows, to get working console arrangements so help/version/etc
4362 // print something, we need to initialize the native app support.
4363 rv = NS_CreateNativeAppSupport(getter_AddRefs(mNativeApp));
4364 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return 1;
4365
4366 // Handle --help, --full-version and --version command line arguments.
4367 // They should return quickly, so we deal with them here.
4368 if (CheckArg("h") || CheckArg("help") || CheckArg("?")) {
4369 DumpHelp();
4370 *aExitFlag = true;
4371 return 0;
4372 }
4373
4374 if (CheckArg("v") || CheckArg("version")) {
4375 DumpVersion();
4376 *aExitFlag = true;
4377 return 0;
4378 }
4379
4380 if (CheckArg("full-version")) {
4381 DumpFullVersion();
4382 *aExitFlag = true;
4383 return 0;
4384 }
4385
4386#ifdef MOZ_ENABLE_DBUS1
4387 const char* dbusServiceLauncher = nullptr;
4388 ar = CheckArg("dbus-service", &dbusServiceLauncher, CheckArgFlag::None);
4389 if (ar == ARG_BAD) {
4390 Output(true, "Missing launcher param for --dbus-service\n");
4391 return 1;
4392 }
4393 if (ar == ARG_FOUND) {
4394 UniquePtr<DBusService> dbusService =
4395 MakeUnique<DBusService>(dbusServiceLauncher);
4396 if (dbusService->Init()) {
4397 dbusService->Run();
4398 }
4399 *aExitFlag = true;
4400 return 0;
4401 }
4402#endif
4403
4404 rv = XRE_InitCommandLine(gArgc, gArgv);
4405 NS_ENSURE_SUCCESS(rv, 1)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "1", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 4405); return 1; } } while (false)
;
4406
4407 return 0;
4408}
4409
4410#if defined(XP_LINUX1) && !defined(ANDROID)
4411
4412static void AnnotateLSBRelease(void*) {
4413 nsCString dist, desc, release, codename;
4414 if (widget::lsb::GetLSBRelease(dist, desc, release, codename)) {
4415 CrashReporter::AppendAppNotesToCrashReport(desc);
4416 }
4417}
4418
4419#endif // defined(XP_LINUX) && !defined(ANDROID)
4420
4421#ifdef XP_WIN
4422static void ReadAheadSystemDll(const wchar_t* dllName) {
4423 wchar_t dllPath[MAX_PATH];
4424 if (ConstructSystem32Path(dllName, dllPath, MAX_PATH)) {
4425 ReadAheadLib(dllPath);
4426 }
4427}
4428
4429static void ReadAheadPackagedDll(const wchar_t* dllName,
4430 const wchar_t* aGREDir) {
4431 wchar_t dllPath[MAX_PATH];
4432 swprintf(dllPath, MAX_PATH, L"%s\\%s", aGREDir, dllName);
4433 ReadAheadLib(dllPath);
4434}
4435
4436static void PR_CALLBACK ReadAheadDlls_ThreadStart(void* arg) {
4437 UniquePtr<wchar_t[]> greDir(static_cast<wchar_t*>(arg));
4438
4439 // In Bug 1628903, we investigated which DLLs we should prefetch in
4440 // order to reduce disk I/O and improve startup on Windows machines.
4441 // Our ultimate goal is to measure the impact of these improvements on
4442 // retention (see Bug 1640087). Before we place this within a pref,
4443 // we should ensure this feature only ships to the nightly channel
4444 // and monitor results from that subset.
4445 if (greDir) {
4446 // Prefetch the DLLs shipped with firefox
4447 ReadAheadPackagedDll(L"libegl.dll", greDir.get());
4448 ReadAheadPackagedDll(L"libGLESv2.dll", greDir.get());
4449 ReadAheadPackagedDll(L"nssckbi.dll", greDir.get());
4450 ReadAheadPackagedDll(L"freebl3.dll", greDir.get());
4451 ReadAheadPackagedDll(L"softokn3.dll", greDir.get());
4452
4453 // Prefetch the system DLLs
4454 ReadAheadSystemDll(L"DWrite.dll");
4455 ReadAheadSystemDll(L"D3DCompiler_47.dll");
4456 } else {
4457 // Load DataExchange.dll and twinapi.appcore.dll for
4458 // nsWindow::EnableDragDrop
4459 ReadAheadSystemDll(L"DataExchange.dll");
4460 ReadAheadSystemDll(L"twinapi.appcore.dll");
4461
4462 // Load twinapi.dll for WindowsUIUtils::UpdateTabletModeState
4463 ReadAheadSystemDll(L"twinapi.dll");
4464
4465 // Load explorerframe.dll for WinTaskbar::Initialize
4466 ReadAheadSystemDll(L"ExplorerFrame.dll");
4467
4468 // Load WinTypes.dll for nsOSHelperAppService::GetApplicationDescription
4469 ReadAheadSystemDll(L"WinTypes.dll");
4470 }
4471}
4472#endif
4473
4474#if defined(MOZ_UPDATER1) && !defined(MOZ_WIDGET_ANDROID)
4475enum struct ShouldNotProcessUpdatesReason {
4476 DevToolsLaunching,
4477 NotAnUpdatingTask,
4478 OtherInstanceRunning,
4479 FirstStartup
4480};
4481
4482const char* ShouldNotProcessUpdatesReasonAsString(
4483 ShouldNotProcessUpdatesReason aReason) {
4484 switch (aReason) {
4485 case ShouldNotProcessUpdatesReason::DevToolsLaunching:
4486 return "DevToolsLaunching";
4487 case ShouldNotProcessUpdatesReason::NotAnUpdatingTask:
4488 return "NotAnUpdatingTask";
4489 case ShouldNotProcessUpdatesReason::OtherInstanceRunning:
4490 return "OtherInstanceRunning";
4491 default:
4492 MOZ_CRASH("impossible value for ShouldNotProcessUpdatesReason")do { do { } while (false); MOZ_ReportCrash("" "impossible value for ShouldNotProcessUpdatesReason"
, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 4492); AnnotateMozCrashReason("MOZ_CRASH(" "impossible value for ShouldNotProcessUpdatesReason"
")"); do { *((volatile int*)__null) = 4492; __attribute__((nomerge
)) ::abort(); } while (false); } while (false)
;
4493 }
4494}
4495
4496Maybe<ShouldNotProcessUpdatesReason> ShouldNotProcessUpdates(
4497 nsXREDirProvider& aDirProvider) {
4498 // Don't process updates when launched from the installer.
4499 // It's possible for a stale update to be present in the case of a paveover;
4500 // ignore it and leave the update service to discard it.
4501 if (ARG_FOUND == CheckArgExists("first-startup")) {
4502 NS_WARNING("ShouldNotProcessUpdates(): FirstStartup")NS_DebugBreak(NS_DEBUG_WARNING, "ShouldNotProcessUpdates(): FirstStartup"
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 4502)
;
4503 return Some(ShouldNotProcessUpdatesReason::FirstStartup);
4504 }
4505
4506 // Do not process updates if we're launching devtools, as evidenced by
4507 // "--chrome ..." with the browser toolbox chrome document URL.
4508
4509 // Keep this synchronized with the value of the same name in
4510 // devtools/client/framework/browser-toolbox/Launcher.sys.mjs. Or, for bonus
4511 // points, lift this value to nsIXulRuntime or similar, so that it can be
4512 // accessed in both locations. (The prefs service isn't available at this
4513 // point so the simplest manner of sharing the value is not available to us.)
4514 const char* BROWSER_TOOLBOX_WINDOW_URL =
4515 "chrome://devtools/content/framework/browser-toolbox/window.html";
4516
4517 const char* chromeParam = nullptr;
4518 if (ARG_FOUND == CheckArg("chrome", &chromeParam, CheckArgFlag::None)) {
4519 if (!chromeParam || !strcmp(BROWSER_TOOLBOX_WINDOW_URL, chromeParam)) {
4520 NS_WARNING("ShouldNotProcessUpdates(): DevToolsLaunching")NS_DebugBreak(NS_DEBUG_WARNING, "ShouldNotProcessUpdates(): DevToolsLaunching"
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 4520)
;
4521 return Some(ShouldNotProcessUpdatesReason::DevToolsLaunching);
4522 }
4523 }
4524
4525# ifdef MOZ_BACKGROUNDTASKS1
4526 // Do not process updates if we're running a background task mode and another
4527 // instance is already running. This avoids periodic maintenance updating
4528 // underneath a browsing session.
4529 Maybe<nsCString> backgroundTasks = BackgroundTasks::GetBackgroundTasks();
4530 if (backgroundTasks.isSome()) {
4531 // Only process updates for specific tasks: at this time, the
4532 // `backgroundupdate` task and the test-only `shouldprocessupdates` task.
4533 //
4534 // Background tasks can be sparked by Firefox instances that are shutting
4535 // down, which can cause races between the task startup trying to update and
4536 // Firefox trying to invoke the updater. This happened when converting
4537 // `pingsender` to a background task, since it is launched to send pings at
4538 // shutdown: Bug 1736373.
4539 //
4540 // We'd prefer to have this be a property of the task definition sibling to
4541 // `backgroundTaskTimeoutSec`, but when we reach this code we're well before
4542 // we can load the task JSM.
4543 if (!BackgroundTasks::IsUpdatingTaskName(backgroundTasks.ref())) {
4544 NS_WARNING("ShouldNotProcessUpdates(): NotAnUpdatingTask")NS_DebugBreak(NS_DEBUG_WARNING, "ShouldNotProcessUpdates(): NotAnUpdatingTask"
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 4544)
;
4545 return Some(ShouldNotProcessUpdatesReason::NotAnUpdatingTask);
4546 }
4547
4548 // At this point we have a dir provider but no XPCOM directory service. We
4549 // launch the update sync manager using that information so that it doesn't
4550 // need to ask for (and fail to find) the directory service.
4551 nsCOMPtr<nsIFile> anAppFile;
4552 bool persistent;
4553 nsresult rv = aDirProvider.GetFile(XRE_EXECUTABLE_FILE"XREExeF", &persistent,
4554 getter_AddRefs(anAppFile));
4555 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0))) || !anAppFile) {
4556 // Strange, but not a reason to skip processing updates.
4557 return Nothing();
4558 }
4559
4560 auto updateSyncManager = new nsUpdateSyncManager(anAppFile);
4561
4562 bool otherInstance = false;
4563 updateSyncManager->IsOtherInstanceRunning(&otherInstance);
4564 if (otherInstance) {
4565 NS_WARNING("ShouldNotProcessUpdates(): OtherInstanceRunning")NS_DebugBreak(NS_DEBUG_WARNING, "ShouldNotProcessUpdates(): OtherInstanceRunning"
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 4565)
;
4566 return Some(ShouldNotProcessUpdatesReason::OtherInstanceRunning);
4567 }
4568 }
4569# endif
4570
4571 return Nothing();
4572}
4573#endif
4574
4575namespace mozilla::startup {
4576Result<nsCOMPtr<nsIFile>, nsresult> GetIncompleteStartupFile(nsIFile* aProfLD) {
4577 nsCOMPtr<nsIFile> crashFile;
4578 MOZ_TRY(aProfLD->Clone(getter_AddRefs(crashFile)))do { auto mozTryTempResult_ = ::mozilla::ToResult(aProfLD->
Clone(getter_AddRefs(crashFile))); if ((__builtin_expect(!!(mozTryTempResult_
.isErr()), 0))) { return mozTryTempResult_.propagateErr(); } }
while (0)
;
4579 MOZ_TRY(crashFile->Append(FILE_STARTUP_INCOMPLETE))do { auto mozTryTempResult_ = ::mozilla::ToResult(crashFile->
Append(u".startup-incomplete"_ns)); if ((__builtin_expect(!!(
mozTryTempResult_.isErr()), 0))) { return mozTryTempResult_.propagateErr
(); } } while (0)
;
4580 return std::move(crashFile);
4581}
4582} // namespace mozilla::startup
4583
4584// Check whether the last startup attempt resulted in a crash or hang.
4585// This is distinct from the definition of a startup crash from
4586// nsAppStartup::TrackStartupCrashBegin.
4587bool XREMain::CheckLastStartupWasCrash() {
4588 Result<nsCOMPtr<nsIFile>, nsresult> crashFile =
4589 GetIncompleteStartupFile(mProfLD);
4590 if (crashFile.isErr()) {
4591 return true;
4592 }
4593
4594 // Attempt to create the incomplete startup canary file. If the file already
4595 // exists, this fails, and we know the last startup was a crash. If it
4596 // doesn't already exist, it is created, and will be removed at the end of
4597 // the startup crash detection window.
4598 AutoFDClose fd;
4599 Unused << crashFile.inspect()->OpenNSPRFileDesc(
4600 PR_WRONLY0x02 | PR_CREATE_FILE0x08 | PR_EXCL0x80, 0666, getter_Transfers(fd));
4601 return !fd;
4602}
4603
4604/*
4605 * XRE_mainStartup - Initializes the profile and various other services.
4606 * Main() will exit early if either return value != 0 or if aExitFlag is
4607 * true.
4608 */
4609int XREMain::XRE_mainStartup(bool* aExitFlag) {
4610 nsresult rv;
4611
4612 if (!aExitFlag) return 1;
4613 *aExitFlag = false;
4614
4615#ifdef XP_MACOSX
4616 mozilla::MacAutoreleasePool pool;
4617#endif
4618
4619 // Enable Telemetry IO Reporting on DEBUG, nightly and local builds,
4620 // but disable it on FUZZING builds and for ANDROID.
4621#ifndef FUZZING
4622# ifndef ANDROID
4623# ifdef DEBUG1
4624 mozilla::Telemetry::InitIOReporting(gAppData->xreDirectory);
4625# else
4626 {
4627 const char* releaseChannel = MOZ_STRINGIFY(MOZ_UPDATE_CHANNEL)"default";
4628 if (strcmp(releaseChannel, "nightly") == 0 ||
4629 strcmp(releaseChannel, "default") == 0) {
4630 mozilla::Telemetry::InitIOReporting(gAppData->xreDirectory);
4631 }
4632 }
4633# endif /* DEBUG */
4634# endif /* ANDROID */
4635#endif /* FUZZING */
4636
4637#if defined(XP_WIN)
4638 // Enable the HeapEnableTerminationOnCorruption exploit mitigation. We ignore
4639 // the return code because it always returns success, although it has no
4640 // effect on Windows older than XP SP3.
4641 HeapSetInformation(NULL__null, HeapEnableTerminationOnCorruption, NULL__null, 0);
4642#endif /* XP_WIN */
4643
4644#ifdef MOZ_WIDGET_GTK1
4645 // Stash startup token in owned memory because gtk_init will clear
4646 // DESKTOP_STARTUP_ID it.
4647 if (const char* v = PR_GetEnv("DESKTOP_STARTUP_ID")) {
4648 mDesktopStartupID.Assign(v);
4649 }
4650 if (const char* v = PR_GetEnv("XDG_ACTIVATION_TOKEN")) {
4651 mXDGActivationToken.Assign(v);
4652 }
4653#endif
4654
4655#if defined(XP_WIN)
4656 {
4657 // Save the shortcut path before lpTitle is replaced by an AUMID,
4658 // such as by WinTaskbar
4659 STARTUPINFOW si;
4660 GetStartupInfoW(&si);
4661 if (si.dwFlags & STARTF_TITLEISAPPID) {
4662 NS_WARNING("AUMID was already set, shortcut may have been lost.")NS_DebugBreak(NS_DEBUG_WARNING, "AUMID was already set, shortcut may have been lost."
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 4662)
;
4663 } else if ((si.dwFlags & STARTF_TITLEISLINKNAME) && si.lpTitle) {
4664 gProcessStartupShortcut.Assign(si.lpTitle);
4665 }
4666 }
4667#endif /* XP_WIN */
4668
4669#if defined(MOZ_WIDGET_GTK1)
4670 // setup for private colormap. Ideally we'd like to do this
4671 // in nsAppShell::Create, but we need to get in before gtk
4672 // has been initialized to make sure everything is running
4673 // consistently.
4674
4675 // Set program name to the one defined in application.ini.
4676 g_set_prgname(gAppData->remotingName);
4677
4678 // Initialize GTK here for splash.
4679
4680# if defined(MOZ_WIDGET_GTK1) && defined(MOZ_X111)
4681 // Disable XInput2 multidevice support due to focus bugginess.
4682 // See bugs 1182700, 1170342.
4683 // gdk_disable_multidevice() affects Gdk X11 backend only,
4684 // the multidevice support is always enabled on Wayland backend.
4685 const char* useXI2 = PR_GetEnv("MOZ_USE_XINPUT2");
4686 if (!useXI2 || (*useXI2 == '0')) gdk_disable_multidevice();
4687# endif
4688
4689 // Open the display ourselves instead of using gtk_init, so that we can
4690 // close it without fear that one day gtk might clean up the display it
4691 // opens.
4692 if (!gtk_parse_args(&gArgc, &gArgv)) return 1;
4693#endif /* MOZ_WIDGET_GTK */
4694
4695#ifdef FUZZING
4696 if (PR_GetEnv("FUZZER")) {
4697 *aExitFlag = true;
4698 return mozilla::fuzzerRunner->Run(&gArgc, &gArgv);
4699 }
4700#endif
4701
4702 if (PR_GetEnv("MOZ_RUN_GTEST")) {
4703 int result;
4704#ifdef XP_WIN
4705 UseParentConsole();
4706#endif
4707 // RunGTest will only be set if we're in xul-unit
4708 if (mozilla::RunGTest) {
4709 gIsGtest = true;
4710 result = mozilla::RunGTest(&gArgc, gArgv);
4711 gIsGtest = false;
4712 } else {
4713 result = 1;
4714 printf("TEST-UNEXPECTED-FAIL | gtest | Not compiled with enable-tests\n");
4715 }
4716 *aExitFlag = true;
4717 return result;
4718 }
4719
4720 bool isBackgroundTaskMode = false;
4721#ifdef MOZ_BACKGROUNDTASKS1
4722 isBackgroundTaskMode = BackgroundTasks::IsBackgroundTaskMode();
4723#endif
4724
4725#ifdef MOZ_HAS_REMOTE1
4726 if (gfxPlatform::IsHeadless()) {
4727 mDisableRemoteClient = true;
4728 mDisableRemoteServer = true;
4729 }
4730#endif
4731
4732#ifdef MOZ_X111
4733 // Init X11 in thread-safe mode. Must be called prior to the first call to
4734 // XOpenDisplay (called inside gdk_display_open). This is a requirement for
4735 // off main tread compositing.
4736 if (!isBackgroundTaskMode && !gfxPlatform::IsHeadless()) {
4737 XInitThreads();
4738 }
4739#endif
4740#if defined(MOZ_WIDGET_GTK1)
4741 if (!isBackgroundTaskMode && !gfxPlatform::IsHeadless()) {
4742 const char* display_name = nullptr;
4743 bool saveDisplayArg = false;
4744
4745 // display_name is owned by gdk.
4746 display_name = gdk_get_display_arg_name();
4747 bool waylandEnabled = IsWaylandEnabled();
4748# ifdef MOZ_WAYLAND1
4749 if (!display_name) {
4750 auto* proxyEnv = getenv("MOZ_DISABLE_WAYLAND_PROXY");
4751 bool disableWaylandProxy = proxyEnv && *proxyEnv;
4752 if (!disableWaylandProxy && XRE_IsParentProcess() && waylandEnabled) {
4753# ifdef MOZ_LOGGING1
4754 if (MOZ_LOG_TEST(gWidgetWaylandLog, mozilla::LogLevel::Debug)(__builtin_expect(!!(mozilla::detail::log_test(gWidgetWaylandLog
, mozilla::LogLevel::Debug)), 0))
) {
4755 WaylandProxy::SetVerbose(true);
4756 }
4757# endif
4758 gWaylandProxy = WaylandProxy::Create();
4759 if (gWaylandProxy) {
4760 gWaylandProxy->RunThread();
4761 }
4762 }
4763 }
4764# endif
4765
4766 // if --display argument is given make sure it's
4767 // also passed to ContentChild::Init() by MOZ_GDK_DISPLAY.
4768 if (display_name) {
4769 SaveWordToEnv("MOZ_GDK_DISPLAY", nsDependentCString(display_name));
4770 saveDisplayArg = true;
4771 }
4772
4773 // On Wayland disabled builds read X11 DISPLAY env exclusively
4774 // and don't care about different displays.
4775 if (!waylandEnabled && !display_name) {
4776 display_name = PR_GetEnv("DISPLAY");
4777 if (!display_name) {
4778 PR_fprintf(PR_STDERRPR_GetSpecialFD(PR_StandardError),
4779 "Error: no DISPLAY environment variable specified\n");
4780 return 1;
4781 }
4782 }
4783
4784 if (display_name) {
4785 GdkDisplay* disp = gdk_display_open(display_name);
4786 if (!disp) {
4787 PR_fprintf(PR_STDERRPR_GetSpecialFD(PR_StandardError), "Error: cannot open display: %s\n", display_name);
4788 return 1;
4789 }
4790 if (saveDisplayArg) {
4791 if (GdkIsX11Display(disp)) {
4792 SaveWordToEnv("DISPLAY", nsDependentCString(display_name));
4793 } else if (GdkIsWaylandDisplay(disp)) {
4794 SaveWordToEnv("WAYLAND_DISPLAY", nsDependentCString(display_name));
4795 }
4796 }
4797 } else {
4798 gdk_display_manager_open_display(gdk_display_manager_get(), nullptr);
4799 }
4800# if defined(MOZ_WAYLAND1)
4801 // We want to use proxy for main connection only so
4802 // restore original Wayland display for next potential Wayland connections
4803 // from gfx probe code and so on.
4804 if (gWaylandProxy) {
4805 gWaylandProxy->RestoreWaylandDisplay();
4806 }
4807 if (waylandEnabled && PR_GetEnv("WAYLAND_DISPLAY") && GdkIsX11Display()) {
4808 // Gtk somehow switched to X11 display but we want Wayland.
4809 // It may happen if compositor response is missig or it's slow
4810 // or WAYLAND_DISPLAY is wrong. In such case throw warning but
4811 // run with X11.
4812 Output(true,
4813 "Error: Failed to open Wayland display, fallback to X11. "
4814 "WAYLAND_DISPLAY='%s' DISPLAY='%s'\n",
4815 PR_GetEnv("WAYLAND_DISPLAY"), PR_GetEnv("DISPLAY"));
4816
4817 // We need to unset WAYLAND_DISPLAY. Gfx probe code doesn't have fallback
4818 // to X11 and we'll end with Browser running SW rendering only then.
4819 g_unsetenv("WAYLAND_DISPLAY");
4820 gWaylandProxy = nullptr;
4821 }
4822# endif
4823 if (!gdk_display_get_default()) {
4824 Output(true,
4825 "Error: we don't have any display, WAYLAND_DISPLAY='%s' "
4826 "DISPLAY='%s'\n",
4827 PR_GetEnv("WAYLAND_DISPLAY"), PR_GetEnv("DISPLAY"));
4828 return 1;
4829 }
4830 // Check that Wayland only and X11 only builds
4831 // use appropriate displays.
4832# if defined(MOZ_WAYLAND1) && !defined(MOZ_X111)
4833 if (!GdkIsWaylandDisplay()) {
4834 Output(true, "Wayland only build is missig Wayland display!\n");
4835 return 1;
4836 }
4837# endif
4838# if !defined(MOZ_WAYLAND1) && defined(MOZ_X111)
4839 if (!GdkIsX11Display()) {
4840 Output(true, "X11 only build is missig X11 display!\n");
4841 return 1;
4842 }
4843# endif
4844 }
4845#endif
4846#if defined(MOZ_HAS_REMOTE1)
4847 // handle --remote now that xpcom is fired up
4848 mRemoteService = new nsRemoteService(gAppData->remotingName);
4849 if (mRemoteService && !mDisableRemoteServer) {
4850 mRemoteService->LockStartup();
4851 gRemoteService = mRemoteService;
4852 }
4853#endif
4854#if defined(MOZ_WIDGET_GTK1)
4855 g_set_application_name(mAppData->name);
4856
4857#endif /* defined(MOZ_WIDGET_GTK) */
4858#ifdef MOZ_X111
4859 // Do this after initializing GDK, or GDK will install its own handler.
4860 XRE_InstallX11ErrorHandler();
4861#endif
4862
4863 // Call the code to install our handler
4864#ifdef MOZ_JPROF
4865 setupProfilingStuff();
4866#endif
4867
4868 bool canRun = false;
4869 rv = mNativeApp->Start(&canRun);
4870 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0))) || !canRun) {
4871 return 1;
4872 }
4873
4874#ifdef MOZ_WIDGET_GTK1
4875 // startup token might be cleared now, we recover it in case we need a
4876 // restart.
4877 if (!mDesktopStartupID.IsEmpty()) {
4878 // Leak it with extreme prejudice!
4879 PR_SetEnv(ToNewCString("DESKTOP_STARTUP_ID="_ns + mDesktopStartupID));
4880 }
4881
4882 if (!mXDGActivationToken.IsEmpty()) {
4883 // Leak it with extreme prejudice!
4884 PR_SetEnv(ToNewCString("XDG_ACTIVATION_TOKEN="_ns + mXDGActivationToken));
4885 }
4886#endif
4887
4888 // Support exiting early for testing startup sequence. Bug 1360493
4889 if (CheckArg("test-launch-without-hang")) {
4890 *aExitFlag = true;
4891 return 0;
4892 }
4893
4894 mProfileSvc = NS_GetToolkitProfileService();
4895 if (!mProfileSvc) {
4896 // We failed to choose or create profile - notify user and quit
4897 ProfileMissingDialog(mNativeApp);
4898 return 1;
4899 }
4900
4901 bool wasDefaultSelection;
4902 nsCOMPtr<nsIToolkitProfile> profile;
4903 rv = SelectProfile(mProfileSvc, mNativeApp, getter_AddRefs(mProfD),
4904 getter_AddRefs(mProfLD), getter_AddRefs(profile),
4905 &wasDefaultSelection);
4906 if (rv == NS_ERROR_LAUNCHED_CHILD_PROCESS || rv == NS_ERROR_ABORT) {
4907 *aExitFlag = true;
4908 return 0;
4909 }
4910
4911 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
4912 // We failed to choose or create profile - notify user and quit
4913 ProfileMissingDialog(mNativeApp);
4914 return 1;
4915 }
4916
4917#if defined(MOZ_HAS_REMOTE1)
4918 if (mRemoteService) {
4919 // We want a unique profile name to identify the remote instance.
4920 nsCString profileName;
4921 if (profile) {
4922 rv = profile->GetName(profileName);
4923 }
4924 if (!profile || NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0))) || profileName.IsEmpty()) {
4925 // Couldn't get a name from the profile. Use the directory name?
4926 nsString leafName;
4927 rv = mProfD->GetLeafName(leafName);
4928 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
4929 CopyUTF16toUTF8(leafName, profileName);
4930 }
4931 }
4932
4933 mRemoteService->SetProfile(profileName);
4934
4935 if (!mDisableRemoteClient) {
4936 // Try to remote the entire command line. If this fails, start up
4937 // normally.
4938# ifdef MOZ_WIDGET_GTK1
4939 const auto& startupToken =
4940 GdkIsWaylandDisplay() ? mXDGActivationToken : mDesktopStartupID;
4941# else
4942 const nsCString startupToken;
4943# endif
4944 RemoteResult rr = mRemoteService->StartClient(
4945 startupToken.IsEmpty() ? nullptr : startupToken.get());
4946 if (rr == REMOTE_FOUND) {
4947 *aExitFlag = true;
4948 mRemoteService->UnlockStartup();
4949 return 0;
4950 }
4951 if (rr == REMOTE_ARG_BAD) {
4952 mRemoteService->UnlockStartup();
4953 return 1;
4954 }
4955 }
4956 }
4957#endif
4958
4959#if defined(MOZ_UPDATER1) && !defined(MOZ_WIDGET_ANDROID)
4960# ifdef XP_WIN
4961 {
4962 // When automatically restarting for a staged background update
4963 // we want the child process to wait here so that the updater
4964 // does not register two instances running and use that as a
4965 // reason to not process updates. This function requires having
4966 // -restart-pid <param> in the command line to function properly.
4967 // Ensure we keep -restart-pid if we are running tests
4968 if (ARG_FOUND == CheckArgExists("restart-pid") &&
4969 !CheckArg("test-only-automatic-restart-no-wait")) {
4970 // We're not testing and can safely remove it now and read the pid.
4971 const char* restartPidString = nullptr;
4972 CheckArg("restart-pid", &restartPidString, CheckArgFlag::RemoveArg);
4973 // pid should be first parameter following -restart-pid.
4974 uint32_t pid = nsDependentCString(restartPidString).ToInteger(&rv, 10U);
4975 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1))) && pid > 0) {
4976 printf_stderr(
4977 "*** MaybeWaitForProcessExit: launched pidDWORD = %u ***\n", pid);
4978 RefPtr<nsUpdateProcessor> updater = new nsUpdateProcessor();
4979 if (NS_FAILED(((bool)(__builtin_expect(!!(NS_FAILED_impl(updater->WaitForProcessExit
(pid, MAYBE_WAIT_TIMEOUT_MS))), 0)))
4980 updater->WaitForProcessExit(pid, MAYBE_WAIT_TIMEOUT_MS))((bool)(__builtin_expect(!!(NS_FAILED_impl(updater->WaitForProcessExit
(pid, MAYBE_WAIT_TIMEOUT_MS))), 0)))
) {
4981 NS_WARNING("Failed to MaybeWaitForProcessExit.")NS_DebugBreak(NS_DEBUG_WARNING, "Failed to MaybeWaitForProcessExit."
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 4981)
;
4982 }
4983 } else {
4984 NS_WARNING("Failed to parse pid from -restart-pid.")NS_DebugBreak(NS_DEBUG_WARNING, "Failed to parse pid from -restart-pid."
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 4984)
;
4985 }
4986 }
4987 }
4988# endif
4989 Maybe<ShouldNotProcessUpdatesReason> shouldNotProcessUpdatesReason =
4990 ShouldNotProcessUpdates(mDirProvider);
4991 if (shouldNotProcessUpdatesReason.isNothing()) {
4992 // Check for and process any available updates
4993 nsCOMPtr<nsIFile> updRoot;
4994 bool persistent;
4995 rv = mDirProvider.GetFile(XRE_UPDATE_ROOT_DIR"UpdRootD", &persistent,
4996 getter_AddRefs(updRoot));
4997 // XRE_UPDATE_ROOT_DIR may fail. Fallback to appDir if failed
4998 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
4999 updRoot = mDirProvider.GetAppDir();
5000 }
5001
5002 // If the MOZ_TEST_PROCESS_UPDATES environment variable already exists, then
5003 // we are being called from the callback application.
5004 if (EnvHasValue("MOZ_TEST_PROCESS_UPDATES")) {
5005 // If the caller has asked us to log our arguments, do so. This is used
5006 // to make sure that the maintenance service successfully launches the
5007 // callback application.
5008 const char* logFile = nullptr;
5009 if (ARG_FOUND == CheckArg("dump-args", &logFile)) {
5010 FILE* logFP = fopen(logFile, "wb");
5011 if (logFP) {
5012 for (int i = 1; i < gRestartArgc; ++i) {
5013 fprintf(logFP, "%s\n", gRestartArgv[i]);
5014 }
5015 fclose(logFP);
5016 }
5017 }
5018 *aExitFlag = true;
5019 return 0;
5020 }
5021
5022 // Support for processing an update and exiting. The
5023 // MOZ_TEST_PROCESS_UPDATES environment variable will be part of the
5024 // updater's environment and the application that is relaunched by the
5025 // updater. When the application is relaunched by the updater it will be
5026 // removed below and the application will exit.
5027 if (CheckArg("test-process-updates")) {
5028 SaveToEnv("MOZ_TEST_PROCESS_UPDATES=1");
5029 }
5030 nsCOMPtr<nsIFile> exeFile, exeDir;
5031 rv = mDirProvider.GetFile(XRE_EXECUTABLE_FILE"XREExeF", &persistent,
5032 getter_AddRefs(exeFile));
5033 NS_ENSURE_SUCCESS(rv, 1)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "1", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 5033); return 1; } } while (false)
;
5034 rv = exeFile->GetParent(getter_AddRefs(exeDir));
5035 NS_ENSURE_SUCCESS(rv, 1)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "1", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 5035); return 1; } } while (false)
;
5036 ProcessUpdates(mDirProvider.GetGREDir(), exeDir, updRoot, gRestartArgc,
5037 gRestartArgv, mAppData->version);
5038 if (EnvHasValue("MOZ_TEST_PROCESS_UPDATES")) {
5039 SaveToEnv("MOZ_TEST_PROCESS_UPDATES=");
5040 *aExitFlag = true;
5041 return 0;
5042 }
5043 } else {
5044 if (CheckArg("test-process-updates") ||
5045 EnvHasValue("MOZ_TEST_PROCESS_UPDATES")) {
5046 // Support for testing *not* processing an update. The launched process
5047 // can witness this environment variable and conclude that its runtime
5048 // environment resulted in not processing updates.
5049
5050 SaveToEnv(nsPrintfCString(
5051 "MOZ_TEST_PROCESS_UPDATES=ShouldNotProcessUpdates(): %s",
5052 ShouldNotProcessUpdatesReasonAsString(
5053 shouldNotProcessUpdatesReason.value()))
5054 .get());
5055 }
5056 }
5057#endif
5058
5059 // We now know there is no existing instance using the selected profile. If
5060 // the profile wasn't selected by specific command line arguments and the
5061 // user has chosen to show the profile manager on startup then do that.
5062 if (wasDefaultSelection) {
5063 bool useSelectedProfile;
5064 rv = mProfileSvc->GetStartWithLastProfile(&useSelectedProfile);
5065 NS_ENSURE_SUCCESS(rv, 1)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "1", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 5065); return 1; } } while (false)
;
5066
5067 if (!useSelectedProfile) {
5068 rv = ShowProfileManager(mProfileSvc, mNativeApp);
5069 if (rv == NS_ERROR_LAUNCHED_CHILD_PROCESS || rv == NS_ERROR_ABORT) {
5070 *aExitFlag = true;
5071 return 0;
5072 }
5073 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
5074 return 1;
5075 }
5076 }
5077 }
5078
5079 // We always want to lock the profile even if we're actually going to reset
5080 // it later.
5081 rv = LockProfile(mNativeApp, mProfD, mProfLD, profile,
5082 getter_AddRefs(mProfileLock));
5083 if (rv == NS_ERROR_LAUNCHED_CHILD_PROCESS || rv == NS_ERROR_ABORT) {
5084 *aExitFlag = true;
5085 return 0;
5086 } else if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
5087 return 1;
5088 }
5089
5090 if (gDoProfileReset) {
5091 if (EnvHasValue("MOZ_RESET_PROFILE_RESTART")) {
5092 SaveToEnv("MOZ_RESET_PROFILE_RESTART=");
5093 // We only want to restore the previous session if the profile refresh was
5094 // triggered by user. And if it was a user-triggered profile refresh
5095 // through, say, the safeMode dialog or the troubleshooting page, the
5096 // MOZ_RESET_PROFILE_RESTART env variable would be set. Hence we set
5097 // MOZ_RESET_PROFILE_MIGRATE_SESSION here so that Firefox profile migrator
5098 // would migrate old session data later.
5099 SaveToEnv("MOZ_RESET_PROFILE_MIGRATE_SESSION=1");
5100 }
5101 // Unlock the source profile.
5102 mProfileLock->Unlock();
5103
5104 // If we're resetting a profile, create a new one and use it to startup.
5105 gResetOldProfile = profile;
5106 rv = mProfileSvc->CreateResetProfile(getter_AddRefs(profile));
5107 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
5108 rv = profile->GetRootDir(getter_AddRefs(mProfD));
5109 NS_ENSURE_SUCCESS(rv, 1)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "1", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 5109); return 1; } } while (false)
;
5110 SaveFileToEnv("XRE_PROFILE_PATH", mProfD);
5111
5112 rv = profile->GetLocalDir(getter_AddRefs(mProfLD));
5113 NS_ENSURE_SUCCESS(rv, 1)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "1", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 5113); return 1; } } while (false)
;
5114 SaveFileToEnv("XRE_PROFILE_LOCAL_PATH", mProfLD);
5115
5116 // Lock the new profile
5117 rv = LockProfile(mNativeApp, mProfD, mProfLD, profile,
5118 getter_AddRefs(mProfileLock));
5119 if (rv == NS_ERROR_LAUNCHED_CHILD_PROCESS || rv == NS_ERROR_ABORT) {
5120 *aExitFlag = true;
5121 return 0;
5122 } else if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
5123 return 1;
5124 }
5125 } else {
5126 NS_WARNING("Profile reset failed.")NS_DebugBreak(NS_DEBUG_WARNING, "Profile reset failed.", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 5126)
;
5127 return 1;
5128 }
5129 }
5130
5131 gProfileLock = mProfileLock;
5132
5133 nsAutoCString version;
5134 BuildVersion(version);
5135
5136#ifdef TARGET_OS_ABI"Linux_x86_64-gcc3"
5137 constexpr auto osABI = nsLiteralCString{TARGET_OS_ABI"Linux_x86_64-gcc3"};
5138#else
5139 // No TARGET_XPCOM_ABI, but at least the OS is known
5140 constexpr auto osABI = nsLiteralCString{OS_TARGET"Linux" "_UNKNOWN"};
5141#endif
5142
5143 // Check for version compatibility with the last version of the app this
5144 // profile was started with. The format of the version stamp is defined
5145 // by the BuildVersion function.
5146 // Also check to see if something has happened to invalidate our
5147 // fastload caches, like an app upgrade.
5148
5149 // If we see .purgecaches, that means someone did a make.
5150 // Re-register components to catch potential changes.
5151 nsCOMPtr<nsIFile> flagFile;
5152 if (mAppData->directory) {
5153 Unused << mAppData->directory->Clone(getter_AddRefs(flagFile));
5154 }
5155 if (flagFile) {
5156 flagFile->AppendNative(FILE_INVALIDATE_CACHES".purgecaches"_ns);
5157 }
5158
5159 bool cachesOK;
5160 bool isDowngrade;
5161 nsCString lastVersion;
5162 bool versionOK = CheckCompatibility(
5163 mProfD, version, osABI, mDirProvider.GetGREDir(), mAppData->directory,
5164 flagFile, &cachesOK, &isDowngrade, lastVersion);
5165
5166 MOZ_RELEASE_ASSERT(!cachesOK || lastVersion.Equals(version),do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!cachesOK || lastVersion.Equals(version))>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(!cachesOK || lastVersion.Equals(version)))), 0))) { do { }
while (false); MOZ_ReportAssertionFailure("!cachesOK || lastVersion.Equals(version)"
" (" "Caches cannot be good if the version has changed." ")"
, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 5167); AnnotateMozCrashReason("MOZ_RELEASE_ASSERT" "(" "!cachesOK || lastVersion.Equals(version)"
") (" "Caches cannot be good if the version has changed." ")"
); do { *((volatile int*)__null) = 5167; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
5167 "Caches cannot be good if the version has changed.")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!cachesOK || lastVersion.Equals(version))>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(!cachesOK || lastVersion.Equals(version)))), 0))) { do { }
while (false); MOZ_ReportAssertionFailure("!cachesOK || lastVersion.Equals(version)"
" (" "Caches cannot be good if the version has changed." ")"
, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 5167); AnnotateMozCrashReason("MOZ_RELEASE_ASSERT" "(" "!cachesOK || lastVersion.Equals(version)"
") (" "Caches cannot be good if the version has changed." ")"
); do { *((volatile int*)__null) = 5167; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5168
5169#ifdef MOZ_BLOCK_PROFILE_DOWNGRADE1
5170 // The argument check must come first so the argument is always removed from
5171 // the command line regardless of whether this is a downgrade or not.
5172 if (!CheckArg("allow-downgrade") && isDowngrade &&
5173 !EnvHasValue("MOZ_ALLOW_DOWNGRADE")) {
5174 rv = CheckDowngrade(mProfD, mNativeApp, mProfileSvc, lastVersion);
5175 if (rv == NS_ERROR_LAUNCHED_CHILD_PROCESS || rv == NS_ERROR_ABORT) {
5176 *aExitFlag = true;
5177 return 0;
5178 }
5179 }
5180#endif
5181
5182 rv = mDirProvider.SetProfile(mProfD, mProfLD);
5183 NS_ENSURE_SUCCESS(rv, 1)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "1", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 5183); return 1; } } while (false)
;
5184
5185 //////////////////////// NOW WE HAVE A PROFILE ////////////////////////
5186
5187 mozilla::Telemetry::SetProfileDir(mProfD);
5188
5189 if (mAppData->flags & NS_XRE_ENABLE_CRASH_REPORTER(1 << 3)) {
5190 MakeOrSetMinidumpPath(mProfD);
5191 }
5192
5193 CrashReporter::SetProfileDirectory(mProfD);
5194
5195#ifdef MOZ_ASAN_REPORTER
5196 // In ASan reporter builds, we need to set ASan's log_path as early as
5197 // possible, so it dumps its errors into files there instead of using
5198 // the default stderr location. Since this is crucial for ASan reporter
5199 // to work at all (and we don't want people to use a non-functional
5200 // ASan reporter build), all failures while setting log_path are fatal.
5201 setASanReporterPath(mProfD);
5202
5203 // Export to env for child processes
5204 SaveFileToEnv("ASAN_REPORTER_PATH", mProfD);
5205#endif
5206
5207 bool lastStartupWasCrash = CheckLastStartupWasCrash();
5208
5209 CrashReporter::RecordAnnotationBool(
5210 CrashReporter::Annotation::LastStartupWasCrash, lastStartupWasCrash);
5211
5212 if (CheckArg("purgecaches") || PR_GetEnv("MOZ_PURGE_CACHES") ||
5213 lastStartupWasCrash || gSafeMode) {
5214 cachesOK = false;
5215 }
5216
5217 CrashReporter::RecordAnnotationBool(
5218 CrashReporter::Annotation::StartupCacheValid, cachesOK && versionOK);
5219
5220 // Every time a profile is loaded by a build with a different version,
5221 // it updates the compatibility.ini file saying what version last wrote
5222 // the fastload caches. On subsequent launches if the version matches,
5223 // there is no need for re-registration. If the user loads the same
5224 // profile in different builds the component registry must be
5225 // re-generated to prevent mysterious component loading failures.
5226 //
5227 bool startupCacheValid = true;
5228
5229 if (!cachesOK || !versionOK) {
5230 QuotaManager::InvalidateQuotaCache();
5231
5232 startupCacheValid = RemoveComponentRegistries(mProfD, mProfLD, false);
5233
5234 // Rewrite compatibility.ini to match the current build. The next run
5235 // should attempt to invalidate the caches if either this run is safe mode
5236 // or the attempt to invalidate the caches this time failed.
5237 WriteVersion(mProfD, version, osABI, mDirProvider.GetGREDir(),
5238 mAppData->directory, gSafeMode || !startupCacheValid);
5239 }
5240
5241 if (!startupCacheValid) StartupCache::IgnoreDiskCache();
5242
5243 if (flagFile) {
5244 flagFile->Remove(true);
5245 }
5246
5247 // Flush any pending page load events.
5248 mozilla::glean_pings::Pageload.Submit("startup"_ns);
5249
5250 if (!isBackgroundTaskMode) {
5251#ifdef USE_GLX_TEST1
5252 GfxInfo::FireGLXTestProcess();
5253#endif
5254#ifdef MOZ_WAYLAND1
5255 // Make sure we have wayland connection for main thread.
5256 // It's used as template to create display connections
5257 // for different threads.
5258 if (IsWaylandEnabled()) {
5259 MOZ_UNUSED(WaylandDisplayGet())do { if (WaylandDisplayGet()) { (void)0; } } while (0);
5260 }
5261#endif
5262#ifdef MOZ_WIDGET_GTK1
5263 nsAppShell::InstallTermSignalHandler();
5264#endif
5265 }
5266
5267 return 0;
5268}
5269
5270#if defined(MOZ_SANDBOX1)
5271void AddSandboxAnnotations() {
5272 CrashReporter::RecordAnnotationU32(
5273 CrashReporter::Annotation::ContentSandboxLevel,
5274 GetEffectiveContentSandboxLevel());
5275 CrashReporter::RecordAnnotationU32(CrashReporter::Annotation::GpuSandboxLevel,
5276 GetEffectiveGpuSandboxLevel());
5277
5278 // Include whether or not this instance is capable of content sandboxing
5279 bool sSandboxCapable = false;
5280
5281# if defined(XP_WIN)
5282 // All supported Windows versions support some level of content sandboxing
5283 sSandboxCapable = true;
5284# elif defined(XP_MACOSX)
5285 // All supported OS X versions are capable
5286 sSandboxCapable = true;
5287# elif defined(XP_LINUX1)
5288 sSandboxCapable = SandboxInfo::Get().CanSandboxContent();
5289# elif defined(__OpenBSD__)
5290 sSandboxCapable = true;
5291 StartOpenBSDSandbox(GeckoProcessType_Default);
5292# endif
5293
5294 CrashReporter::RecordAnnotationBool(
5295 CrashReporter::Annotation::ContentSandboxCapable, sSandboxCapable);
5296}
5297#endif /* MOZ_SANDBOX */
5298
5299/*
5300 * XRE_mainRun - Command line startup, profile migration, and
5301 * the calling of appStartup->Run().
5302 */
5303nsresult XREMain::XRE_mainRun() {
5304 nsresult rv = NS_OK;
5305 NS_ASSERTION(mScopedXPCOM, "Scoped xpcom not initialized.")do { if (!(mScopedXPCOM)) { NS_DebugBreak(NS_DEBUG_ASSERTION,
"Scoped xpcom not initialized.", "mScopedXPCOM", "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 5305); MOZ_PretendNoReturn(); } } while (0)
;
5306
5307#if defined(XP_WIN)
5308 RefPtr<mozilla::DllServices> dllServices(mozilla::DllServices::Get());
5309 dllServices->StartUntrustedModulesProcessor(false);
5310 auto dllServicesDisable =
5311 MakeScopeExit([&dllServices]() { dllServices->DisableFull(); });
5312
5313 mozilla::mscom::InitProfilerMarkers();
5314#endif // defined(XP_WIN)
5315
5316 // We need the appStartup pointer to span multiple scopes, so we declare
5317 // it here.
5318 nsCOMPtr<nsIAppStartup> appStartup;
5319 // Ditto with the command line.
5320 nsCOMPtr<nsICommandLineRunner> cmdLine;
5321
5322 {
5323#ifdef XP_MACOSX
5324 // In this scope, create an autorelease pool that will leave scope with
5325 // it just before entering our event loop.
5326 mozilla::MacAutoreleasePool pool;
5327#endif
5328
5329 rv = mScopedXPCOM->SetWindowCreator(mNativeApp);
5330 NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "NS_ERROR_FAILURE", static_cast
<uint32_t>(__rv), name ? " (" : "", name ? name : "", name
? ")" : ""); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 5330); return NS_ERROR_FAILURE; } } while (false)
;
5331
5332 // tell the crash reporter to also send the release channel
5333 nsCOMPtr<nsIPrefService> prefs =
5334 do_GetService("@mozilla.org/preferences-service;1", &rv);
5335 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
5336 nsCOMPtr<nsIPrefBranch> defaultPrefBranch;
5337 rv = prefs->GetDefaultBranch(nullptr, getter_AddRefs(defaultPrefBranch));
5338
5339 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
5340 nsAutoCString sval;
5341 rv = defaultPrefBranch->GetCharPref("app.update.channel", sval);
5342 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
5343 CrashReporter::RecordAnnotationNSCString(
5344 CrashReporter::Annotation::ReleaseChannel, sval);
5345 }
5346 }
5347 }
5348 // Needs to be set after xpcom initialization.
5349 bool includeContextHeap = Preferences::GetBool(
5350 "toolkit.crashreporter.include_context_heap", false);
5351 CrashReporter::SetIncludeContextHeap(includeContextHeap);
5352
5353#if defined(XP_LINUX1) && !defined(ANDROID)
5354 PR_CreateThread(PR_USER_THREAD, AnnotateLSBRelease, 0, PR_PRIORITY_LOW,
5355 PR_GLOBAL_THREAD, PR_UNJOINABLE_THREAD, 0);
5356#endif
5357
5358 if (mStartOffline) {
5359 nsCOMPtr<nsIIOService> io(
5360 do_GetService("@mozilla.org/network/io-service;1"));
5361 NS_ENSURE_TRUE(io, NS_ERROR_FAILURE)do { if ((__builtin_expect(!!(!(io)), 0))) { NS_DebugBreak(NS_DEBUG_WARNING
, "NS_ENSURE_TRUE(" "io" ") failed", nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 5361); return NS_ERROR_FAILURE; } } while (false)
;
5362 io->SetManageOfflineStatus(false);
5363 io->SetOffline(true);
5364 }
5365
5366#ifdef XP_WIN
5367 mozilla::DllPrefetchExperimentRegistryInfo prefetchRegInfo;
5368 mozilla::AlteredDllPrefetchMode dllPrefetchMode =
5369 prefetchRegInfo.GetAlteredDllPrefetchMode();
5370
5371 if (!PR_GetEnv("XRE_NO_DLL_READAHEAD") &&
5372 dllPrefetchMode != mozilla::AlteredDllPrefetchMode::NoPrefetch) {
5373 nsCOMPtr<nsIFile> greDir = mDirProvider.GetGREDir();
5374 nsAutoString path;
5375 rv = greDir->GetPath(path);
5376 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
5377 PRThread* readAheadThread;
5378 wchar_t* pathRaw;
5379
5380 // We use the presence of a path argument inside the thread to determine
5381 // which list of Dlls to use. The old list does not need access to the
5382 // GRE dir, so the path argument is set to a null pointer.
5383 if (dllPrefetchMode ==
5384 mozilla::AlteredDllPrefetchMode::OptimizedPrefetch) {
5385 pathRaw = new wchar_t[MAX_PATH];
5386 wcscpy_s(pathRaw, MAX_PATH, path.get());
5387 } else {
5388 pathRaw = nullptr;
5389 }
5390 readAheadThread = PR_CreateThread(
5391 PR_USER_THREAD, ReadAheadDlls_ThreadStart, (void*)pathRaw,
5392 PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_UNJOINABLE_THREAD, 0);
5393 if (readAheadThread == NULL__null) {
5394 delete[] pathRaw;
5395 }
5396 }
5397 }
5398#endif
5399
5400 if (gDoMigration) {
5401 nsCOMPtr<nsIFile> file;
5402 mDirProvider.GetAppDir()->Clone(getter_AddRefs(file));
5403 file->AppendNative("override.ini"_ns);
5404 nsINIParsernsINIParser_internal parser;
5405 nsresult rv = parser.Init(file);
5406 // if override.ini doesn't exist, also check for distribution.ini
5407 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
5408 bool persistent;
5409 mDirProvider.GetFile(XRE_APP_DISTRIBUTION_DIR"XREAppDist", &persistent,
5410 getter_AddRefs(file));
5411 file->AppendNative("distribution.ini"_ns);
5412 rv = parser.Init(file);
5413 }
5414 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
5415 nsAutoCString buf;
5416 rv = parser.GetString("XRE", "EnableProfileMigrator", buf);
5417 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
5418 if (buf[0] == '0' || buf[0] == 'f' || buf[0] == 'F') {
5419 gDoMigration = false;
5420 }
5421 }
5422 }
5423 }
5424
5425 // We'd like to initialize the JSContext *after* reading the user prefs.
5426 // Unfortunately that's not possible if we have to do profile migration
5427 // because that requires us to execute JS before reading user prefs.
5428 // Restarting the browser after profile migration would fix this. See
5429 // bug 1592523.
5430 bool initializedJSContext = false;
5431
5432 {
5433 // Profile Migration
5434 if (mAppData->flags & NS_XRE_ENABLE_PROFILE_MIGRATOR(1 << 1) && gDoMigration) {
5435 gDoMigration = false;
5436
5437 xpc::InitializeJSContext();
5438 initializedJSContext = true;
5439
5440 nsCOMPtr<nsIProfileMigrator> pm(
5441 do_CreateInstance(NS_PROFILEMIGRATOR_CONTRACTID"@mozilla.org/toolkit/profile-migrator;1"));
5442 if (pm) {
5443 nsAutoCString aKey;
5444 nsAutoCString aName;
5445 if (gDoProfileReset) {
5446 // Automatically migrate from the current application if we just
5447 // reset the profile.
5448 aKey = MOZ_APP_NAME"firefox";
5449 gResetOldProfile->GetName(aName);
5450 }
5451#ifdef XP_MACOSX
5452 // Necessary for migration wizard to be accessible.
5453 InitializeMacApp();
5454#endif
5455 pm->Migrate(&mDirProvider, aKey, aName);
5456 }
5457 }
5458
5459 if (gDoProfileReset) {
5460 if (!initializedJSContext) {
5461 xpc::InitializeJSContext();
5462 initializedJSContext = true;
5463 }
5464
5465 nsresult backupCreated =
5466 ProfileResetCleanup(mProfileSvc, gResetOldProfile);
5467 if (NS_FAILED(backupCreated)((bool)(__builtin_expect(!!(NS_FAILED_impl(backupCreated)), 0
)))
) {
5468 NS_WARNING("Could not cleanup the profile that was reset")NS_DebugBreak(NS_DEBUG_WARNING, "Could not cleanup the profile that was reset"
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 5468)
;
5469 }
5470 }
5471 }
5472
5473 // Initialize user preferences before notifying startup observers so they're
5474 // ready in time for early consumers, such as the component loader.
5475 mDirProvider.InitializeUserPrefs();
5476
5477 // Now that all (user) prefs have been loaded we can initialize the main
5478 // thread's JSContext.
5479 if (!initializedJSContext) {
5480 xpc::InitializeJSContext();
5481 }
5482
5483 // Finally, now that JS has been initialized, we can finish pref loading.
5484 // This needs to happen after JS and XPConnect initialization because
5485 // AutoConfig files require JS execution. Note that this means AutoConfig
5486 // files can't override JS engine start-up prefs.
5487 mDirProvider.FinishInitializingUserPrefs();
5488
5489#if defined(MOZ_SANDBOX1) && defined(XP_WIN)
5490 // Now that we have preferences and the directory provider, we can
5491 // finish initializing SandboxBroker. This must happen before the GFX
5492 // platform is initialized (which will launch the GPU process), which
5493 // occurs when the "app-startup" category is started up below
5494 //
5495 // After this completes, we are ready to launch sandboxed processes
5496 mozilla::SandboxBroker::GeckoDependentInitialize();
5497#endif
5498
5499 nsCOMPtr<nsIFile> workingDir;
5500 rv = NS_GetSpecialDirectory(NS_OS_CURRENT_WORKING_DIR"CurWorkD",
5501 getter_AddRefs(workingDir));
5502 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
5503 // No working dir? This can happen if it gets deleted before we start.
5504 workingDir = nullptr;
5505 }
5506
5507 cmdLine = new nsCommandLine();
5508
5509 rv = cmdLine->Init(gArgc, gArgv, workingDir,
5510 nsICommandLine::STATE_INITIAL_LAUNCH);
5511 NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "NS_ERROR_FAILURE", static_cast
<uint32_t>(__rv), name ? " (" : "", name ? name : "", name
? ")" : ""); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 5511); return NS_ERROR_FAILURE; } } while (false)
;
5512
5513 // "app-startup" is the name of both the category and the event
5514 NS_CreateServicesFromCategory("app-startup", cmdLine, "app-startup",
5515 nullptr);
5516
5517 appStartup = components::AppStartup::Service();
5518 NS_ENSURE_TRUE(appStartup, NS_ERROR_FAILURE)do { if ((__builtin_expect(!!(!(appStartup)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "appStartup" ") failed",
nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 5518); return NS_ERROR_FAILURE; } } while (false)
;
5519
5520 mDirProvider.DoStartup();
5521
5522#ifdef XP_WIN
5523 // It needs to be called on the main thread because it has to use
5524 // nsObserverService.
5525 EnsureWin32kInitialized();
5526#endif
5527
5528 // As FilePreferences need the profile directory, we must initialize right
5529 // here.
5530 mozilla::FilePreferences::InitDirectoriesAllowlist();
5531 mozilla::FilePreferences::InitPrefs();
5532
5533 nsCString userAgentLocale;
5534 LocaleService::GetInstance()->GetAppLocaleAsBCP47(userAgentLocale);
5535 CrashReporter::RecordAnnotationNSCString(
5536 CrashReporter::Annotation::useragent_locale, userAgentLocale);
5537
5538 if (!AppShutdown::IsInOrBeyond(ShutdownPhase::AppShutdownConfirmed)) {
5539 /* Special-case services that need early access to the command
5540 line. */
5541 nsCOMPtr<nsIObserverService> obsService =
5542 mozilla::services::GetObserverService();
5543 if (obsService) {
5544 obsService->NotifyObservers(cmdLine, "command-line-startup", nullptr);
5545 }
5546 }
5547
5548#ifdef XP_WIN
5549 // Hack to sync up the various environment storages. XUL_APP_FILE is special
5550 // in that it comes from a different CRT (firefox.exe's static-linked copy).
5551 // Ugly details in http://bugzil.la/1175039#c27
5552 char appFile[MAX_PATH];
5553 if (GetEnvironmentVariableA("XUL_APP_FILE", appFile, sizeof(appFile))) {
5554 SmprintfPointer saved = mozilla::Smprintf("XUL_APP_FILE=%s", appFile);
5555 // We intentionally leak the string here since it is required by
5556 // PR_SetEnv.
5557 PR_SetEnv(saved.release());
5558 }
5559#endif
5560
5561 mozilla::AppShutdown::SaveEnvVarsForPotentialRestart();
5562
5563 // clear out any environment variables which may have been set
5564 // during the relaunch process now that we know we won't be relaunching.
5565 SaveToEnv("XRE_PROFILE_PATH=");
5566 SaveToEnv("XRE_PROFILE_LOCAL_PATH=");
5567 SaveToEnv("XRE_START_OFFLINE=");
5568 SaveToEnv("XUL_APP_FILE=");
5569 SaveToEnv("XRE_BINARY_PATH=");
5570 SaveToEnv("XRE_RESTARTED_BY_PROFILE_MANAGER=");
5571
5572 if (!AppShutdown::IsInOrBeyond(ShutdownPhase::AppShutdownConfirmed)) {
5573 // Don't create the hidden window during startup on
5574 // platforms that don't always need it.
5575#ifdef XP_MACOSX
5576 bool lazyHiddenWindow = false;
5577#else
5578 bool lazyHiddenWindow = true;
5579#endif
5580
5581#ifdef MOZ_BACKGROUNDTASKS1
5582 if (BackgroundTasks::IsBackgroundTaskMode()) {
5583 // Background tasks aren't going to load a chrome XUL document.
5584 lazyHiddenWindow = true;
5585 }
5586#endif
5587
5588 if (!lazyHiddenWindow) {
5589 rv = appStartup->CreateHiddenWindow();
5590 NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "NS_ERROR_FAILURE", static_cast
<uint32_t>(__rv), name ? " (" : "", name ? name : "", name
? ")" : ""); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre/nsAppRunner.cpp"
, 5590); return NS_ERROR_FAILURE; } } while (false)
;
5591 }
5592
5593#ifdef XP_WIN
5594 Preferences::RegisterCallbackAndCall(
5595 RegisterApplicationRestartChanged,
5596 PREF_WIN_REGISTER_APPLICATION_RESTART);
5597 SetupAlteredPrefetchPref();
5598 SetupSkeletonUIPrefs();
5599# if defined(MOZ_LAUNCHER_PROCESS)
5600 SetupLauncherProcessPref();
5601# endif // defined(MOZ_LAUNCHER_PROCESS)
5602# if defined(MOZ_DEFAULT_BROWSER_AGENT)
5603# if defined(MOZ_BACKGROUNDTASKS1)
5604 // The backgroundtask profile is not a browsing profile, let alone the new
5605 // default profile, so don't mirror its properties into the registry.
5606 if (!BackgroundTasks::IsBackgroundTaskMode())
5607# endif // defined(MOZ_BACKGROUNDTASKS)
5608 {
5609 Preferences::RegisterCallbackAndCall(
5610 &OnDefaultAgentTelemetryPrefChanged,
5611 kPrefHealthReportUploadEnabled);
5612 Preferences::RegisterCallbackAndCall(
5613 &OnDefaultAgentTelemetryPrefChanged, kPrefDefaultAgentEnabled);
5614
5615 Preferences::RegisterCallbackAndCall(
5616 &OnDefaultAgentRemoteSettingsPrefChanged,