gecko-dev/gfx/ipc/GPUChild.h
Jamie Nicol 3fcda9ab4f Bug 1743454 - Ensure GPU process crash reports are generated regardless of which IPC actor dies first. r=aosmond
GPU process crash reports are handled by calling GenerateCrashReport()
in GPUChild::ActorDestroy() if the reason is AbnormalShutdown. This
ensures we only create crash report if the process actually crashed,
and not when it was deliberately stopped.

However, sometimes actors other than GPUChild are the first to be
destroyed immediately after a crash, for example CompositorBridgeChild
or UiCompositorControllerChild. If such an actor receives an
ActorDestroy message with AbnormalShutdown as the reason, they will
call GPUProcessManager::NotifyRemoteActorDestroyed(), which leads to
GPUProcessHost::Shutdown(), which will close the PGPU channel. This
creates a race condition after a GPU process crash, where sometimes
the channel gets closed gracefully and ActorDestroy will receive a
NormalShutdown reason rather than AbnormalShutdown.

This patch adds a flag to GPUProcessHost::Shutdown() indicating
whether it is being called in response to an unexpected shutdown being
detected by another actor. If set, it sets a flag on the
GPUChild. When GPUChild::ActorDestroy() eventually gets called, it
knows to act in response to a crash if either the reason is
AbnormalShutdown or this flag has been set.

Differential Revision: https://phabricator.services.mozilla.com/D132811
2021-12-08 19:08:17 +00:00

102 lines
4.0 KiB
C++

/* -*- 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/. */
#ifndef _include_mozilla_gfx_ipc_GPUChild_h_
#define _include_mozilla_gfx_ipc_GPUChild_h_
#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 dom {
class MemoryReportRequestHost;
} // namespace dom
namespace gfx {
class GPUProcessHost;
class GPUChild final : public ipc::CrashReporterHelper<GeckoProcessType_GPU>,
public PGPUChild,
public gfxVarReceiver {
typedef mozilla::dom::MemoryReportRequestHost MemoryReportRequestHost;
public:
explicit GPUChild(GPUProcessHost* aHost);
virtual ~GPUChild();
void Init();
bool EnsureGPUReady();
base::ProcessHandle GetChildProcessHandle();
// Notifies that an unexpected GPU process shutdown has been noticed by a
// different IPDL actor, and the GPU process is being torn down as a result.
// ActorDestroy may receive either NormalShutdown or AbnormalShutdown as a
// reason, depending on timings, but either way we treat the shutdown as
// abnormal.
void OnUnexpectedShutdown();
// gfxVarReceiver overrides.
void OnVarChanged(const GfxVarUpdate& aVar) override;
// PGPUChild overrides.
mozilla::ipc::IPCResult RecvInitComplete(const GPUDeviceData& aData);
mozilla::ipc::IPCResult RecvDeclareStable();
mozilla::ipc::IPCResult RecvReportCheckerboard(const uint32_t& aSeverity,
const nsCString& aLog);
mozilla::ipc::IPCResult RecvCreateVRProcess();
mozilla::ipc::IPCResult RecvShutdownVRProcess();
mozilla::ipc::IPCResult RecvAccumulateChildHistograms(
nsTArray<HistogramAccumulation>&& aAccumulations);
mozilla::ipc::IPCResult RecvAccumulateChildKeyedHistograms(
nsTArray<KeyedHistogramAccumulation>&& aAccumulations);
mozilla::ipc::IPCResult RecvUpdateChildScalars(
nsTArray<ScalarAction>&& aScalarActions);
mozilla::ipc::IPCResult RecvUpdateChildKeyedScalars(
nsTArray<KeyedScalarAction>&& aScalarActions);
mozilla::ipc::IPCResult RecvRecordChildEvents(
nsTArray<ChildEventData>&& events);
mozilla::ipc::IPCResult RecvRecordDiscardedData(
const DiscardedData& aDiscardedData);
void ActorDestroy(ActorDestroyReason aWhy) override;
mozilla::ipc::IPCResult RecvGraphicsError(const nsCString& aError);
mozilla::ipc::IPCResult RecvNotifyUiObservers(const nsCString& aTopic);
mozilla::ipc::IPCResult RecvNotifyDeviceReset(const GPUDeviceData& aData);
mozilla::ipc::IPCResult RecvFlushMemory(const nsString& aReason);
mozilla::ipc::IPCResult RecvAddMemoryReport(const MemoryReport& aReport);
mozilla::ipc::IPCResult RecvUpdateFeature(const Feature& aFeature,
const FeatureFailure& aChange);
mozilla::ipc::IPCResult RecvUsedFallback(const Fallback& aFallback,
const nsCString& aMessage);
mozilla::ipc::IPCResult RecvBHRThreadHang(const HangDetails& aDetails);
mozilla::ipc::IPCResult RecvUpdateMediaCodecsSupported(
const PDMFactory::MediaCodecsSupported& aSupported);
mozilla::ipc::IPCResult RecvFOGData(ByteBuf&& aBuf);
bool SendRequestMemoryReport(const uint32_t& aGeneration,
const bool& aAnonymize,
const bool& aMinimizeMemoryUsage,
const Maybe<ipc::FileDescriptor>& aDMDFile);
static void Destroy(UniquePtr<GPUChild>&& aChild);
private:
GPUProcessHost* mHost;
UniquePtr<MemoryReportRequestHost> mMemoryReportRequest;
bool mGPUReady;
bool mUnexpectedShutdown = false;
};
} // namespace gfx
} // namespace mozilla
#endif // _include_mozilla_gfx_ipc_GPUChild_h_