Bug 1753758 - Add crash reporting test for UtilityProcess r=gsvelto

Differential Revision: https://phabricator.services.mozilla.com/D137908
This commit is contained in:
Alexandre Lissy 2022-02-09 22:07:33 +00:00
Родитель 5b3f94efd9
Коммит c9affa0ba0
3 изменённых файлов: 108 добавлений и 1 удалений

Просмотреть файл

@ -15,6 +15,10 @@
#include "mozilla/ipc/ProcessChild.h"
#include "mozilla/FOGIPC.h"
#include "nsHashPropertyBag.h"
#include "mozilla/Services.h"
#include "nsIObserverService.h"
namespace mozilla::ipc {
static std::atomic<UtilityProcessParent*> sUtilityProcessParent;
@ -79,7 +83,24 @@ mozilla::ipc::IPCResult UtilityProcessParent::RecvFOGData(ByteBuf&& aBuf) {
void UtilityProcessParent::ActorDestroy(ActorDestroyReason aWhy) {
if (aWhy == AbnormalShutdown) {
GenerateCrashReport(OtherPid());
nsAutoString dumpID;
GenerateCrashReport(OtherPid(), &dumpID);
nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
if (obs) {
RefPtr<nsHashPropertyBag> props = new nsHashPropertyBag();
// It's okay for dumpID to be empty if there was no minidump generated
// tests like ipc/glue/test/browser/browser_utility_crashReporter.js are
// there to verify this
if (!dumpID.IsEmpty()) {
props->SetPropertyAsAString(u"dumpID"_ns, dumpID);
}
nsAutoString pid;
pid.AppendInt(static_cast<uint64_t>(OtherPid()));
obs->NotifyObservers((nsIPropertyBag2*)props, "ipc:utility-shutdown",
pid.get());
}
}
mHost->OnChannelClosed();

Просмотреть файл

@ -2,9 +2,12 @@
support-files =
../../../../tools/profiler/tests/shared-head.js
[browser_utility_crashReporter.js]
skip-if = !crashreporter
[browser_utility_clean_shutdown.js]
[browser_utility_hard_kill.js]
[browser_utility_memoryReport.js]
skip-if = tsan # bug 1754554
[browser_utility_profiler.js]
skip-if = tsan # from tools/profiler/tests/browser/browser.ini, timing out on profiler tests?
[browser_utility_start.js]

Просмотреть файл

@ -0,0 +1,83 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
var utilityPid = undefined;
const utilityProcessTest = Cc[
"@mozilla.org/utility-process-test;1"
].createInstance(Ci.nsIUtilityProcessTest);
add_task(async () => {
await utilityProcessTest
.startProcess()
.then(async pid => {
utilityPid = pid;
ok(true, "Could start Utility process: " + pid);
})
.catch(async () => {
ok(false, "Cannot start Utility process?");
});
});
add_task(async () => {
SimpleTest.expectChildProcessCrash();
const crashMan = Services.crashmanager;
const utilityProcessGone = TestUtils.topicObserved("ipc:utility-shutdown");
info("prune any previous crashes");
const future = new Date(Date.now() + 1000 * 60 * 60 * 24);
await crashMan.pruneOldCrashes(future);
info("crash Utility Process");
const ProcessTools = Cc["@mozilla.org/processtools-service;1"].getService(
Ci.nsIProcessToolsService
);
ProcessTools.crash(utilityPid);
info("Waiting for utility process to go away.");
let [subject, data] = await utilityProcessGone;
ok(
parseInt(data, 10) === utilityPid,
`Should match the crashed PID ${utilityPid} with ${data}`
);
ok(
subject instanceof Ci.nsIPropertyBag2,
"Subject needs to be a nsIPropertyBag2 to clean up properly"
);
const dumpID = subject.getPropertyAsAString("dumpID");
ok(dumpID, "There should be a dumpID");
await crashMan.ensureCrashIsPresent(dumpID);
await crashMan.getCrashes().then(crashes => {
is(crashes.length, 1, "There should be only one record");
const crash = crashes[0];
ok(
crash.isOfType(
crashMan.processTypes[Ci.nsIXULRuntime.PROCESS_TYPE_UTILITY],
crashMan.CRASH_TYPE_CRASH
),
"Record should be a utility process crash"
);
ok(crash.id === dumpID, "Record should have an ID");
});
let minidumpDirectory = Services.dirsvc.get("ProfD", Ci.nsIFile);
minidumpDirectory.append("minidumps");
let dumpfile = minidumpDirectory.clone();
dumpfile.append(dumpID + ".dmp");
if (dumpfile.exists()) {
info(`Removal of ${dumpfile.path}`);
dumpfile.remove(false);
}
let extrafile = minidumpDirectory.clone();
extrafile.append(dumpID + ".extra");
info(`Removal of ${extrafile.path}`);
if (extrafile.exists()) {
extrafile.remove(false);
}
});