When a tracee fails to receive a message we sent it, drain that message from the socket buffer

Resolves #2628
diff --git a/src/AutoRemoteSyscalls.cc b/src/AutoRemoteSyscalls.cc
index 07e7649..3fd3658 100644
--- a/src/AutoRemoteSyscalls.cc
+++ b/src/AutoRemoteSyscalls.cc
@@ -433,15 +433,14 @@
   remote.task()->write_bytes_helper(remote_buf.get().cast<char>(),
     sizeof(msg), &msg, &ok);
 
-
   if (!ok) {
     return -ESRCH;
   }
   int ret = 0;
-  if (!has_socketcall_syscall(Arch::arch())) {
-    ret = remote.syscall(Arch::recvmsg, child_sock, msg.remote_msg(), 0);
-  } else {
+  if (has_socketcall_syscall(Arch::arch())) {
     ret = remote.syscall(Arch::socketcall, SYS_RECVMSG, msg.remote_sc_args());
+  } else {
+    ret = remote.syscall(Arch::recvmsg, child_sock, msg.remote_msg(), 0);
   }
   if (ret < 0) {
     return ret;
@@ -457,7 +456,7 @@
   fd_message<NativeArch> msg;
   struct msghdr *msgp = (struct msghdr*)&msg.msg;
   if (0 > recvmsg(sock, msgp, MSG_CMSG_CLOEXEC)) {
-    FATAL() << "Failed to receive fd";
+    return -1;
   }
 
   struct cmsghdr* cmsg = CMSG_FIRSTHDR(msgp);
@@ -493,6 +492,7 @@
   ASSERT(t, child_syscall_result > 0) << "Failed to sendmsg() in tracee; err="
                                       << errno_name(-child_syscall_result);
   int our_fd = recvmsg_socket(task()->session().tracee_socket_fd());
+  ASSERT(t, our_fd >= 0) << "Failed to receive fd";
   return ScopedFd(our_fd);
 }
 
@@ -511,7 +511,13 @@
   long child_syscall_result =
       child_recvmsg<Arch>(*this, task()->session().tracee_fd_number());
   if (child_syscall_result == -ESRCH) {
-    return ScopedFd();
+    /* The child did not receive the message. Read it out of the socket
+       buffer so it doesn't get read by another child later! */
+    int fd = recvmsg_socket(task()->session().tracee_socket_receiver_fd());
+    if (fd >= 0) {
+      close(fd);
+    }
+    return -ESRCH;
   }
   ASSERT(t, child_syscall_result >= 0) << "Failed to recvmsg() in tracee; err="
                                        << errno_name(-child_syscall_result);