Bug 1325834: Add crash reporter annotations to report COM marshaling failure codes; r?jimm
MozReview-Commit-ID: FcEBoU0DzzR
--- 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));
}
}