зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1379857 - Record Rust panics for child process crashes. r=dmajor
Install crash reporter's panic hook in child processes (and also delay the main process installation until we know crash reporter is enabled). When collecting child crash annotations, read the Rust panic message if it exists. MozReview-Commit-ID: Gfp2E8IHjw8 --HG-- extra : rebase_source : 9e261f399e7c54fc262a1500cf2514ddd1012406
This commit is contained in:
Родитель
98a8e93fd9
Коммит
50ecb4bb87
|
@ -1391,7 +1391,14 @@ PrepareChildExceptionTimeAnnotations()
|
|||
WriteAnnotation(apiData, "OOMAllocationSize", oomAllocationSizeBuffer);
|
||||
}
|
||||
|
||||
if (gMozCrashReason) {
|
||||
char* rust_panic_reason;
|
||||
size_t rust_panic_len;
|
||||
if (get_rust_panic_reason(&rust_panic_reason, &rust_panic_len)) {
|
||||
// rust_panic_reason is not null-terminated.
|
||||
WriteLiteral(apiData, "MozCrashReason=");
|
||||
apiData.WriteBuffer(rust_panic_reason, rust_panic_len);
|
||||
WriteLiteral(apiData, "\n");
|
||||
} else if (gMozCrashReason) {
|
||||
WriteAnnotation(apiData, "MozCrashReason", gMozCrashReason);
|
||||
}
|
||||
|
||||
|
@ -1594,8 +1601,6 @@ nsresult SetExceptionHandler(nsIFile* aXREDirectory,
|
|||
if (gExceptionHandler)
|
||||
return NS_ERROR_ALREADY_INITIALIZED;
|
||||
|
||||
install_rust_panic_hook();
|
||||
|
||||
#if !defined(DEBUG) || defined(MOZ_WIDGET_GONK)
|
||||
// In non-debug builds, enable the crash reporter by default, and allow
|
||||
// disabling it with the MOZ_CRASHREPORTER_DISABLE environment variable.
|
||||
|
@ -1822,6 +1827,8 @@ nsresult SetExceptionHandler(nsIFile* aXREDirectory,
|
|||
|
||||
oldTerminateHandler = std::set_terminate(&TerminateHandler);
|
||||
|
||||
install_rust_panic_hook();
|
||||
|
||||
InitThreadAnnotation();
|
||||
|
||||
return NS_OK;
|
||||
|
@ -3780,6 +3787,8 @@ SetRemoteExceptionHandler(const nsACString& crashPipe)
|
|||
|
||||
oldTerminateHandler = std::set_terminate(&TerminateHandler);
|
||||
|
||||
install_rust_panic_hook();
|
||||
|
||||
// we either do remote or nothing, no fallback to regular crash reporting
|
||||
return gExceptionHandler->IsOutOfProcess();
|
||||
}
|
||||
|
@ -3827,6 +3836,8 @@ SetRemoteExceptionHandler()
|
|||
|
||||
oldTerminateHandler = std::set_terminate(&TerminateHandler);
|
||||
|
||||
install_rust_panic_hook();
|
||||
|
||||
// we either do remote or nothing, no fallback to regular crash reporting
|
||||
return gExceptionHandler->IsOutOfProcess();
|
||||
}
|
||||
|
@ -3856,6 +3867,8 @@ SetRemoteExceptionHandler(const nsACString& crashPipe)
|
|||
|
||||
oldTerminateHandler = std::set_terminate(&TerminateHandler);
|
||||
|
||||
install_rust_panic_hook();
|
||||
|
||||
// we either do remote or nothing, no fallback to regular crash reporting
|
||||
return gExceptionHandler->IsOutOfProcess();
|
||||
}
|
||||
|
|
|
@ -145,6 +145,13 @@ function handleMinidump(callback) {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper for testing a content process crash.
|
||||
*
|
||||
* This variant accepts a setup function which runs in the content process
|
||||
* to set data as needed _before_ the crash. The tail file triggers a generic
|
||||
* crash after setup.
|
||||
*/
|
||||
function do_content_crash(setup, callback) {
|
||||
do_load_child_test_harness();
|
||||
do_test_pending();
|
||||
|
@ -192,6 +199,55 @@ function do_content_crash(setup, callback) {
|
|||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper for testing a content process crash.
|
||||
*
|
||||
* This variant accepts a trigger function which runs in the content process
|
||||
* and does something to _trigger_ the crash.
|
||||
*/
|
||||
function do_triggered_content_crash(trigger, callback) {
|
||||
do_load_child_test_harness();
|
||||
do_test_pending();
|
||||
|
||||
// Setting the minidump path won't work in the child, so we need to do
|
||||
// that here.
|
||||
let crashReporter =
|
||||
Components.classes["@mozilla.org/toolkit/crash-reporter;1"]
|
||||
.getService(Components.interfaces.nsICrashReporter);
|
||||
crashReporter.minidumpPath = do_get_tempdir();
|
||||
|
||||
/* import-globals-from ../unit/crasher_subprocess_head.js */
|
||||
|
||||
let headfile = do_get_file("../unit/crasher_subprocess_head.js");
|
||||
if (trigger) {
|
||||
if (typeof(trigger) == "function") {
|
||||
// funky, but convenient
|
||||
trigger = "(" + trigger.toSource() + ")();";
|
||||
}
|
||||
}
|
||||
|
||||
let handleCrash = function() {
|
||||
let id = getMinidump().leafName.slice(0, -4);
|
||||
Services.crashmanager.ensureCrashIsPresent(id).then(() => {
|
||||
try {
|
||||
handleMinidump(callback);
|
||||
} catch (x) {
|
||||
do_report_unexpected_exception(x);
|
||||
}
|
||||
do_test_finished();
|
||||
});
|
||||
};
|
||||
|
||||
do_get_profile();
|
||||
makeFakeAppDir().then(() => {
|
||||
sendCommand("load(\"" + headfile.path.replace(/\\/g, "/") + "\");", () =>
|
||||
sendCommand(trigger, () =>
|
||||
do_execute_soon(handleCrash)
|
||||
)
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
// Import binary APIs via js-ctypes.
|
||||
Components.utils.import("resource://test/CrashTestUtils.jsm");
|
||||
Components.utils.import("resource://gre/modules/KeyValueParser.jsm");
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
/* import-globals-from ../unit/head_crashreporter.js */
|
||||
load("../unit/head_crashreporter.js");
|
||||
|
||||
function run_test() {
|
||||
if (!("@mozilla.org/toolkit/crash-reporter;1" in Components.classes)) {
|
||||
dump("INFO | test_content_rust_panic.js | Can't test crashreporter in a non-libxul build.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
// Try crashing with a Rust panic
|
||||
do_triggered_content_crash(
|
||||
function() {
|
||||
Components.classes["@mozilla.org/xpcom/debug;1"]
|
||||
.getService(Components.interfaces.nsIDebug2)
|
||||
.rustPanic("OH NO");
|
||||
},
|
||||
function(mdump, extra) {
|
||||
do_check_eq(extra.MozCrashReason, "OH NO");
|
||||
}
|
||||
);
|
||||
}
|
|
@ -12,3 +12,4 @@ support-files =
|
|||
skip-if = os != 'win'
|
||||
[test_content_memory_list.js]
|
||||
skip-if = os != 'win'
|
||||
[test_content_rust_panic.js]
|
Загрузка…
Ссылка в новой задаче