Bug 1531030: Use MOZ_DISABLE_POISON_IO_INTERPOSER to disable PoisonIOInterposer when it is unsafe to initialize; r=erahm
authorAaron Klotz <aklotz@mozilla.com>
Fri, 01 Mar 2019 19:34:54 +0000
changeset 462034 7e2fced298cb76c55a36145780fb821ab1419cec
parent 462033 290bdcdf2b6336e218e8c2bf441dcfaddc26586c
child 462035 02dec1fe0aca13a3e4bbbace8100d3cdabce7f6f
push id112259
push userrmaries@mozilla.com
push dateSat, 02 Mar 2019 10:10:00 +0000
treeherdermozilla-inbound@d016ded4616b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerserahm
bugs1531030
milestone67.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1531030: Use MOZ_DISABLE_POISON_IO_INTERPOSER to disable PoisonIOInterposer when it is unsafe to initialize; r=erahm If we are running a background thread in the launcher process to log failures, then allowing the main thread to proceed with monkeypatching system calls is a Bad Idea. This patch gives us an environment variable that, when set, indicates that it is unsafe for PoisonIOInterposer to run. This scenario is an uncommon one, but one that we must account for nonetheless. Differential Revision: https://phabricator.services.mozilla.com/D21607
browser/app/winlauncher/ErrorHandler.cpp
xpcom/build/IOInterposer.cpp
--- a/browser/app/winlauncher/ErrorHandler.cpp
+++ b/browser/app/winlauncher/ErrorHandler.cpp
@@ -690,16 +690,23 @@ static bool SendPing(const mozilla::Laun
       launcherEnabled.unwrap() ==
           mozilla::LauncherRegistryInfo::EnabledState::ForceDisabled) {
     // If the launcher is force disabled, we do not send any pings
     // (since studies and thus telemetry have been opted out)
     return false;
   }
 #endif  // defined(MOZ_LAUNCHER_PROCESS)
 
+  // We send this ping when the launcher process fails. After we start the
+  // SendPingThread, this thread falls back from running as the launcher process
+  // to running as the browser main thread. Once this happens, it will be unsafe
+  // to set up PoisonIOInterposer (since we have already spun up a background
+  // thread).
+  mozilla::SaveToEnv("MOZ_DISABLE_POISON_IO_INTERPOSER=1");
+
   // Capture aError and our module list into context for processing on another
   // thread.
   auto thdParam = mozilla::MakeUnique<PingThreadContext>(aError);
 
   // The ping does a lot of file I/O. Since we want this thread to continue
   // executing browser startup, we should gather that information on a
   // background thread.
   uintptr_t thdHandle =
--- a/xpcom/build/IOInterposer.cpp
+++ b/xpcom/build/IOInterposer.cpp
@@ -17,16 +17,17 @@
 #include "mozilla/StaticPtr.h"
 #include "mozilla/ThreadLocal.h"
 #include "nscore.h"  // for NS_FREE_PERMANENT_DATA
 #if !defined(XP_WIN)
 #  include "NSPRInterposer.h"
 #endif  // !defined(XP_WIN)
 #include "nsXULAppAPI.h"
 #include "PoisonIOInterposer.h"
+#include "prenv.h"
 
 using namespace mozilla;
 
 namespace {
 
 /** Find if a vector contains a specific element */
 template <class T>
 bool VectorContains(const std::vector<T>& aVector, const T& aElement) {
@@ -391,17 +392,24 @@ bool IOInterposer::Init() {
   sThreadLocalDataInitialized = true;
   bool isMainThread = true;
   RegisterCurrentThread(isMainThread);
   sMasterList = new MasterList();
 
   MainThreadIOLogger::Init();
 
   // Now we initialize the various interposers depending on platform
-  InitPoisonIOInterposer();
+
+  // Under certain conditions it may be unsafe to initialize PoisonIOInterposer,
+  // such as when a background thread is already running. We set this variable
+  // elsewhere when such a condition applies.
+  if (!PR_GetEnv("MOZ_DISABLE_POISON_IO_INTERPOSER")) {
+    InitPoisonIOInterposer();
+  }
+
   // We don't hook NSPR on Windows because PoisonIOInterposer captures a
   // superset of the former's events.
 #if !defined(XP_WIN)
   InitNSPRIOInterposing();
 #endif
   return true;
 }