Bug 1258663 - Crash annotate system call failures in the IPC transport. r=gabor
authorCervantes Yu <cyu@mozilla.com>
Fri, 01 Apr 2016 14:33:52 +0800
changeset 291196 f71f7068c9f0de5d9a006c67c4d1e397dc3b0b0b
parent 291195 5d5b5862ab90e00fcf4c9737dbe4f810f9a7dae3
child 291197 50ab25f4ea759f2910bb9a0ba942c963c8de05d7
push id19656
push usergwagner@mozilla.com
push dateMon, 04 Apr 2016 13:43:23 +0000
treeherderb2g-inbound@e99061fde28a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersgabor
bugs1258663
milestone48.0a1
Bug 1258663 - Crash annotate system call failures in the IPC transport. r=gabor
ipc/glue/ProtocolUtils.cpp
ipc/glue/ProtocolUtils.h
ipc/glue/Transport_posix.cpp
ipc/glue/Transport_win.cpp
--- a/ipc/glue/ProtocolUtils.cpp
+++ b/ipc/glue/ProtocolUtils.cpp
@@ -2,16 +2,20 @@
  * vim: sw=2 ts=8 et :
  */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "base/process_util.h"
 
+#ifdef OS_POSIX
+#include <errno.h>
+#endif
+
 #include "mozilla/ipc/MessageChannel.h"
 #include "mozilla/ipc/ProtocolUtils.h"
 #include "mozilla/ipc/Transport.h"
 #include "mozilla/StaticMutex.h"
 
 #if defined(MOZ_SANDBOX) && defined(XP_WIN)
 #define TARGET_SANDBOX_EXPORTS
 #include "mozilla/sandboxTarget.h"
@@ -290,16 +294,32 @@ bool DuplicateHandle(HANDLE aSourceHandl
   }
 
   return !!::DuplicateHandle(::GetCurrentProcess(), aSourceHandle,
                               targetProcess, aTargetHandle,
                               aDesiredAccess, FALSE, aOptions);
 }
 #endif
 
+#ifdef MOZ_CRASHREPORTER
+void AnnotateSystemError()
+{
+  int64_t error = 0;
+#if defined(XP_WIN)
+  error = ::GetLastError();
+#elif defined(OS_POSIX)
+  error = errno;
+#endif
+  if (error) {
+    CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("SystemError"),
+                                       nsPrintfCString("%lld", error));
+  }
+}
+#endif
+
 void
 ProtocolErrorBreakpoint(const char* aMsg)
 {
     // Bugs that generate these error messages can be tough to
     // reproduce.  Log always in the hope that someone finds the error
     // message.
     printf_stderr("IPDL protocol error: %s\n", aMsg);
 }
@@ -320,16 +340,17 @@ FatalError(const char* aProtocolName, co
     // there's no other really nice way of getting a minidump out of
     // this process if we're off the main thread.
     formattedMessage.AppendLiteral("\". Intentionally crashing.");
     NS_ERROR(formattedMessage.get());
     CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("IPCFatalErrorProtocol"),
                                        nsDependentCString(aProtocolName));
     CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("IPCFatalErrorMsg"),
                                        nsDependentCString(aMsg));
+    AnnotateSystemError();
 #endif
     MOZ_CRASH("IPC FatalError in the parent process!");
   } else {
     formattedMessage.AppendLiteral("\". abort()ing as a result.");
     NS_RUNTIMEABORT(formattedMessage.get());
   }
 }
 
--- a/ipc/glue/ProtocolUtils.h
+++ b/ipc/glue/ProtocolUtils.h
@@ -329,16 +329,26 @@ bool
 DuplicateHandle(HANDLE aSourceHandle,
                 DWORD aTargetProcessId,
                 HANDLE* aTargetHandle,
                 DWORD aDesiredAccess,
                 DWORD aOptions);
 #endif
 
 /**
+ * Annotate the crash reporter with the error error code from the most recent
+ * system call.
+ */
+#ifdef MOZ_CRASHREPORTER
+void AnnotateSystemError();
+#else
+#define AnnotateSystemError() do { } while (0)
+#endif
+
+/**
  * An endpoint represents one end of a partially initialized IPDL channel. To
  * set up a new top-level protocol:
  *
  * Endpoint<PFooParent> parentEp;
  * Endpoint<PFooChild> childEp;
  * nsresult rv;
  * rv = PFoo::CreateEndpoints(parentPid, childPid, &parentEp, &childEp);
  *
--- a/ipc/glue/Transport_posix.cpp
+++ b/ipc/glue/Transport_posix.cpp
@@ -10,16 +10,17 @@
 #include <string>
 
 #include "base/eintr_wrapper.h"
 
 #include "chrome/common/child_process_info.h"
 
 #include "mozilla/ipc/Transport.h"
 #include "mozilla/ipc/FileDescriptor.h"
+#include "ProtocolUtils.h"
 
 using namespace std;
 
 using base::ProcessHandle;
 
 namespace mozilla {
 namespace ipc {
 
@@ -65,16 +66,19 @@ OpenDescriptor(const FileDescriptor& aFd
   return new Transport(aFd.PlatformHandle(), aMode, nullptr);
 }
 
 TransportDescriptor
 DuplicateDescriptor(const TransportDescriptor& aTd)
 {
   TransportDescriptor result = aTd;
   result.mFd.fd = dup(aTd.mFd.fd);
+  if (result.mFd.fd == -1) {
+    AnnotateSystemError();
+  }
   MOZ_RELEASE_ASSERT(result.mFd.fd != -1, "DuplicateDescriptor failed");
   return result;
 }
 
 void
 CloseDescriptor(const TransportDescriptor& aTd)
 {
   close(aTd.mFd.fd);
--- a/ipc/glue/Transport_win.cpp
+++ b/ipc/glue/Transport_win.cpp
@@ -59,16 +59,19 @@ TransferHandleToProcess(HANDLE source, b
 
   if (source == INVALID_HANDLE_VALUE) {
     return source;
   }
   HANDLE handleDup;
   DWORD access = 0;
   DWORD options = DUPLICATE_SAME_ACCESS;
   bool ok = DuplicateHandle(source, pid, &handleDup, access, options);
+  if (!ok) {
+    AnnotateSystemError();
+  }
   MOZ_RELEASE_ASSERT(ok);
 
   // Now close our own copy of the handle (we're supposed to be transferring,
   // not copying).
   CloseHandle(source);
 
   return handleDup;
 }
@@ -98,16 +101,19 @@ DuplicateDescriptor(const TransportDescr
     return aTd;
   }
 
   HANDLE serverDup;
   DWORD access = 0;
   DWORD options = DUPLICATE_SAME_ACCESS;
   bool ok = DuplicateHandle(aTd.mServerPipeHandle, base::GetCurrentProcId(),
                             &serverDup, access, options);
+  if (!ok) {
+    AnnotateSystemError();
+  }
   MOZ_RELEASE_ASSERT(ok);
 
   TransportDescriptor desc = aTd;
   desc.mServerPipeHandle = serverDup;
   return desc;
 }
 
 void