summaryrefslogtreecommitdiffstats
path: root/toolkit/crashreporter/test/unit/head_crashreporter.js
diff options
context:
space:
mode:
authorMatt A. Tobin <mattatobin@localhost.localdomain>2018-02-02 04:16:08 -0500
committerMatt A. Tobin <mattatobin@localhost.localdomain>2018-02-02 04:16:08 -0500
commit5f8de423f190bbb79a62f804151bc24824fa32d8 (patch)
tree10027f336435511475e392454359edea8e25895d /toolkit/crashreporter/test/unit/head_crashreporter.js
parent49ee0794b5d912db1f95dce6eb52d781dc210db5 (diff)
downloadUXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.gz
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.lz
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.xz
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.zip
Add m-esr52 at 52.6.0
Diffstat (limited to 'toolkit/crashreporter/test/unit/head_crashreporter.js')
-rw-r--r--toolkit/crashreporter/test/unit/head_crashreporter.js173
1 files changed, 173 insertions, 0 deletions
diff --git a/toolkit/crashreporter/test/unit/head_crashreporter.js b/toolkit/crashreporter/test/unit/head_crashreporter.js
new file mode 100644
index 000000000..45c491ad2
--- /dev/null
+++ b/toolkit/crashreporter/test/unit/head_crashreporter.js
@@ -0,0 +1,173 @@
+Components.utils.import("resource://gre/modules/osfile.jsm");
+
+function getEventDir() {
+ return OS.Path.join(do_get_tempdir().path, "crash-events");
+}
+
+/*
+ * Run an xpcshell subprocess and crash it.
+ *
+ * @param setup
+ * A string of JavaScript code to execute in the subprocess
+ * before crashing. If this is a function and not a string,
+ * it will have .toSource() called on it, and turned into
+ * a call to itself. (for programmer convenience)
+ * This code will be evaluted between crasher_subprocess_head.js
+ * and crasher_subprocess_tail.js, so it will have access
+ * to everything defined in crasher_subprocess_head.js,
+ * which includes "crashReporter", a variable holding
+ * the crash reporter service.
+ *
+ * @param callback
+ * A JavaScript function to be called after the subprocess
+ * crashes. It will be passed (minidump, extra), where
+ * minidump is an nsILocalFile of the minidump file produced,
+ * and extra is an object containing the key,value pairs from
+ * the .extra file.
+ *
+ * @param canReturnZero
+ * If true, the subprocess may return with a zero exit code.
+ * Certain types of crashes may not cause the process to
+ * exit with an error.
+ */
+function do_crash(setup, callback, canReturnZero)
+{
+ // get current process filename (xpcshell)
+ let ds = Components.classes["@mozilla.org/file/directory_service;1"]
+ .getService(Components.interfaces.nsIProperties);
+ let bin = ds.get("XREExeF", Components.interfaces.nsILocalFile);
+ if (!bin.exists()) {
+ // weird, can't find xpcshell binary?
+ do_throw("Can't find xpcshell binary!");
+ }
+ // get Gre dir (GreD)
+ let greD = ds.get("GreD", Components.interfaces.nsILocalFile);
+ let headfile = do_get_file("crasher_subprocess_head.js");
+ let tailfile = do_get_file("crasher_subprocess_tail.js");
+ // run xpcshell -g GreD -f head -e "some setup code" -f tail
+ let process = Components.classes["@mozilla.org/process/util;1"]
+ .createInstance(Components.interfaces.nsIProcess);
+ process.init(bin);
+ let args = ['-g', greD.path,
+ '-f', headfile.path];
+ if (setup) {
+ if (typeof(setup) == "function")
+ // funky, but convenient
+ setup = "("+setup.toSource()+")();";
+ args.push('-e', setup);
+ }
+ args.push('-f', tailfile.path);
+
+ let env = Components.classes["@mozilla.org/process/environment;1"]
+ .getService(Components.interfaces.nsIEnvironment);
+
+ let crashD = do_get_tempdir();
+ crashD.append("crash-events");
+ if (!crashD.exists()) {
+ crashD.create(crashD.DIRECTORY_TYPE, 0o700);
+ }
+
+ env.set("CRASHES_EVENTS_DIR", crashD.path);
+
+ try {
+ process.run(true, args, args.length);
+ }
+ catch (ex) {} // on Windows we exit with a -1 status when crashing.
+ finally {
+ env.set("CRASHES_EVENTS_DIR", "");
+ }
+
+ if (!canReturnZero) {
+ // should exit with an error (should have crashed)
+ do_check_neq(process.exitValue, 0);
+ }
+
+ handleMinidump(callback);
+}
+
+function handleMinidump(callback)
+{
+ // find minidump
+ let minidump = null;
+ let en = do_get_tempdir().directoryEntries;
+ while (en.hasMoreElements()) {
+ let f = en.getNext().QueryInterface(Components.interfaces.nsILocalFile);
+ if (f.leafName.substr(-4) == ".dmp") {
+ minidump = f;
+ break;
+ }
+ }
+
+ if (minidump == null)
+ do_throw("No minidump found!");
+
+ let extrafile = minidump.clone();
+ extrafile.leafName = extrafile.leafName.slice(0, -4) + ".extra";
+
+ let memoryfile = minidump.clone();
+ memoryfile.leafName = memoryfile.leafName.slice(0, -4) + ".memory.json.gz";
+
+ // Just in case, don't let these files linger.
+ do_register_cleanup(function() {
+ if (minidump.exists())
+ minidump.remove(false);
+ if (extrafile.exists())
+ extrafile.remove(false);
+ if (memoryfile.exists())
+ memoryfile.remove(false);
+ });
+ do_check_true(extrafile.exists());
+ let extra = parseKeyValuePairsFromFile(extrafile);
+
+ if (callback)
+ callback(minidump, extra);
+
+ if (minidump.exists())
+ minidump.remove(false);
+ if (extrafile.exists())
+ extrafile.remove(false);
+ if (memoryfile.exists())
+ memoryfile.remove(false);
+}
+
+function do_content_crash(setup, 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();
+
+ let headfile = do_get_file("../unit/crasher_subprocess_head.js");
+ let tailfile = do_get_file("../unit/crasher_subprocess_tail.js");
+ if (setup) {
+ if (typeof(setup) == "function")
+ // funky, but convenient
+ setup = "("+setup.toSource()+")();";
+ }
+
+ let handleCrash = function() {
+ try {
+ handleMinidump(callback);
+ } catch (x) {
+ do_report_unexpected_exception(x);
+ }
+ do_test_finished();
+ };
+
+ sendCommand("load(\"" + headfile.path.replace(/\\/g, "/") + "\");", () =>
+ sendCommand(setup, () =>
+ sendCommand("load(\"" + tailfile.path.replace(/\\/g, "/") + "\");", () =>
+ 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");