Bug Summary

File:var/lib/jenkins/workspace/firefox-scan-build/browser/app/nsBrowserApp.cpp
Warning:line 181, column 15
Potential memory leak

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 nsBrowserApp.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/browser/app -fcoverage-compilation-dir=/var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/browser/app -resource-dir /usr/lib/llvm-19/lib/clang/19 -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/system_wrappers -U _FORTIFY_SOURCE -D _FORTIFY_SOURCE=2 -D DEBUG=1 -D XPCOM_GLUE -D MOZ_HAS_MOZGLUE -D MOZ_GECKODRIVER -D FIREFOX_ICO="/var/lib/jenkins/workspace/firefox-scan-build/browser/branding/unofficial/firefox.ico" -D DOCUMENT_ICO="/var/lib/jenkins/workspace/firefox-scan-build/browser/branding/unofficial/document.ico" -D NEWWINDOW_ICO="/var/lib/jenkins/workspace/firefox-scan-build/browser/branding/unofficial/newwindow.ico" -D NEWTAB_ICO="/var/lib/jenkins/workspace/firefox-scan-build/browser/branding/unofficial/newtab.ico" -D PBMODE_ICO="/var/lib/jenkins/workspace/firefox-scan-build/browser/branding/unofficial/pbmode.ico" -D DOCUMENT_PDF_ICO="/var/lib/jenkins/workspace/firefox-scan-build/browser/branding/unofficial/document_pdf.ico" -I /var/lib/jenkins/workspace/firefox-scan-build/browser/app -I /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/browser/app -I /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/build -I /var/lib/jenkins/workspace/firefox-scan-build/toolkit/xre -I /var/lib/jenkins/workspace/firefox-scan-build/xpcom/base -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 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../include/c++/14 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../include/x86_64-linux-gnu/c++/14 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../include/c++/14/backward -internal-isystem /usr/lib/llvm-19/lib/clang/19/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../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 -fstrict-flex-arrays=1 -stack-protector 2 -fstack-clash-protection -ftrivial-auto-var-init=pattern -fno-rtti -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -fno-sized-deallocation -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-09-22-115206-3586786-1 -x c++ /var/lib/jenkins/workspace/firefox-scan-build/browser/app/nsBrowserApp.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 "nsXULAppAPI.h"
7#include "mozilla/XREAppData.h"
8#include "XREChildData.h"
9#include "XREShellData.h"
10#include "application.ini.h"
11#include "mozilla/Bootstrap.h"
12#include "mozilla/ProcessType.h"
13#include "mozilla/RuntimeExceptionModule.h"
14#include "mozilla/ScopeExit.h"
15#include "BrowserDefines.h"
16#if defined(XP_WIN)
17# include <windows.h>
18# include <stdlib.h>
19#elif defined(XP_UNIX1)
20# include <sys/resource.h>
21# include <unistd.h>
22# include <fcntl.h>
23#endif
24
25#include <stdio.h>
26#include <stdarg.h>
27#include <time.h>
28
29#include "nsCOMPtr.h"
30
31#ifdef XP_WIN
32# include "mozilla/PreXULSkeletonUI.h"
33# include "freestanding/SharedSection.h"
34# include "LauncherProcessWin.h"
35# include "mozilla/GeckoArgs.h"
36# include "mozilla/mscom/ProcessRuntime.h"
37# include "mozilla/WindowsDllBlocklist.h"
38# include "mozilla/WindowsDpiInitialization.h"
39# include "mozilla/WindowsProcessMitigations.h"
40
41# define XRE_WANT_ENVIRON
42# include "nsWindowsWMain.cpp"
43
44# define strcasecmp _stricmp
45# ifdef MOZ_SANDBOX1
46# include "mozilla/sandboxing/SandboxInitialization.h"
47# include "mozilla/sandboxing/sandboxLogging.h"
48# endif
49#endif
50#include "BinaryPath.h"
51
52#include "nsXPCOMPrivate.h" // for MAXPATHLEN and XPCOM_DLL
53
54#include "mozilla/Sprintf.h"
55#include "mozilla/StartupTimeline.h"
56#include "BaseProfiler.h"
57
58#ifdef LIBFUZZER
59# include "FuzzerDefs.h"
60#endif
61
62#ifdef MOZ_LINUX_32_SSE2_STARTUP_ERROR
63# include <cpuid.h>
64# include "mozilla/Unused.h"
65
66static bool IsSSE2Available() {
67 // The rest of the app has been compiled to assume that SSE2 is present
68 // unconditionally, so we can't use the normal copy of SSE.cpp here.
69 // Since SSE.cpp caches the results and we need them only transiently,
70 // instead of #including SSE.cpp here, let's just inline the specific check
71 // that's needed.
72 unsigned int level = 1u;
73 unsigned int eax, ebx, ecx, edx;
74 unsigned int bits = (1u << 26);
75 unsigned int max = __get_cpuid_max(0, nullptr);
76 if (level > max) {
77 return false;
78 }
79 __cpuid_count(level, 0, eax, ebx, ecx, edx);
80 return (edx & bits) == bits;
81}
82
83static const char sSSE2Message[] =
84 "This browser version requires a processor with the SSE2 instruction "
85 "set extension.\nYou may be able to obtain a version that does not "
86 "require SSE2 from your Linux distribution.\n";
87
88__attribute__((constructor)) static void SSE2Check() {
89 if (IsSSE2Available()) {
90 return;
91 }
92 // Using write() in order to avoid jemalloc-based buffering. Ignoring return
93 // values, since there isn't much we could do on failure and there is no
94 // point in trying to recover from errors.
95 MOZ_UNUSED(do { if (write(2, sSSE2Message, sizeof(mozilla::detail::ArrayLengthHelper
(sSSE2Message)) - 1)) { (void)0; } } while (0)
96 write(STDERR_FILENO, sSSE2Message, MOZ_ARRAY_LENGTH(sSSE2Message) - 1))do { if (write(2, sSSE2Message, sizeof(mozilla::detail::ArrayLengthHelper
(sSSE2Message)) - 1)) { (void)0; } } while (0)
;
97 // _exit() instead of exit() to avoid running the usual "at exit" code.
98 _exit(255);
99}
100#endif
101
102#if !defined(MOZ_WIDGET_COCOA) && !defined(MOZ_WIDGET_ANDROID)
103# define MOZ_BROWSER_CAN_BE_CONTENTPROC
104#endif
105
106using namespace mozilla;
107
108#ifdef XP_MACOSX
109# define kOSXResourcesFolder "Resources"
110#endif
111#define kDesktopFolder"browser" "browser"
112
113static MOZ_FORMAT_PRINTF(1, 2)__attribute__((format(printf, 1, 2))) void Output(const char* fmt, ...) {
114 va_list ap;
115 va_start(ap, fmt)__builtin_va_start(ap, fmt);
116
117#ifndef XP_WIN
118 vfprintf(stderrstderr, fmt, ap);
119#else
120 char msg[2048];
121 vsnprintf_s(msg, _countof(msg), _TRUNCATE, fmt, ap);
122
123 wchar_t wide_msg[2048];
124 MultiByteToWideChar(CP_UTF8, 0, msg, -1, wide_msg, _countof(wide_msg));
125# if MOZ_WINCONSOLE
126 fwprintf_s(stderrstderr, wide_msg);
127# else
128 // Linking user32 at load-time interferes with the DLL blocklist (bug 932100).
129 // This is a rare codepath, so we can load user32 at run-time instead.
130 HMODULE user32 = LoadLibraryW(L"user32.dll");
131 if (user32) {
132 decltype(MessageBoxW)* messageBoxW =
133 (decltype(MessageBoxW)*)GetProcAddress(user32, "MessageBoxW");
134 if (messageBoxW) {
135 messageBoxW(nullptr, wide_msg, L"Firefox",
136 MB_OK | MB_ICONERROR | MB_SETFOREGROUND);
137 }
138 FreeLibrary(user32);
139 }
140# endif
141#endif
142
143 va_end(ap)__builtin_va_end(ap);
144}
145
146/**
147 * Return true if |arg| matches the given argument name.
148 */
149static bool IsArg(const char* arg, const char* s) {
150 if (*arg == '-') {
151 if (*++arg == '-') ++arg;
152 return !strcasecmp(arg, s);
153 }
154
155#if defined(XP_WIN)
156 if (*arg == '/') return !strcasecmp(++arg, s);
157#endif
158
159 return false;
160}
161
162Bootstrap::UniquePtr gBootstrap;
163
164static int do_main(int argc, char* argv[], char* envp[]) {
165 // Allow firefox.exe to launch XULRunner apps via -app <application.ini>
166 // Note that -app must be the *first* argument.
167 const char* appDataFile = getenv("XUL_APP_FILE");
168 if ((!appDataFile
6.1
'appDataFile' is null
|| !*appDataFile) && (argc
6.2
'argc' is > 1
> 1 && IsArg(argv[1], "app"))) {
7
Taking true branch
169 if (argc == 2) {
8
Assuming 'argc' is not equal to 2
9
Taking false branch
170 Output("Incorrect number of arguments passed to -app");
171 return 255;
172 }
173 appDataFile = argv[2];
174
175 char appEnv[MAXPATHLEN4096];
176 SprintfLiteral(appEnv, "XUL_APP_FILE=%s", argv[2]);
177 if (putenv(strdup(appEnv))) {
10
Memory is allocated
11
Assuming the condition is false
12
Taking false branch
178 Output("Couldn't set %s.\n", appEnv);
179 return 255;
180 }
181 argv[2] = argv[0];
13
Potential memory leak
182 argv += 2;
183 argc -= 2;
184 } else if (argc > 1 && IsArg(argv[1], "xpcshell")) {
185 for (int i = 1; i < argc; i++) {
186 argv[i] = argv[i + 1];
187 }
188
189 XREShellData shellData;
190#if defined(XP_WIN) && defined(MOZ_SANDBOX1)
191 shellData.sandboxBrokerServices =
192 sandboxing::GetInitializedBrokerServices();
193#endif
194
195#ifdef LIBFUZZER
196 shellData.fuzzerDriver = fuzzer::FuzzerDriver;
197#endif
198#ifdef AFLFUZZ
199 shellData.fuzzerDriver = afl_interface_raw;
200#endif
201
202 return gBootstrap->XRE_XPCShellMain(--argc, argv, envp, &shellData);
203 }
204
205 BootstrapConfig config;
206
207 if (appDataFile && *appDataFile) {
208 config.appData = nullptr;
209 config.appDataPath = appDataFile;
210 } else {
211 // no -app flag so we use the compiled-in app data
212 config.appData = &sAppData;
213 config.appDataPath = kDesktopFolder"browser";
214 }
215
216#if defined(XP_WIN) && defined(MOZ_SANDBOX1)
217 sandbox::BrokerServices* brokerServices =
218 sandboxing::GetInitializedBrokerServices();
219 if (!brokerServices) {
220 Output("Couldn't initialize the broker services.\n");
221 return 255;
222 }
223 config.sandboxBrokerServices = brokerServices;
224#endif
225
226#ifdef LIBFUZZER
227 if (getenv("FUZZER"))
228 gBootstrap->XRE_LibFuzzerSetDriver(fuzzer::FuzzerDriver);
229#endif
230
231 EnsureBrowserCommandlineSafe(argc, argv);
232
233 return gBootstrap->XRE_main(argc, argv, config);
234}
235
236static nsresult InitXPCOMGlue(LibLoadingStrategy aLibLoadingStrategy) {
237 if (gBootstrap) {
238 return NS_OK;
239 }
240
241 UniqueFreePtr<char> exePath = BinaryPath::Get();
242 if (!exePath) {
243 Output("Couldn't find the application directory.\n");
244 return NS_ERROR_FAILURE;
245 }
246
247 auto bootstrapResult =
248 mozilla::GetBootstrap(exePath.get(), aLibLoadingStrategy);
249 if (bootstrapResult.isErr()) {
250 Output("Couldn't load XPCOM.\n");
251 return NS_ERROR_FAILURE;
252 }
253
254 gBootstrap = bootstrapResult.unwrap();
255
256 // This will set this thread as the main thread.
257 gBootstrap->NS_LogInit();
258
259 return NS_OK;
260}
261
262#ifdef HAS_DLL_BLOCKLIST
263// NB: This must be extern, as this value is checked elsewhere
264uint32_t gBlocklistInitFlags = eDllBlocklistInitFlagDefault;
265#endif
266
267#if defined(XP_UNIX1)
268static void ReserveDefaultFileDescriptors() {
269 // Reserve the lower positions of the file descriptors to make sure
270 // we don't reuse stdin/stdout/stderr in case they we closed
271 // before launch.
272 // Otherwise code explicitly writing to fd 1 or 2 might accidentally
273 // write to something else, like in bug 1820896 where FD 1 is
274 // reused for the X server display connection.
275 int fd = open("/dev/null", O_RDONLY00);
276 for (int i = 0; i < 2; i++) {
277 mozilla::Unused << dup(fd);
278 }
279}
280#endif
281
282int main(int argc, char* argv[], char* envp[]) {
283#if defined(XP_UNIX1)
284 ReserveDefaultFileDescriptors();
285#endif
286
287#ifdef MOZ_BROWSER_CAN_BE_CONTENTPROC
288 if (argc > 1 && IsArg(argv[1], "contentproc")) {
1
Assuming 'argc' is > 1
2
Taking false branch
289 // Set the process type and gecko child id.
290 SetGeckoProcessType(argv[--argc]);
291 SetGeckoChildID(argv[--argc]);
292
293# if defined(MOZ_ENABLE_FORKSERVER1)
294 if (GetGeckoProcessType() == GeckoProcessType_ForkServer) {
295 nsresult rv = InitXPCOMGlue(LibLoadingStrategy::NoReadAhead);
296 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
297 return 255;
298 }
299
300 // Run a fork server in this process, single thread. When it returns, it
301 // means the fork server have been stopped or a new child process is
302 // created.
303 //
304 // For the latter case, XRE_ForkServer() will return false, running in a
305 // child process just forked from the fork server process. argc & argv
306 // will be updated with the values passing from the chrome process, as
307 // will GeckoProcessType and GeckoChildID. With the new values, this
308 // function continues the reset of the code acting as a child process.
309 if (gBootstrap->XRE_ForkServer(&argc, &argv)) {
310 // Return from the fork server in the fork server process.
311 // Stop the fork server.
312 // InitXPCOMGlue calls NS_LogInit, so we need to balance it here.
313 gBootstrap->NS_LogTerm();
314 return 0;
315 }
316 }
317# endif
318 }
319#endif
320
321 mozilla::TimeStamp start = mozilla::TimeStamp::Now();
322
323 AUTO_BASE_PROFILER_INIT::mozilla::baseprofiler::AutoProfilerInit raiiObject323;
324 AUTO_BASE_PROFILER_LABEL("nsBrowserApp main", OTHER)::mozilla::baseprofiler::AutoProfilerLabel raiiObject324( "nsBrowserApp main"
, nullptr, ::mozilla::baseprofiler::ProfilingCategoryPair::OTHER
)
;
325
326 // Register an external module to report on otherwise uncatchable exceptions.
327 // Note that in child processes this must be called after Gecko process type
328 // has been set.
329 CrashReporter::RegisterRuntimeExceptionModule();
330
331 // Make sure we unregister the runtime exception module before returning.
332 auto unregisterRuntimeExceptionModule =
333 MakeScopeExit([] { CrashReporter::UnregisterRuntimeExceptionModule(); });
334
335#ifdef MOZ_BROWSER_CAN_BE_CONTENTPROC
336 // We are launching as a content process, delegate to the appropriate
337 // main
338 if (GetGeckoProcessType() != GeckoProcessType_Default) {
3
Assuming the condition is false
4
Taking false branch
339# if defined(XP_WIN) && defined(MOZ_SANDBOX1)
340 // We need to set whether our process is supposed to have win32k locked down
341 // from the command line setting before DllBlocklist_Initialize,
342 // GetInitializedTargetServices and WindowsDpiInitialization.
343 Maybe<bool> win32kLockedDown =
344 mozilla::geckoargs::sWin32kLockedDown.Get(argc, argv);
345 if (win32kLockedDown.isSome() && *win32kLockedDown) {
346 mozilla::SetWin32kLockedDownInPolicy();
347 }
348# endif
349
350# ifdef HAS_DLL_BLOCKLIST
351 uint32_t initFlags =
352 gBlocklistInitFlags | eDllBlocklistInitFlagIsChildProcess;
353 SetDllBlocklistProcessTypeFlags(initFlags, GetGeckoProcessType());
354 DllBlocklist_Initialize(initFlags);
355# endif // HAS_DLL_BLOCKLIST
356
357# if defined(XP_WIN) && defined(MOZ_SANDBOX1)
358 // We need to initialize the sandbox TargetServices before InitXPCOMGlue
359 // because we might need the sandbox broker to give access to some files.
360 if (IsSandboxedProcess() && !sandboxing::GetInitializedTargetServices()) {
361 Output("Failed to initialize the sandbox target services.");
362 return 255;
363 }
364# endif
365# if defined(XP_WIN)
366 // Ideally, we would be able to set our DPI awareness in
367 // firefox.exe.manifest Unfortunately, that would cause Win32k calls when
368 // user32.dll gets loaded, which would be incompatible with Win32k Lockdown
369 //
370 // MSDN says that it's allowed-but-not-recommended to initialize DPI
371 // programatically, as long as it's done before any HWNDs are created.
372 // Thus, we do it almost as soon as we possibly can
373 {
374 auto result = mozilla::WindowsDpiInitialization();
375 (void)result; // Ignore errors since some tools block DPI calls
376 }
377# endif
378
379 nsresult rv = InitXPCOMGlue(LibLoadingStrategy::NoReadAhead);
380 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
381 return 255;
382 }
383
384 XREChildData childData;
385
386# if defined(XP_WIN) && defined(MOZ_SANDBOX1)
387 if (IsSandboxedProcess()) {
388 childData.sandboxTargetServices =
389 mozilla::sandboxing::GetInitializedTargetServices();
390 if (!childData.sandboxTargetServices) {
391 return 1;
392 }
393
394 childData.ProvideLogFunction = mozilla::sandboxing::ProvideLogFunction;
395 }
396
397 if (GetGeckoProcessType() == GeckoProcessType_RemoteSandboxBroker) {
398 childData.sandboxBrokerServices =
399 mozilla::sandboxing::GetInitializedBrokerServices();
400 }
401# endif
402
403 rv = gBootstrap->XRE_InitChildProcess(argc, argv, &childData);
404
405# if defined(DEBUG1) && defined(HAS_DLL_BLOCKLIST)
406 DllBlocklist_Shutdown();
407# endif
408
409 // InitXPCOMGlue calls NS_LogInit, so we need to balance it here.
410 gBootstrap->NS_LogTerm();
411
412 return NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0))) ? 1 : 0;
413 }
414#endif
415
416#ifdef HAS_DLL_BLOCKLIST
417 DllBlocklist_Initialize(gBlocklistInitFlags);
418#endif
419
420// We will likely only ever support this as a command line argument on Windows
421// and OSX, so we're ifdefing here just to not create any expectations.
422#if defined(XP_WIN) || defined(XP_MACOSX)
423 if (argc > 1 && IsArg(argv[1], "silentmode")) {
424 ::putenv(const_cast<char*>("MOZ_APP_SILENT_START=1"));
425# if defined(XP_WIN)
426 // On windows We also want to set a separate variable, which we want to
427 // persist across restarts, which will let us keep the process alive
428 // even if the last window is closed.
429 ::putenv(const_cast<char*>("MOZ_APP_ALLOW_WINDOWLESS=1"));
430# endif
431# if defined(XP_MACOSX)
432 ::putenv(const_cast<char*>("MOZ_APP_NO_DOCK=1"));
433# endif
434 }
435#endif
436
437#if defined(XP_WIN)
438
439 // Ideally, we would be able to set our DPI awareness in firefox.exe.manifest
440 // Unfortunately, that would cause Win32k calls when user32.dll gets loaded,
441 // which would be incompatible with Win32k Lockdown
442 //
443 // MSDN says that it's allowed-but-not-recommended to initialize DPI
444 // programatically, as long as it's done before any HWNDs are created.
445 // Thus, we do it almost as soon as we possibly can
446 {
447 auto result = mozilla::WindowsDpiInitialization();
448 (void)result; // Ignore errors since some tools block DPI calls
449 }
450
451 // Once the browser process hits the main function, we no longer need
452 // a writable section handle because all dependent modules have been
453 // loaded.
454 mozilla::freestanding::gSharedSection.ConvertToReadOnly();
455
456 mozilla::CreateAndStorePreXULSkeletonUI(GetModuleHandle(nullptr), argc, argv);
457#endif
458
459 nsresult rv = InitXPCOMGlue(LibLoadingStrategy::ReadAhead);
460 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
5
Taking false branch
461 return 255;
462 }
463
464 gBootstrap->XRE_StartupTimelineRecord(mozilla::StartupTimeline::START, start);
465
466#ifdef MOZ_BROWSER_CAN_BE_CONTENTPROC
467 gBootstrap->XRE_EnableSameExecutableForContentProc();
468#endif
469
470 int result = do_main(argc, argv, envp);
6
Calling 'do_main'
471
472#if defined(XP_WIN)
473 CleanupProcessRuntime();
474#endif
475
476 gBootstrap->NS_LogTerm();
477
478#if defined(DEBUG1) && defined(HAS_DLL_BLOCKLIST)
479 DllBlocklist_Shutdown();
480#endif
481
482#ifdef XP_MACOSX
483 // Allow writes again. While we would like to catch writes from static
484 // destructors to allow early exits to use _exit, we know that there is
485 // at least one such write that we don't control (see bug 826029). For
486 // now we enable writes again and early exits will have to use exit instead
487 // of _exit.
488 gBootstrap->XRE_StopLateWriteChecks();
489#endif
490
491 gBootstrap.reset();
492
493 return result;
494}