Bug 1571711 - Factorize crash handling out of the various process IPC classes r=froydnj

Differential Revision: https://phabricator.services.mozilla.com/D41657

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Gabriele Svelto 2019-08-15 12:06:51 +00:00
parent f4e2add6c3
commit 14db2c37b8
16 changed files with 106 additions and 143 deletions

View File

@ -424,29 +424,21 @@ bool GMPParent::EnsureProcessLoaded() {
}
void GMPParent::AddCrashAnnotations() {
mCrashReporter->AddAnnotation(CrashReporter::Annotation::GMPPlugin, true);
mCrashReporter->AddAnnotation(CrashReporter::Annotation::PluginFilename,
NS_ConvertUTF16toUTF8(mName));
mCrashReporter->AddAnnotation(CrashReporter::Annotation::PluginName,
mDisplayName);
mCrashReporter->AddAnnotation(CrashReporter::Annotation::PluginVersion,
mVersion);
if (mCrashReporter) {
mCrashReporter->AddAnnotation(CrashReporter::Annotation::GMPPlugin, true);
mCrashReporter->AddAnnotation(CrashReporter::Annotation::PluginFilename,
NS_ConvertUTF16toUTF8(mName));
mCrashReporter->AddAnnotation(CrashReporter::Annotation::PluginName,
mDisplayName);
mCrashReporter->AddAnnotation(CrashReporter::Annotation::PluginVersion,
mVersion);
}
}
bool GMPParent::GetCrashID(nsString& aResult) {
if (!mCrashReporter) {
CrashReporter::FinalizeOrphanedMinidump(OtherPid(),
GeckoProcessType_GMPlugin);
return false;
}
AddCrashAnnotations();
if (!mCrashReporter->GenerateCrashReport(OtherPid())) {
return false;
}
aResult = mCrashReporter->MinidumpID();
return true;
return GenerateCrashReport(OtherPid(), &aResult);
}
static void GMPNotifyObservers(const uint32_t aPluginID,
@ -508,14 +500,6 @@ void GMPParent::ActorDestroy(ActorDestroyReason aWhy) {
}
}
mozilla::ipc::IPCResult GMPParent::RecvInitCrashReporter(
Shmem&& aShmem, const NativeThreadId& aThreadId) {
mCrashReporter = MakeUnique<ipc::CrashReporterHost>(GeckoProcessType_GMPlugin,
aShmem, aThreadId);
return IPC_OK();
}
PGMPStorageParent* GMPParent::AllocPGMPStorageParent() {
GMPStorageParent* p = new GMPStorageParent(mNodeId, this);
mStorage.AppendElement(p); // Addrefs, released in DeallocPGMPStorageParent.

View File

@ -13,6 +13,7 @@
#include "GMPTimerParent.h"
#include "GMPStorageParent.h"
#include "mozilla/gmp/PGMPParent.h"
#include "mozilla/ipc/CrashReporterHelper.h"
#include "nsCOMPtr.h"
#include "nscore.h"
#include "nsISupports.h"
@ -22,9 +23,6 @@
#include "mozilla/MozPromise.h"
namespace mozilla {
namespace ipc {
class CrashReporterHost;
} // namespace ipc
namespace gmp {
class GMPCapability {
@ -54,7 +52,9 @@ enum GMPState {
class GMPContentParent;
class GMPParent final : public PGMPParent {
class GMPParent final
: public PGMPParent,
public ipc::CrashReporterHelper<GeckoProcessType_GMPlugin> {
friend class PGMPParent;
public:
@ -157,9 +157,6 @@ class GMPParent final : public PGMPParent {
bool GetCrashID(nsString& aResult);
void ActorDestroy(ActorDestroyReason aWhy) override;
mozilla::ipc::IPCResult RecvInitCrashReporter(
Shmem&& shmem, const NativeThreadId& aThreadId);
mozilla::ipc::IPCResult RecvPGMPStorageConstructor(
PGMPStorageParent* actor) override;
PGMPStorageParent* AllocPGMPStorageParent();
@ -217,8 +214,6 @@ class GMPParent final : public PGMPParent {
// to terminate gracefully.
bool mHoldingSelfRef;
UniquePtr<ipc::CrashReporterHost> mCrashReporter;
const RefPtr<AbstractThread> mMainThread;
};

View File

@ -80,14 +80,6 @@ mozilla::ipc::IPCResult RDDChild::RecvInitComplete() {
return IPC_OK();
}
mozilla::ipc::IPCResult RDDChild::RecvInitCrashReporter(
Shmem&& aShmem, const NativeThreadId& aThreadId) {
mCrashReporter = MakeUnique<ipc::CrashReporterHost>(GeckoProcessType_RDD,
aShmem, aThreadId);
return IPC_OK();
}
bool RDDChild::SendRequestMemoryReport(const uint32_t& aGeneration,
const bool& aAnonymize,
const bool& aMinimizeMemoryUsage,
@ -119,12 +111,7 @@ mozilla::ipc::IPCResult RDDChild::RecvFinishMemoryReport(
void RDDChild::ActorDestroy(ActorDestroyReason aWhy) {
if (aWhy == AbnormalShutdown) {
if (mCrashReporter) {
mCrashReporter->GenerateCrashReport(OtherPid());
mCrashReporter = nullptr;
} else {
CrashReporter::FinalizeOrphanedMinidump(OtherPid(), GeckoProcessType_RDD);
}
GenerateCrashReport(OtherPid());
}
gfxVars::RemoveReceiver(this);

View File

@ -7,7 +7,7 @@
#define _include_dom_media_ipc_RDDChild_h_
#include "mozilla/PRDDChild.h"
#include "mozilla/RefPtr.h"
#include "mozilla/ipc/CrashReporterHelper.h"
#include "mozilla/UniquePtr.h"
#include "mozilla/gfx/gfxVarReceiver.h"
@ -17,16 +17,15 @@ namespace mozilla {
class SandboxBroker;
#endif
namespace ipc {
class CrashReporterHost;
} // namespace ipc
namespace dom {
class MemoryReportRequestHost;
} // namespace dom
class RDDProcessHost;
class RDDChild final : public PRDDChild, public gfx::gfxVarReceiver {
class RDDChild final : public PRDDChild,
public ipc::CrashReporterHelper<GeckoProcessType_RDD>,
public gfx::gfxVarReceiver {
typedef mozilla::dom::MemoryReportRequestHost MemoryReportRequestHost;
public:
@ -41,8 +40,6 @@ class RDDChild final : public PRDDChild, public gfx::gfxVarReceiver {
// PRDDChild overrides.
mozilla::ipc::IPCResult RecvInitComplete();
mozilla::ipc::IPCResult RecvInitCrashReporter(
Shmem&& shmem, const NativeThreadId& aThreadId);
void ActorDestroy(ActorDestroyReason aWhy) override;
@ -58,7 +55,6 @@ class RDDChild final : public PRDDChild, public gfx::gfxVarReceiver {
private:
RDDProcessHost* mHost;
UniquePtr<ipc::CrashReporterHost> mCrashReporter;
UniquePtr<MemoryReportRequestHost> mMemoryReportRequest;
#if defined(XP_LINUX) && defined(MOZ_SANDBOX)
UniquePtr<SandboxBroker> mSandboxBroker;

View File

@ -17,7 +17,6 @@
#if defined(XP_WIN)
# include "mozilla/gfx/DeviceManagerDx.h"
#endif
#include "mozilla/ipc/CrashReporterHost.h"
#include "mozilla/layers/APZInputBridgeChild.h"
#include "mozilla/layers/LayerTreeOwnerTracker.h"
#include "mozilla/Unused.h"
@ -118,14 +117,6 @@ mozilla::ipc::IPCResult GPUChild::RecvGraphicsError(const nsCString& aError) {
return IPC_OK();
}
mozilla::ipc::IPCResult GPUChild::RecvInitCrashReporter(
Shmem&& aShmem, const NativeThreadId& aThreadId) {
mCrashReporter = MakeUnique<ipc::CrashReporterHost>(GeckoProcessType_GPU,
aShmem, aThreadId);
return IPC_OK();
}
mozilla::ipc::IPCResult GPUChild::RecvCreateVRProcess() {
// Make sure create VR process at the main process
MOZ_ASSERT(XRE_IsParentProcess());
@ -237,12 +228,7 @@ mozilla::ipc::IPCResult GPUChild::RecvFinishMemoryReport(
void GPUChild::ActorDestroy(ActorDestroyReason aWhy) {
if (aWhy == AbnormalShutdown) {
if (mCrashReporter) {
mCrashReporter->GenerateCrashReport(OtherPid());
mCrashReporter = nullptr;
} else {
CrashReporter::FinalizeOrphanedMinidump(OtherPid(), GeckoProcessType_GPU);
}
GenerateCrashReport(OtherPid());
Telemetry::Accumulate(
Telemetry::SUBPROCESS_ABNORMAL_ABORT,

View File

@ -8,14 +8,12 @@
#include "mozilla/RefPtr.h"
#include "mozilla/UniquePtr.h"
#include "mozilla/ipc/CrashReporterHelper.h"
#include "mozilla/gfx/PGPUChild.h"
#include "mozilla/gfx/gfxVarReceiver.h"
namespace mozilla {
namespace ipc {
class CrashReporterHost;
} // namespace ipc
namespace dom {
class MemoryReportRequestHost;
} // namespace dom
@ -23,7 +21,9 @@ namespace gfx {
class GPUProcessHost;
class GPUChild final : public PGPUChild, public gfxVarReceiver {
class GPUChild final : public ipc::CrashReporterHelper<GeckoProcessType_GPU>,
public PGPUChild,
public gfxVarReceiver {
typedef mozilla::dom::MemoryReportRequestHost MemoryReportRequestHost;
public:
@ -42,8 +42,6 @@ class GPUChild final : public PGPUChild, public gfxVarReceiver {
mozilla::ipc::IPCResult RecvInitComplete(const GPUDeviceData& aData);
mozilla::ipc::IPCResult RecvReportCheckerboard(const uint32_t& aSeverity,
const nsCString& aLog);
mozilla::ipc::IPCResult RecvInitCrashReporter(
Shmem&& shmem, const NativeThreadId& aThreadId);
mozilla::ipc::IPCResult RecvCreateVRProcess();
mozilla::ipc::IPCResult RecvShutdownVRProcess();
@ -81,7 +79,6 @@ class GPUChild final : public PGPUChild, public gfxVarReceiver {
private:
GPUProcessHost* mHost;
UniquePtr<ipc::CrashReporterHost> mCrashReporter;
UniquePtr<MemoryReportRequestHost> mMemoryReportRequest;
bool mGPUReady;
};

View File

@ -14,7 +14,6 @@
#include "mozilla/Telemetry.h"
#include "mozilla/VsyncDispatcher.h"
#include "mozilla/dom/MemoryReportRequest.h"
#include "mozilla/ipc/CrashReporterHost.h"
namespace mozilla {
namespace gfx {
@ -91,12 +90,7 @@ mozilla::ipc::IPCResult VRChild::RecvFinishMemoryReport(
void VRChild::ActorDestroy(ActorDestroyReason aWhy) {
if (aWhy == AbnormalShutdown) {
if (mCrashReporter) {
mCrashReporter->GenerateCrashReport(OtherPid());
mCrashReporter = nullptr;
} else {
CrashReporter::FinalizeOrphanedMinidump(OtherPid(), GeckoProcessType_VR);
}
GenerateCrashReport(OtherPid());
Telemetry::Accumulate(
Telemetry::SUBPROCESS_ABNORMAL_ABORT,
@ -175,14 +169,6 @@ mozilla::ipc::IPCResult VRChild::RecvInitComplete() {
return IPC_OK();
}
mozilla::ipc::IPCResult VRChild::RecvInitCrashReporter(
Shmem&& aShmem, const NativeThreadId& aThreadId) {
mCrashReporter = MakeUnique<ipc::CrashReporterHost>(GeckoProcessType_VR,
aShmem, aThreadId);
return IPC_OK();
}
bool VRChild::SendRequestMemoryReport(const uint32_t& aGeneration,
const bool& aAnonymize,
const bool& aMinimizeMemoryUsage,

View File

@ -9,13 +9,11 @@
#include "mozilla/gfx/PVRChild.h"
#include "mozilla/gfx/gfxVarReceiver.h"
#include "mozilla/ipc/CrashReporterHelper.h"
#include "mozilla/VsyncDispatcher.h"
#include "gfxVR.h"
namespace mozilla {
namespace ipc {
class CrashReporterHost;
} // namespace ipc
namespace dom {
class MemoryReportRequestHost;
} // namespace dom
@ -24,7 +22,9 @@ namespace gfx {
class VRProcessParent;
class VRChild;
class VRChild final : public PVRChild, public gfxVarReceiver {
class VRChild final : public PVRChild,
public ipc::CrashReporterHelper<GeckoProcessType_VR>,
public gfxVarReceiver {
typedef mozilla::dom::MemoryReportRequestHost MemoryReportRequestHost;
friend class PVRChild;
@ -48,15 +48,12 @@ class VRChild final : public PVRChild, public gfxVarReceiver {
mozilla::ipc::IPCResult RecvOpenVRControllerManifestPathToParent(
const OpenVRControllerType& aType, const nsCString& aPath);
mozilla::ipc::IPCResult RecvInitComplete();
mozilla::ipc::IPCResult RecvInitCrashReporter(
Shmem&& shmem, const NativeThreadId& aThreadId);
mozilla::ipc::IPCResult RecvAddMemoryReport(const MemoryReport& aReport);
mozilla::ipc::IPCResult RecvFinishMemoryReport(const uint32_t& aGeneration);
private:
VRProcessParent* mHost;
UniquePtr<ipc::CrashReporterHost> mCrashReporter;
UniquePtr<MemoryReportRequestHost> mMemoryReportRequest;
bool mVRReady;
};

View File

@ -24,7 +24,7 @@ class CrashReporterClient {
// |aTopLevelProtocol| must be a top-level protocol instance, as sub-actors
// do not have AllocUnsafeShmem. It must also have a child-to-parent message:
//
// async SetCrashReporterClient(Shmem shmem);
// async InitCrashReporter(Shmem shmem, NativeThreadId threadId);
//
// The parent-side receive function of this message should save the shmem
// somewhere, and when the top-level actor's ActorDestroy runs (or when the

View File

@ -0,0 +1,64 @@
/* 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/. */
#ifndef mozilla_ipc_CrashReporterHelper_h
#define mozilla_ipc_CrashReporterHelper_h
#include "CrashReporterHost.h"
#include "mozilla/ipc/Shmem.h"
#include "mozilla/UniquePtr.h"
#include "nsExceptionHandler.h"
namespace mozilla {
namespace ipc {
/**
* This class encapsulates the common elements of crash report handling for
* toplevel protocols representing processes. To use this class, you should:
*
* 1. Declare a method to initialize the crash reporter in your IPDL:
* `async InitCrashReporter(Shmem shmem, NativeThreadId threadId)`
*
* 2. Inherit from this class, providing the appropriate `GeckoProcessType`
* enum value for the template parameter PT.
*
* 3. When your protocol actor is destroyed with a reason of `AbnormalShutdown`,
* you should call `GenerateCrashReport(OtherPid())`. If you need the crash
* report ID it will be copied in the second optional parameter upon
* successful crash report generation.
*/
template <GeckoProcessType PT>
class CrashReporterHelper {
public:
CrashReporterHelper() : mCrashReporter(nullptr) {}
IPCResult RecvInitCrashReporter(Shmem&& aShmem,
const CrashReporter::ThreadId& aThreadId) {
mCrashReporter = MakeUnique<ipc::CrashReporterHost>(PT, aShmem, aThreadId);
return IPC_OK();
}
protected:
bool GenerateCrashReport(base::ProcessId aPid,
nsString* aMinidumpId = nullptr) {
if (!mCrashReporter) {
CrashReporter::FinalizeOrphanedMinidump(aPid, PT);
return false;
}
bool generated = mCrashReporter->GenerateCrashReport(aPid);
if (generated && aMinidumpId) {
*aMinidumpId = mCrashReporter->MinidumpID();
}
mCrashReporter = nullptr;
return generated;
}
UniquePtr<ipc::CrashReporterHost> mCrashReporter;
};
} // namespace ipc
} // namespace mozilla
#endif // mozilla_ipc_CrashReporterHelper_h

View File

@ -14,6 +14,7 @@
#include "base/process.h"
#include "nsExceptionHandler.h"
#include "nsThreadUtils.h"
#include "ProtocolUtils.h"
namespace mozilla {
namespace ipc {

View File

@ -16,6 +16,7 @@ EXPORTS.mozilla.ipc += [
'BrowserProcessSubThread.h',
'ByteBuf.h',
'CrashReporterClient.h',
'CrashReporterHelper.h',
'CrashReporterHost.h',
'CrashReporterMetadataShmem.h',
'CrossProcessMutex.h',

View File

@ -6,7 +6,6 @@
#include "SocketProcessParent.h"
#include "SocketProcessHost.h"
#include "mozilla/ipc/CrashReporterHost.h"
#include "mozilla/net/DNSRequestParent.h"
#include "mozilla/Telemetry.h"
#include "mozilla/TelemetryIPC.h"
@ -44,23 +43,9 @@ SocketProcessParent* SocketProcessParent::GetSingleton() {
return sSocketProcessParent;
}
mozilla::ipc::IPCResult SocketProcessParent::RecvInitCrashReporter(
Shmem&& aShmem, const NativeThreadId& aThreadId) {
mCrashReporter = MakeUnique<CrashReporterHost>(GeckoProcessType_Content,
aShmem, aThreadId);
return IPC_OK();
}
void SocketProcessParent::ActorDestroy(ActorDestroyReason aWhy) {
if (aWhy == AbnormalShutdown) {
if (mCrashReporter) {
mCrashReporter->GenerateCrashReport(OtherPid());
mCrashReporter = nullptr;
} else {
CrashReporter::FinalizeOrphanedMinidump(OtherPid(),
GeckoProcessType_Content);
}
GenerateCrashReport(OtherPid());
}
if (mHost) {

View File

@ -7,6 +7,7 @@
#define mozilla_net_SocketProcessParent_h
#include "mozilla/UniquePtr.h"
#include "mozilla/ipc/CrashReporterHelper.h"
#include "mozilla/net/PSocketProcessParent.h"
namespace mozilla {
@ -26,7 +27,9 @@ class SocketProcessHost;
// IPC actor of socket process in parent process. This is allocated and managed
// by SocketProcessHost.
class SocketProcessParent final : public PSocketProcessParent {
class SocketProcessParent final
: public PSocketProcessParent,
public ipc::CrashReporterHelper<GeckoProcessType_Content> {
public:
friend class SocketProcessHost;
@ -35,8 +38,6 @@ class SocketProcessParent final : public PSocketProcessParent {
static SocketProcessParent* GetSingleton();
mozilla::ipc::IPCResult RecvInitCrashReporter(
Shmem&& aShmem, const NativeThreadId& aThreadId);
mozilla::ipc::IPCResult RecvAddMemoryReport(const MemoryReport& aReport);
mozilla::ipc::IPCResult RecvFinishMemoryReport(const uint32_t& aGeneration);
mozilla::ipc::IPCResult RecvAccumulateChildHistograms(
@ -72,7 +73,6 @@ class SocketProcessParent final : public PSocketProcessParent {
private:
SocketProcessHost* mHost;
UniquePtr<ipc::CrashReporterHost> mCrashReporter;
UniquePtr<dom::MemoryReportRequestHost> mMemoryReportRequest;
static void Destroy(UniquePtr<SocketProcessParent>&& aParent);

View File

@ -63,13 +63,7 @@ void RemoteSandboxBrokerParent::ActorDestroy(ActorDestroyReason aWhy) {
nsDependentCString(XRE_ChildProcessTypeToString(
GeckoProcessType_RemoteSandboxBroker)),
1);
if (mCrashReporter) {
mCrashReporter->GenerateCrashReport(OtherPid());
mCrashReporter = nullptr;
} else {
CrashReporter::FinalizeOrphanedMinidump(
OtherPid(), GeckoProcessType_RemoteSandboxBroker);
}
GenerateCrashReport(OtherPid());
}
Shutdown();
}
@ -85,12 +79,4 @@ void RemoteSandboxBrokerParent::Shutdown() {
}
}
mozilla::ipc::IPCResult RemoteSandboxBrokerParent::RecvInitCrashReporter(
Shmem&& aShmem, const NativeThreadId& aThreadId) {
mCrashReporter = MakeUnique<ipc::CrashReporterHost>(
GeckoProcessType_RemoteSandboxBroker, aShmem, aThreadId);
return IPC_OK();
}
} // namespace mozilla

View File

@ -9,11 +9,13 @@
#include "mozilla/PRemoteSandboxBrokerParent.h"
#include "RemoteSandboxBrokerProcessParent.h"
#include "mozilla/ipc/CrashReporterHost.h"
#include "mozilla/ipc/CrashReporterHelper.h"
namespace mozilla {
class RemoteSandboxBrokerParent : public PRemoteSandboxBrokerParent {
class RemoteSandboxBrokerParent
: public PRemoteSandboxBrokerParent,
public ipc::CrashReporterHelper<GeckoProcessType_RemoteSandboxBroker> {
friend class PRemoteSandboxBrokerParent;
public:
@ -27,15 +29,11 @@ class RemoteSandboxBrokerParent : public PRemoteSandboxBrokerParent {
RefPtr<GenericPromise> Launch(const nsTArray<uint64_t>& aHandlesToShare);
private:
mozilla::ipc::IPCResult RecvInitCrashReporter(
Shmem&& aShmem, const NativeThreadId& aThreadId);
void ActorDestroy(ActorDestroyReason aWhy) override;
RemoteSandboxBrokerProcessParent* mProcess = nullptr;
bool mOpened = false;
UniquePtr<ipc::CrashReporterHost> mCrashReporter;
};
} // namespace mozilla