Bug 1743454 - Notify GeckoView crash handler of GPU process crashes. r=agi,aosmond

Rename ContentCrashHandler.jsm to ChildCrashHandler.jsm as it is now
responsible for all types of child process crashes. Have it observe
"compositor:process-aborted" in addition to
"ipc:content-shutdown". Additionally, rename the
"GeckoView:ContentCrashReport" event it sends to
"GeckoView:ChildCrashReport".

In GPUChild::ActorDestroy, provide an out variable for
GenerateCrashReport to return the dump ID, and stuff this in to a
property bag, along with "abnormal: true", sent to
"compositor:process-aborted" observers.

In ChildCrashHandler, set the "processType" argument sent with the
GeckoView:ChildCrashReport event to BACKGROUND_CHILD for GPU process
crashes, and FOREGROUND_CHILD otherwise.

Differential Revision: https://phabricator.services.mozilla.com/D132810
This commit is contained in:
Jamie Nicol 2021-12-08 19:08:16 +00:00
parent 61bcf0d1a8
commit e8bce5ff6b
5 changed files with 27 additions and 16 deletions

View File

@ -30,8 +30,10 @@
#include "mozilla/ipc/Endpoint.h"
#include "mozilla/layers/APZInputBridgeChild.h"
#include "mozilla/layers/LayerTreeOwnerTracker.h"
#include "nsHashPropertyBag.h"
#include "nsIGfxInfo.h"
#include "nsIObserverService.h"
#include "nsIPropertyBag2.h"
#include "ProfilerParent.h"
namespace mozilla {
@ -264,7 +266,8 @@ mozilla::ipc::IPCResult GPUChild::RecvAddMemoryReport(
void GPUChild::ActorDestroy(ActorDestroyReason aWhy) {
if (aWhy == AbnormalShutdown) {
GenerateCrashReport(OtherPid());
nsAutoString dumpId;
GenerateCrashReport(OtherPid(), &dumpId);
Telemetry::Accumulate(
Telemetry::SUBPROCESS_ABNORMAL_ABORT,
@ -272,9 +275,13 @@ void GPUChild::ActorDestroy(ActorDestroyReason aWhy) {
1);
// Notify the Telemetry environment so that we can refresh and do a
// subsession split
// subsession split. This also notifies the crash reporter on geckoview.
if (nsCOMPtr<nsIObserverService> obsvc = services::GetObserverService()) {
obsvc->NotifyObservers(nullptr, "compositor:process-aborted", nullptr);
RefPtr<nsHashPropertyBag> props = new nsHashPropertyBag();
props->SetPropertyAsBool(u"abnormal"_ns, true);
props->SetPropertyAsAString(u"dumpID"_ns, dumpId);
obsvc->NotifyObservers((nsIPropertyBag2*)props,
"compositor:process-aborted", nullptr);
}
}

View File

@ -138,9 +138,9 @@ class GeckoViewStartup {
) {
ActorManagerParent.addJSWindowActors(JSWINDOWACTORS);
GeckoViewUtils.addLazyGetter(this, "ContentCrashHandler", {
module: "resource://gre/modules/ContentCrashHandler.jsm",
observers: ["ipc:content-shutdown"],
GeckoViewUtils.addLazyGetter(this, "ChildCrashHandler", {
module: "resource://gre/modules/ChildCrashHandler.jsm",
observers: ["ipc:content-shutdown", "compositor:process-aborted"],
});
}
break;

View File

@ -309,7 +309,7 @@ public final class GeckoRuntime implements Parcelable {
mDelegate.onShutdown();
EventDispatcher.getInstance()
.unregisterUiThreadListener(mEventListener, "Gecko:Exited");
} else if ("GeckoView:ContentCrashReport".equals(event) && crashHandler != null) {
} else if ("GeckoView:ChildCrashReport".equals(event) && crashHandler != null) {
final Context context = GeckoAppShell.getApplicationContext();
final Intent i = new Intent(ACTION_CRASHED, null, context, crashHandler);
i.putExtra(EXTRA_MINIDUMP_PATH, message.getString(EXTRA_MINIDUMP_PATH));
@ -364,7 +364,7 @@ public final class GeckoRuntime implements Parcelable {
}
EventDispatcher.getInstance()
.registerUiThreadListener(mEventListener, "GeckoView:ContentCrashReport");
.registerUiThreadListener(mEventListener, "GeckoView:ChildCrashReport");
flags |= GeckoThread.FLAG_ENABLE_NATIVE_CRASHREPORTER;
} catch (final PackageManager.NameNotFoundException e) {

View File

@ -4,7 +4,7 @@
"use strict";
var EXPORTED_SYMBOLS = ["ContentCrashHandler"];
var EXPORTED_SYMBOLS = ["ChildCrashHandler"];
const { XPCOMUtils } = ChromeUtils.import(
"resource://gre/modules/XPCOMUtils.jsm"
@ -21,7 +21,7 @@ XPCOMUtils.defineLazyModuleGetters(this, {
ChromeUtils.defineModuleGetter(this, "OS", "resource://gre/modules/osfile.jsm");
const { debug, warn } = GeckoViewUtils.initLogging("ContentCrashHandler");
const { debug, warn } = GeckoViewUtils.initLogging("ChildCrashHandler");
function getDir(name) {
const uAppDataPath = Services.dirsvc.get("UAppData", Ci.nsIFile).path;
@ -36,7 +36,7 @@ function getPendingMinidump(id) {
});
}
var ContentCrashHandler = {
var ChildCrashHandler = {
// The event listener for this is hooked up in GeckoViewStartup.jsm
observe(aSubject, aTopic, aData) {
aSubject.QueryInterface(Ci.nsIPropertyBag2);
@ -54,20 +54,24 @@ var ContentCrashHandler = {
}
const dumpID = aSubject.get("dumpID");
if (!dumpID) {
if (aTopic === "ipc:content-shutdown" && !dumpID) {
Services.telemetry
.getHistogramById("FX_CONTENT_CRASH_DUMP_UNAVAILABLE")
.add(1);
return;
}
debug`Notifying content process crash, dump ID ${dumpID}`;
debug`Notifying child process crash, dump ID ${dumpID}`;
const [minidumpPath, extrasPath] = getPendingMinidump(dumpID);
const processType = "FOREGROUND_CHILD";
// Report GPU process crashes as occuring in a background process, and others as foreground.
const processType =
aTopic === "compositor:process-aborted"
? "BACKGROUND_CHILD"
: "FOREGROUND_CHILD";
EventDispatcher.instance.sendRequest({
type: "GeckoView:ContentCrashReport",
type: "GeckoView:ChildCrashReport",
minidumpPath,
extrasPath,
success: true,

View File

@ -7,7 +7,7 @@
EXTRA_JS_MODULES += [
"AndroidLog.jsm",
"BrowserUsageTelemetry.jsm",
"ContentCrashHandler.jsm",
"ChildCrashHandler.jsm",
"DelayedInit.jsm",
"GeckoViewActorChild.jsm",
"GeckoViewActorManager.jsm",