Bug 1258317 - Part 1: Annotate the crash report with process information on failure to transfer an IPC transport to another process. r?gabor draft
authorCervantes Yu <cyu@mozilla.com>
Tue, 19 Apr 2016 19:08:55 +0800
changeset 354564 f0303118ac47e379c361e2a1481b457b3ff8406e
parent 352420 1f16d3da9280e40ada252acf8110b91ee1edbb08
child 519040 b1b242698b78587f03184570e5bfc10403cdf539
push id16120
push usercyu@mozilla.com
push dateThu, 21 Apr 2016 07:13:42 +0000
reviewersgabor
bugs1258317
milestone48.0a1
Bug 1258317 - Part 1: Annotate the crash report with process information on failure to transfer an IPC transport to another process. r?gabor MozReview-Commit-ID: LE2FnrQgzze
ipc/glue/ProtocolUtils.cpp
ipc/glue/ProtocolUtils.h
ipc/glue/Transport_win.cpp
--- a/ipc/glue/ProtocolUtils.cpp
+++ b/ipc/glue/ProtocolUtils.cpp
@@ -16,16 +16,21 @@
 #include "mozilla/ipc/Transport.h"
 #include "mozilla/StaticMutex.h"
 
 #if defined(MOZ_SANDBOX) && defined(XP_WIN)
 #define TARGET_SANDBOX_EXPORTS
 #include "mozilla/sandboxTarget.h"
 #endif
 
+#if defined(MOZ_CRASHREPORTER) && defined(XP_WIN)
+#include "Aclapi.h"
+#include "Sddl.h"
+#endif
+
 using namespace IPC;
 
 using base::GetCurrentProcId;
 using base::ProcessHandle;
 using base::ProcessId;
 
 namespace mozilla {
 namespace ipc {
@@ -295,28 +300,111 @@ bool DuplicateHandle(HANDLE aSourceHandl
 
   return !!::DuplicateHandle(::GetCurrentProcess(), aSourceHandle,
                               targetProcess, aTargetHandle,
                               aDesiredAccess, FALSE, aOptions);
 }
 #endif
 
 #ifdef MOZ_CRASHREPORTER
-void AnnotateSystemError()
+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));
+    CrashReporter::AnnotateCrashReport(
+      NS_LITERAL_CSTRING("IPCSystemError"),
+      nsPrintfCString("%lld", error));
+  }
+}
+
+void
+AnnotateProcessInformation(base::ProcessId aPid)
+{
+#ifdef XP_WIN
+  HANDLE processHandle = OpenProcess(READ_CONTROL|PROCESS_QUERY_INFORMATION, FALSE, aPid);
+  if (!processHandle) {
+    CrashReporter::AnnotateCrashReport(
+      NS_LITERAL_CSTRING("IPCExtraSystemError"),
+      nsPrintfCString("Failed to get information of process %d, error(%d)",
+                      aPid,
+                      ::GetLastError()));
+    return;
+  }
+
+  DWORD exitCode = 0;
+  if (!::GetExitCodeProcess(processHandle, &exitCode)) {
+    CrashReporter::AnnotateCrashReport(
+      NS_LITERAL_CSTRING("IPCExtraSystemError"),
+      nsPrintfCString("Failed to get exit information of process %d, error(%d)",
+                      aPid,
+                      ::GetLastError()));
+    return;
+  }
+
+  if (exitCode != STILL_ACTIVE) {
+    CrashReporter::AnnotateCrashReport(
+      NS_LITERAL_CSTRING("IPCExtraSystemError"),
+      nsPrintfCString("Process %d is not alive. Exit code: %d",
+                      aPid,
+                      exitCode));
+    return;
   }
+
+  PSECURITY_DESCRIPTOR secDesc = nullptr;
+  PSID ownerSid = nullptr;
+  DWORD rv = ::GetSecurityInfo(processHandle,
+                               SE_KERNEL_OBJECT,
+                               OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION,
+                               &ownerSid,
+                               nullptr,
+                               nullptr,
+                               nullptr,
+                               &secDesc);
+  if (rv != ERROR_SUCCESS) {
+    // GetSecurityInfo() failed.
+    CrashReporter::AnnotateCrashReport(
+      NS_LITERAL_CSTRING("IPCExtraSystemError"),
+      nsPrintfCString("Failed to get security information of process %d,"
+                      " error(%d)",
+                      aPid,
+                      rv));
+    return;
+  }
+
+  LPTSTR ownerSidStr = nullptr;
+  nsString annotation{};
+  annotation.AppendLiteral("Owner: ");
+  if (::ConvertSidToStringSid(ownerSid, &ownerSidStr)) {
+    annotation.Append(ownerSidStr);
+  }
+  ::LocalFree(ownerSidStr);
+
+  LPTSTR secDescStr = nullptr;
+  annotation.AppendLiteral(", Security Descriptor: ");
+  if (::ConvertSecurityDescriptorToStringSecurityDescriptor(secDesc,
+                                                            SDDL_REVISION_1,
+                                                            DACL_SECURITY_INFORMATION,
+                                                            &secDescStr,
+                                                            nullptr)) {
+    annotation.Append(secDescStr);
+  }
+
+  CrashReporter::AnnotateCrashReport(
+    NS_LITERAL_CSTRING("IPCExtraSystemError"),
+    NS_ConvertUTF16toUTF8(annotation));
+
+  ::LocalFree(secDescStr);
+  ::LocalFree(secDesc);
+#endif
 }
 #endif
 
 void
 LogMessageForProtocol(const char* aTopLevelProtocol, base::ProcessId aOtherPid,
                       const char* aContextDescription,
                       const char* aMessageDescription,
                       MessageDirection aDirection)
--- a/ipc/glue/ProtocolUtils.h
+++ b/ipc/glue/ProtocolUtils.h
@@ -349,23 +349,25 @@ 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.
+ * Annotate the crash reporter with the error code from the most recent system
+ * call. Returns the system error.
  */
 #ifdef MOZ_CRASHREPORTER
 void AnnotateSystemError();
+void AnnotateProcessInformation(base::ProcessId aPid);
 #else
 #define AnnotateSystemError() do { } while (0)
+#define AnnotateProcessInformation(...) 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;
--- a/ipc/glue/Transport_win.cpp
+++ b/ipc/glue/Transport_win.cpp
@@ -61,16 +61,17 @@ TransferHandleToProcess(HANDLE source, b
     return source;
   }
   HANDLE handleDup;
   DWORD access = 0;
   DWORD options = DUPLICATE_SAME_ACCESS;
   bool ok = DuplicateHandle(source, pid, &handleDup, access, options);
   if (!ok) {
     AnnotateSystemError();
+    AnnotateProcessInformation(pid);
   }
   MOZ_RELEASE_ASSERT(ok);
 
   // Now close our own copy of the handle (we're supposed to be transferring,
   // not copying).
   CloseHandle(source);
 
   return handleDup;