Bug 1488808 Part 3 - Store channel buffer's containing vector in untracked memory, r=mccr8.
authorBrian Hackett <bhackett1024@gmail.com>
Wed, 17 Oct 2018 10:00:01 -0600
changeset 490270 d9e7dfd8ce93c6b1c36ee07921a7ca853b4f0e19
parent 490269 33cf80c7214823e5e38307a666add7a0ef116e17
child 490271 4dd9ee253d32862d02c8abc578268338dd554ae2
push id247
push userfmarier@mozilla.com
push dateSat, 27 Oct 2018 01:06:44 +0000
reviewersmccr8
bugs1488808
milestone64.0a1
Bug 1488808 Part 3 - Store channel buffer's containing vector in untracked memory, r=mccr8.
toolkit/recordreplay/ipc/Channel.cpp
toolkit/recordreplay/ipc/Channel.h
--- a/toolkit/recordreplay/ipc/Channel.cpp
+++ b/toolkit/recordreplay/ipc/Channel.cpp
@@ -7,16 +7,17 @@
 #include "Channel.h"
 
 #include "ChildIPC.h"
 #include "ProcessRewind.h"
 #include "Thread.h"
 
 #include "MainThreadUtils.h"
 #include "nsXULAppAPI.h"
+#include "base/eintr_wrapper.h"
 #include "base/process_util.h"
 #include "mozilla/dom/ContentChild.h"
 #include "mozilla/ipc/FileDescriptor.h"
 
 #include <sys/socket.h>
 #include <sys/un.h>
 
 namespace mozilla {
@@ -60,16 +61,17 @@ struct HelloMessage
 };
 
 Channel::Channel(size_t aId, bool aMiddlemanRecording, const MessageHandler& aHandler)
   : mId(aId)
   , mHandler(aHandler)
   , mInitialized(false)
   , mConnectionFd(0)
   , mFd(0)
+  , mMessageBuffer(nullptr)
   , mMessageBytes(0)
 {
   MOZ_RELEASE_ASSERT(NS_IsMainThread());
 
   if (IsRecordingOrReplaying()) {
     MOZ_RELEASE_ASSERT(AreThreadEventsPassedThrough());
 
     mFd = socket(AF_UNIX, SOCK_STREAM, 0);
@@ -174,58 +176,60 @@ Channel::SendMessage(const Message& aMsg
     ptr += rv;
     nbytes -= rv;
   }
 }
 
 Message*
 Channel::WaitForMessage()
 {
-  if (!mMessageBuffer.length()) {
-    mMessageBuffer.appendN(0, PageSize);
+  if (!mMessageBuffer) {
+    mMessageBuffer = (MessageBuffer*) AllocateMemory(sizeof(MessageBuffer), MemoryKind::Generic);
+    mMessageBuffer->appendN(0, PageSize);
   }
 
   size_t messageSize = 0;
   while (true) {
     if (mMessageBytes >= sizeof(Message)) {
-      Message* msg = (Message*) mMessageBuffer.begin();
+      Message* msg = (Message*) mMessageBuffer->begin();
       messageSize = msg->mSize;
+      MOZ_RELEASE_ASSERT(messageSize >= sizeof(Message));
       if (mMessageBytes >= messageSize) {
         break;
       }
     }
 
     // Make sure the buffer is large enough for the entire incoming message.
-    if (messageSize > mMessageBuffer.length()) {
-      mMessageBuffer.appendN(0, messageSize - mMessageBuffer.length());
+    if (messageSize > mMessageBuffer->length()) {
+      mMessageBuffer->appendN(0, messageSize - mMessageBuffer->length());
     }
 
-    ssize_t nbytes = HANDLE_EINTR(recv(mFd, &mMessageBuffer[mMessageBytes],
-                                       mMessageBuffer.length() - mMessageBytes, 0));
+    ssize_t nbytes = HANDLE_EINTR(recv(mFd, &mMessageBuffer->begin()[mMessageBytes],
+                                       mMessageBuffer->length() - mMessageBytes, 0));
     if (nbytes < 0) {
       MOZ_RELEASE_ASSERT(errno == EAGAIN);
       continue;
     } else if (nbytes == 0) {
       // The other side of the channel has shut down.
       if (IsMiddleman()) {
         return nullptr;
       }
       PrintSpew("Channel disconnected, exiting...\n");
       _exit(0);
     }
 
     mMessageBytes += nbytes;
   }
 
-  Message* res = ((Message*)mMessageBuffer.begin())->Clone();
+  Message* res = ((Message*)mMessageBuffer->begin())->Clone();
 
   // Remove the message we just received from the incoming buffer.
   size_t remaining = mMessageBytes - messageSize;
   if (remaining) {
-    memmove(mMessageBuffer.begin(), &mMessageBuffer[messageSize], remaining);
+    memmove(mMessageBuffer->begin(), &mMessageBuffer->begin()[messageSize], remaining);
   }
   mMessageBytes = remaining;
 
   PrintMessage("RecvMsg", *res);
   return res;
 }
 
 void
--- a/toolkit/recordreplay/ipc/Channel.h
+++ b/toolkit/recordreplay/ipc/Channel.h
@@ -440,17 +440,18 @@ private:
 
   // Descriptor used to communicate with the other side.
   int mFd;
 
   // For synchronizing initialization of the channel.
   Monitor mMonitor;
 
   // Buffer for message data received from the other side of the channel.
-  InfallibleVector<char, 0, AllocPolicy<MemoryKind::Generic>> mMessageBuffer;
+  typedef InfallibleVector<char, 0, AllocPolicy<MemoryKind::Generic>> MessageBuffer;
+  MessageBuffer* mMessageBuffer;
 
   // The number of bytes of data already in the message buffer.
   size_t mMessageBytes;
 
   // If spew is enabled, print a message and associated info to stderr.
   void PrintMessage(const char* aPrefix, const Message& aMsg);
 
   // Block until a complete message is received from the other side of the