Bug 1481009 Part 6 - Cleanly shutdown middleman processes after a recording/replaying child crashes, r=froydnj.
authorBrian Hackett <bhackett1024@gmail.com>
Mon, 13 Aug 2018 20:47:49 +0000
changeset 431320 41d3f63a86da3ac2a57c46afc40a99ab411539df
parent 431319 305a6de8a4579c3a2546d693a927f143e4c4e906
child 431321 a3bd72355db187ec1f492127d117f6d5796ce802
push id106418
push userbhackett@mozilla.com
push dateTue, 14 Aug 2018 00:10:02 +0000
treeherdermozilla-inbound@515c80e08cb9 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersfroydnj
bugs1481009
milestone63.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 1481009 Part 6 - Cleanly shutdown middleman processes after a recording/replaying child crashes, r=froydnj.
toolkit/crashreporter/CrashAnnotations.yaml
toolkit/recordreplay/ipc/Channel.cpp
toolkit/recordreplay/ipc/ChildProcess.cpp
toolkit/recordreplay/ipc/ParentForwarding.cpp
--- a/toolkit/crashreporter/CrashAnnotations.yaml
+++ b/toolkit/crashreporter/CrashAnnotations.yaml
@@ -573,16 +573,21 @@ ProxyStreamUnmarshalStatus:
     the various value this annotation can take.
   type: string
 
 ProxyStreamValid:
   description: >
     Set to "false" when encountering an invalid IPC proxy stream.
   type: string
 
+RecordReplayError:
+  description: >
+    Any fatal error that occurred while recording/replaying a tab.
+  type: string
+
 ReleaseChannel:
   description: >
     Application release channel (e.g. default, beta, ...)
   type: string
   ping: true
 
 RemoteType:
   description: >
--- a/toolkit/recordreplay/ipc/Channel.cpp
+++ b/toolkit/recordreplay/ipc/Channel.cpp
@@ -159,17 +159,23 @@ Channel::SendMessage(const Message& aMsg
   }
 
   PrintMessage("SendMsg", aMsg);
 
   const char* ptr = (const char*) &aMsg;
   size_t nbytes = aMsg.mSize;
   while (nbytes) {
     int rv = HANDLE_EINTR(send(mFd, ptr, nbytes, 0));
-    MOZ_RELEASE_ASSERT((size_t) rv <= nbytes);
+    if (rv < 0) {
+      // If the other side of the channel has crashed, don't send the message.
+      // Avoid crashing in this process too, so that we don't generate another
+      // minidump that masks the original crash.
+      MOZ_RELEASE_ASSERT(errno == EPIPE);
+      return;
+    }
     ptr += rv;
     nbytes -= rv;
   }
 }
 
 Message*
 Channel::WaitForMessage()
 {
--- a/toolkit/recordreplay/ipc/ChildProcess.cpp
+++ b/toolkit/recordreplay/ipc/ChildProcess.cpp
@@ -545,19 +545,19 @@ ChildProcessInfo::CanRestart()
 void
 ChildProcessInfo::AttemptRestart(const char* aWhy)
 {
   MOZ_RELEASE_ASSERT(NS_IsMainThread());
 
   PrintSpew("Warning: Child process died [%d]: %s\n", (int) GetId(), aWhy);
 
   if (!CanRestart()) {
-    nsAutoCString why(aWhy);
-    dom::ContentChild::GetSingleton()->SendRecordReplayFatalError(why);
-    Thread::WaitForeverNoIdle();
+    CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::RecordReplayError,
+                                       nsAutoCString(aWhy));
+    Shutdown();
   }
 
   mNumRestarts++;
 
   dom::ContentChild::GetSingleton()->SendTerminateReplayingProcess(mChannel->GetId());
 
   bool newPaused = mPaused;
   Message* newPausedMessage = mPausedMessage;
--- a/toolkit/recordreplay/ipc/ParentForwarding.cpp
+++ b/toolkit/recordreplay/ipc/ParentForwarding.cpp
@@ -317,17 +317,17 @@ public:
   }
 
   virtual void OnChannelClose() override {
     MOZ_RELEASE_ASSERT(mSide == ipc::ChildSide);
     MainThreadMessageLoop()->PostTask(NewRunnableFunction("Shutdown", Shutdown));
   }
 
   virtual void OnChannelError() override {
-    MOZ_CRASH("MiddlemanProtocol::OnChannelError");
+    MainThreadMessageLoop()->PostTask(NewRunnableFunction("Shutdown", Shutdown));
   }
 };
 
 static MiddlemanProtocol* gChildProtocol;
 static MiddlemanProtocol* gParentProtocol;
 
 ipc::MessageChannel*
 ChannelToUIProcess()