Bug 1325834: Add crash reporter annotations to report COM marshaling failure codes; r?jimm draft
authorAaron Klotz <aklotz@mozilla.com>
Mon, 27 Feb 2017 11:55:42 -0700
changeset 490161 328a46e238251d56a195c6714227e722c72a763b
parent 490146 0a91264315cb16fbe83580f262379efb7fdd8e04
child 547189 929bac22fcdf64974603facf0b6c1c29b31dbb79
push id47020
push useraklotz@mozilla.com
push dateMon, 27 Feb 2017 19:28:15 +0000
reviewersjimm
bugs1325834
milestone54.0a1
Bug 1325834: Add crash reporter annotations to report COM marshaling failure codes; r?jimm MozReview-Commit-ID: FcEBoU0DzzR
ipc/mscom/ProxyStream.cpp
--- a/ipc/mscom/ProxyStream.cpp
+++ b/ipc/mscom/ProxyStream.cpp
@@ -1,19 +1,19 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* 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 "mozilla/Move.h"
 #include "mozilla/mscom/EnsureMTA.h"
 #include "mozilla/mscom/ProxyStream.h"
 #include "mozilla/mscom/Utils.h"
-
-#include "mozilla/Move.h"
+#include "nsExceptionHandler.h"
 
 #include <windows.h>
 #include <objbase.h>
 #include <shlwapi.h>
 
 namespace mozilla {
 namespace mscom {
 
@@ -39,40 +39,48 @@ ProxyStream::ProxyStream(const BYTE* aIn
   // NB: We can't check for a null mStream until after we have checked for
   // the zero aInitBufSize above. This is because InitStream will also fail
   // in that case, even though marshaling a nullptr is allowable.
   MOZ_ASSERT(mStream);
   if (!mStream) {
     return;
   }
 
+  HRESULT unmarshalResult = S_OK;
+
   // We need to convert to an interface here otherwise we mess up const
   // correctness with IPDL. We'll request an IUnknown and then QI the
   // actual interface later.
 
   auto marshalFn = [&]() -> void
   {
     IUnknown* rawUnmarshaledProxy = nullptr;
     // OK to forget mStream when calling into this function because the stream
     // gets released even if the unmarshaling part fails.
-    DebugOnly<HRESULT> hr =
+    unmarshalResult =
       ::CoGetInterfaceAndReleaseStream(mStream.forget().take(), IID_IUnknown,
                                        (void**)&rawUnmarshaledProxy);
-    MOZ_ASSERT(SUCCEEDED(hr));
+    MOZ_ASSERT(SUCCEEDED(unmarshalResult));
     mUnmarshaledProxy.reset(rawUnmarshaledProxy);
   };
 
   if (XRE_IsParentProcess()) {
     // We'll marshal this stuff directly using the current thread, therefore its
     // proxy will reside in the same apartment as the current thread.
     marshalFn();
   } else {
     // When marshaling in child processes, we want to force the MTA.
     EnsureMTA mta(marshalFn);
   }
+
+  if (FAILED(unmarshalResult)) {
+    nsPrintfCString hrAsStr("0x%08X", unmarshalResult);
+    CrashReporter::AnnotateCrashReport(
+        NS_LITERAL_CSTRING("CoGetInterfaceAndReleaseStreamFailure"), hrAsStr);
+  }
 }
 
 already_AddRefed<IStream>
 ProxyStream::InitStream(const BYTE* aInitBuf, const UINT aInitBufSize)
 {
   return already_AddRefed<IStream>(::SHCreateMemStream(aInitBuf, aInitBufSize));
 }
 
@@ -151,42 +159,51 @@ ProxyStream::GetInterface(REFIID aIID, v
 ProxyStream::ProxyStream(REFIID aIID, IUnknown* aObject)
   : mGlobalLockedBuf(nullptr)
   , mHGlobal(nullptr)
   , mBufSize(0)
 {
   RefPtr<IStream> stream;
   HGLOBAL hglobal = NULL;
 
+  HRESULT marshalResult = S_OK;
+
   auto marshalFn = [&]() -> void
   {
     HRESULT hr = ::CreateStreamOnHGlobal(nullptr, TRUE, getter_AddRefs(stream));
     if (FAILED(hr)) {
       return;
     }
 
     hr = ::CoMarshalInterface(stream, aIID, aObject, MSHCTX_LOCAL, nullptr,
                               MSHLFLAGS_NORMAL);
     if (FAILED(hr)) {
+      marshalResult = hr;
       return;
     }
 
     hr = ::GetHGlobalFromStream(stream, &hglobal);
     MOZ_ASSERT(SUCCEEDED(hr));
   };
 
   if (XRE_IsParentProcess()) {
     // We'll marshal this stuff directly using the current thread, therefore its
     // stub will reside in the same apartment as the current thread.
     marshalFn();
   } else {
     // When marshaling in child processes, we want to force the MTA.
     EnsureMTA mta(marshalFn);
   }
 
+  if (FAILED(marshalResult)) {
+    nsPrintfCString hrAsStr("0x%08X", marshalResult);
+    CrashReporter::AnnotateCrashReport(
+        NS_LITERAL_CSTRING("CoMarshalInterfaceFailure"), hrAsStr);
+  }
+
   mStream = mozilla::Move(stream);
   if (hglobal) {
     mGlobalLockedBuf = reinterpret_cast<BYTE*>(::GlobalLock(hglobal));
     mHGlobal = hglobal;
     mBufSize = static_cast<int>(::GlobalSize(hglobal));
   }
 }