gecko-dev/ipc/app/MozillaRuntimeMain.cpp
Aaron Klotz 004362bf3e Bug 1690384: Propagate error information up through XPCOMGlueLoad and GetBootstrap; r=glandium
We know that some GV installations (particularly but not exlcusively Focus) are
failing to load `libxul.so` during early Gecko bootstrapping. Unfortunately
a boolean pass/fail result is not giving us sufficient information to be able to
properly troubleshoot this problem.

This patch adds `mozilla::Result`-based return values to `XPCOMGlueLoad` and
`GetBootstrap` in an effort to produce more actionable information about these
failures.

We include either a `nsresult` or, if the failure is rooted in a dynamic linker
failure, appropriate platform-specific error information:

* On Unix-based platforms, a `UniqueFreePtr<char>` containing the string from `dlerror(3)`;
* On Windows, the Win32 `DWORD` error code from `GetLastError()`.

For non-Android platforms, I updated them to handle the new return type, but
otherwise did not make any further changes.

For Android, we include the error information in the message string that we pass
into the Java `Exception` that is subsequently thrown.

Differential Revision: https://phabricator.services.mozilla.com/D104263
2021-02-23 23:25:22 +00:00

81 lines
2.3 KiB
C++

/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "../contentproc/plugin-container.cpp"
#include "mozilla/Bootstrap.h"
#if defined(XP_WIN)
# include "mozilla/WindowsDllBlocklist.h"
#endif // defined(XP_WIN)
using namespace mozilla;
static bool UseForkServer(int argc, char* argv[]) {
#if defined(MOZ_ENABLE_FORKSERVER)
return strcmp(argv[argc - 1], "forkserver") == 0;
#else
return false;
#endif
}
static int RunForkServer(Bootstrap::UniquePtr&& bootstrap, int argc,
char* argv[]) {
#if defined(MOZ_ENABLE_FORKSERVER)
int ret = 0;
bootstrap->NS_LogInit();
// Run a fork server in this process, single thread. When it
// returns, it means the fork server have been stopped or a new
// content process is created.
//
// For the later case, XRE_ForkServer() will return false, running
// in a content process just forked from the fork server process.
// argc & argv will be updated with the values passing from the
// chrome process. With the new values, this function
// continues the reset of the code acting as a content process.
if (bootstrap->XRE_ForkServer(&argc, &argv)) {
// Return from the fork server in the fork server process.
// Stop the fork server.
} else {
// In a content process forked from the fork server.
// Start acting as a content process.
ret = content_process_main(bootstrap.get(), argc, argv);
}
bootstrap->NS_LogTerm();
return ret;
#else
return 0;
#endif
}
int main(int argc, char* argv[]) {
auto bootstrapResult = GetBootstrap();
if (bootstrapResult.isErr()) {
return 2;
}
Bootstrap::UniquePtr bootstrap = bootstrapResult.unwrap();
int ret;
if (UseForkServer(argc, argv)) {
ret = RunForkServer(std::move(bootstrap), argc, argv);
} else {
#ifdef HAS_DLL_BLOCKLIST
DllBlocklist_Initialize(eDllBlocklistInitFlagIsChildProcess);
#endif
ret = content_process_main(bootstrap.get(), argc, argv);
#if defined(DEBUG) && defined(HAS_DLL_BLOCKLIST)
DllBlocklist_Shutdown();
#endif
}
return ret;
}