Bug 1461459: Add nightly-only release asserts in GeckoChildProcessHost::PerformAsyncLaunchInternal to investigate failures to asynchronously launch content processes. r=jld
authorStephen A Pohl <spohl.mozilla.bugs@gmail.com>
Tue, 05 Jun 2018 21:12:20 -0400
changeset 421527 25f96c342f93d6f5bd60d8c4b3573887377cbf6e
parent 421526 5a34a56825e8d40140808a2543e29ced97bfd448
child 421528 355fe159b162e11b4dd54b8b4b119f974adfe4ed
push id34096
push usernbeleuzu@mozilla.com
push dateWed, 06 Jun 2018 09:37:23 +0000
treeherdermozilla-central@cec4a3cecc29 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjld
bugs1461459
milestone62.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 1461459: Add nightly-only release asserts in GeckoChildProcessHost::PerformAsyncLaunchInternal to investigate failures to asynchronously launch content processes. r=jld
ipc/glue/GeckoChildProcessHost.cpp
--- a/ipc/glue/GeckoChildProcessHost.cpp
+++ b/ipc/glue/GeckoChildProcessHost.cpp
@@ -622,32 +622,38 @@ AddAppDirToCommandLine(std::vector<std::
 }
 
 bool
 GeckoChildProcessHost::PerformAsyncLaunchInternal(std::vector<std::string>& aExtraOpts)
 {
   // We rely on the fact that InitializeChannel() has already been processed
   // on the IO thread before this point is reached.
   if (!GetChannel()) {
+#ifdef ASYNC_CONTENTPROC_LAUNCH
+    MOZ_RELEASE_ASSERT(1 == 2);
+#endif
     return false;
   }
 
   base::ProcessHandle process = 0;
 
   // send the child the PID so that it can open a ProcessHandle back to us.
   // probably don't want to do this in the long run
   char pidstring[32];
   SprintfLiteral(pidstring, "%d", base::GetCurrentProcId());
 
   const char* const childProcessType =
       XRE_ChildProcessTypeToString(mProcessType);
 
   PRFileDesc* crashAnnotationReadPipe;
   PRFileDesc* crashAnnotationWritePipe;
   if (PR_CreatePipe(&crashAnnotationReadPipe, &crashAnnotationWritePipe) != PR_SUCCESS) {
+#ifdef ASYNC_CONTENTPROC_LAUNCH
+    MOZ_RELEASE_ASSERT(2 == 3);
+#endif
     return false;
   }
 
 //--------------------------------------------------
 #if defined(OS_POSIX)
   // For POSIX, we have to be extremely anal about *not* using
   // std::wstring in code compiled with Mozilla's -fshort-wchar
   // configuration, because chromium is compiled with -fno-short-wchar
@@ -828,27 +834,36 @@ GeckoChildProcessHost::PerformAsyncLaunc
   const int kTimeoutMs = 10000;
 
   MachReceiveMessage child_message;
   ReceivePort parent_recv_port(mach_connection_name.c_str());
   kern_return_t err = parent_recv_port.WaitForMessage(&child_message, kTimeoutMs);
   if (err != KERN_SUCCESS) {
     std::string errString = StringPrintf("0x%x %s", err, mach_error_string(err));
     CHROMIUM_LOG(ERROR) << "parent WaitForMessage() failed: " << errString;
+#ifdef ASYNC_CONTENTPROC_LAUNCH
+    MOZ_RELEASE_ASSERT(3 == 4);
+#endif
     return false;
   }
 
   task_t child_task = child_message.GetTranslatedPort(0);
   if (child_task == MACH_PORT_NULL) {
     CHROMIUM_LOG(ERROR) << "parent GetTranslatedPort(0) failed.";
+#ifdef ASYNC_CONTENTPROC_LAUNCH
+    MOZ_RELEASE_ASSERT(4 == 5);
+#endif
     return false;
   }
 
   if (child_message.GetTranslatedPort(1) == MACH_PORT_NULL) {
     CHROMIUM_LOG(ERROR) << "parent GetTranslatedPort(1) failed.";
+#ifdef ASYNC_CONTENTPROC_LAUNCH
+    MOZ_RELEASE_ASSERT(5 == 6);
+#endif
     return false;
   }
   MachPortSender parent_sender(child_message.GetTranslatedPort(1));
 
   if (child_message.GetTranslatedPort(2) == MACH_PORT_NULL) {
     CHROMIUM_LOG(ERROR) << "parent GetTranslatedPort(2) failed.";
   }
   auto* parent_recv_port_memory_ack = new MachPortSender(child_message.GetTranslatedPort(2));
@@ -856,35 +871,47 @@ GeckoChildProcessHost::PerformAsyncLaunc
   if (child_message.GetTranslatedPort(3) == MACH_PORT_NULL) {
     CHROMIUM_LOG(ERROR) << "parent GetTranslatedPort(3) failed.";
   }
   auto* parent_send_port_memory = new MachPortSender(child_message.GetTranslatedPort(3));
 
   MachSendMessage parent_message(/* id= */0);
   if (!parent_message.AddDescriptor(MachMsgPortDescriptor(bootstrap_port))) {
     CHROMIUM_LOG(ERROR) << "parent AddDescriptor(" << bootstrap_port << ") failed.";
+#ifdef ASYNC_CONTENTPROC_LAUNCH
+    MOZ_RELEASE_ASSERT(6 == 7);
+#endif
     return false;
   }
 
   auto* parent_recv_port_memory = new ReceivePort();
   if (!parent_message.AddDescriptor(MachMsgPortDescriptor(parent_recv_port_memory->GetPort()))) {
     CHROMIUM_LOG(ERROR) << "parent AddDescriptor(" << parent_recv_port_memory->GetPort() << ") failed.";
+#ifdef ASYNC_CONTENTPROC_LAUNCH
+    MOZ_RELEASE_ASSERT(7 == 8);
+#endif
     return false;
   }
 
   auto* parent_send_port_memory_ack = new ReceivePort();
   if (!parent_message.AddDescriptor(MachMsgPortDescriptor(parent_send_port_memory_ack->GetPort()))) {
     CHROMIUM_LOG(ERROR) << "parent AddDescriptor(" << parent_send_port_memory_ack->GetPort() << ") failed.";
+#ifdef ASYNC_CONTENTPROC_LAUNCH
+    MOZ_RELEASE_ASSERT(8 == 9);
+#endif
     return false;
   }
 
   err = parent_sender.SendMessage(parent_message, kTimeoutMs);
   if (err != KERN_SUCCESS) {
     std::string errString = StringPrintf("0x%x %s", err, mach_error_string(err));
     CHROMIUM_LOG(ERROR) << "parent SendMessage() failed: " << errString;
+#ifdef ASYNC_CONTENTPROC_LAUNCH
+    MOZ_RELEASE_ASSERT(9 == 10);
+#endif
     return false;
   }
 
   SharedMemoryBasic::SetupMachMemory(process, parent_recv_port_memory, parent_recv_port_memory_ack,
                                      parent_send_port_memory, parent_send_port_memory_ack, false);
 
 # endif // MOZ_WIDGET_COCOA
 
@@ -943,26 +970,32 @@ GeckoChildProcessHost::PerformAsyncLaunc
       }
 #  endif // defined(MOZ_CONTENT_SANDBOX)
       break;
     case GeckoProcessType_Plugin:
       if (mSandboxLevel > 0 &&
           !PR_GetEnv("MOZ_DISABLE_NPAPI_SANDBOX")) {
         bool ok = mSandboxBroker.SetSecurityLevelForPluginProcess(mSandboxLevel);
         if (!ok) {
+#ifdef ASYNC_CONTENTPROC_LAUNCH
+          MOZ_RELEASE_ASSERT(10 == 11);
+#endif
           return false;
         }
         shouldSandboxCurrentProcess = true;
       }
       break;
 #ifdef MOZ_ENABLE_SKIA_PDF
     case GeckoProcessType_PDFium:
       if (!PR_GetEnv("MOZ_DISABLE_PDFIUM_SANDBOX")) {
         bool ok = mSandboxBroker.SetSecurityLevelForPDFiumProcess();
         if (!ok) {
+#ifdef ASYNC_CONTENTPROC_LAUNCH
+          MOZ_RELEASE_ASSERT(11 == 12);
+#endif
           return false;
         }
         shouldSandboxCurrentProcess = true;
       }
       break;
 #endif
     case GeckoProcessType_IPDLUnitTest:
       // XXX: We don't sandbox this process type yet
@@ -973,16 +1006,19 @@ GeckoChildProcessHost::PerformAsyncLaunc
         // not at USER_LOCKDOWN. So look in the command line arguments
         // to see if we're loading the path to the Widevine CDM, and if
         // so use sandbox level USER_RESTRICTED instead of USER_LOCKDOWN.
         bool isWidevine = std::any_of(aExtraOpts.begin(), aExtraOpts.end(),
           [](const std::string arg) { return arg.find("gmp-widevinecdm") != std::string::npos; });
         auto level = isWidevine ? SandboxBroker::Restricted : SandboxBroker::LockDown;
         bool ok = mSandboxBroker.SetSecurityLevelForGMPlugin(level);
         if (!ok) {
+#ifdef ASYNC_CONTENTPROC_LAUNCH
+          MOZ_RELEASE_ASSERT(12 == 13);
+#endif
           return false;
         }
         shouldSandboxCurrentProcess = true;
       }
       break;
     case GeckoProcessType_GPU:
       if (mSandboxLevel > 0 && !PR_GetEnv("MOZ_DISABLE_GPU_SANDBOX")) {
         // For now we treat every failure as fatal in SetSecurityLevelForGPUProcess
@@ -1082,16 +1118,19 @@ GeckoChildProcessHost::PerformAsyncLaunc
 # endif // MOZ_SANDBOX
   }
 
 #else // goes with defined(OS_POSIX)
 #  error Sorry
 #endif // defined(OS_POSIX)
 
   if (!process) {
+#ifdef ASYNC_CONTENTPROC_LAUNCH
+    MOZ_RELEASE_ASSERT(13 == 14);
+#endif
     return false;
   }
   // NB: on OS X, we block much longer than we need to in order to
   // reach this call, waiting for the child process's task_t.  The
   // best way to fix that is to refactor this file, hard.
 #if defined(MOZ_WIDGET_COCOA)
   mChildTask = child_task;
 #endif // defined(MOZ_WIDGET_COCOA)