Bug 1481009 Part 6 - Cleanly shutdown middleman processes after a recording/replaying child crashes, r=froydnj.
☠☠ backed out by e3cec7443adf ☠ ☠
authorBrian Hackett <bhackett1024@gmail.com>
Wed, 08 Aug 2018 16:49:14 +0000
changeset 431103 4e6908123a97033d65fadd2cd04ce0118658c7e8
parent 431102 6869ea5ebd32246bfc155d0a5fa0ad0ea6619580
child 431104 4a0c7dd5e1acf4e3f517eeee51b6483de04af949
push id106352
push userbhackett@mozilla.com
push dateSat, 11 Aug 2018 14:55:04 +0000
treeherdermozilla-inbound@11ee868c5903 [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()