bug 1165017 - annotate content process URL on location change. r=mconley

--HG--
extra : rebase_source : 3c2c48e333ed0978134f87bc132a5194e402b9f1
This commit is contained in:
Ted Mielczarek 2015-05-15 13:00:11 -04:00
parent cfe5014bab
commit 9fa6778286
5 changed files with 192 additions and 2 deletions

View File

@ -147,6 +147,15 @@ let WebProgressListener = {
json.mayEnableCharacterEncodingMenu = docShell.mayEnableCharacterEncodingMenu;
json.principal = content.document.nodePrincipal;
json.synthetic = content.document.mozSyntheticDocument;
if (AppConstants.MOZ_CRASHREPORTER && CrashReporter.enabled) {
let uri = aLocationURI.clone();
try {
// If the current URI contains a username/password, remove it.
uri.userPass = "";
} catch (ex) { /* Ignore failures on about: URIs. */ }
CrashReporter.annotateCrashReport("URL", uri.spec);
}
}
this._send("Content:LocationChange", json, objects);
@ -261,8 +270,17 @@ let WebNavigation = {
},
loadURI: function(uri, flags, referrer, referrerPolicy, baseURI) {
if (AppConstants.MOZ_CRASHREPORTER && CrashReporter.enabled)
CrashReporter.annotateCrashReport("URL", uri);
if (AppConstants.MOZ_CRASHREPORTER && CrashReporter.enabled) {
let annotation = uri;
try {
let url = Services.io.newURI(uri, null, null);
// If the current URI contains a username/password, remove it.
url.userPass = "";
annotation = url.spec;
} catch (ex) { /* Ignore failures to parse and failures
on about: URIs. */ }
CrashReporter.annotateCrashReport("URL", annotation);
}
if (referrer)
referrer = Services.io.newURI(referrer, null, null);
if (baseURI)

View File

@ -31,3 +31,8 @@ support-files =
data/post_form_inner.sjs
data/post_form_outer.sjs
skip-if = e10s # Bug ?????? - test directly manipulates content (gBrowser.contentDocument.getElementById("postForm").submit();)
[browser_content_url_annotation.js]
skip-if = !e10s || !crashreporter
support-files =
file_redirect.html
file_redirect_to.html

View File

@ -0,0 +1,139 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
/*global Services, requestLongerTimeout, TestUtils, BrowserTestUtils,
ok, info, dump, is, Ci, Cu, Components, ctypes, privateNoteIntentionalCrash,
gBrowser, add_task, addEventListener, removeEventListener, ContentTask */
"use strict";
// Running this test in ASAN is slow.
requestLongerTimeout(2);
/**
* Returns a Promise that resolves once a remote <xul:browser> has experienced
* a crash. Resolves with the data from the .extra file (the crash annotations).
*
* @param browser
* The <xul:browser> that will crash
* @return Promise
*/
function crashBrowser(browser) {
let kv = {};
Cu.import("resource://gre/modules/KeyValueParser.jsm", kv);
// This frame script is injected into the remote browser, and used to
// intentionally crash the tab. We crash by using js-ctypes and dereferencing
// a bad pointer. The crash should happen immediately upon loading this
// frame script.
let frame_script = () => {
const Cu = Components.utils;
Cu.import("resource://gre/modules/ctypes.jsm");
let dies = function() {
privateNoteIntentionalCrash();
let zero = new ctypes.intptr_t(8);
let badptr = ctypes.cast(zero, ctypes.PointerType(ctypes.int32_t));
let crash = badptr.contents;
};
dump("Et tu, Brute?");
dies();
};
function checkSubject(subject, data) {
return subject instanceof Ci.nsIPropertyBag2 &&
subject.hasKey("abnormal");
};
let crashPromise = TestUtils.topicObserved('ipc:content-shutdown',
checkSubject);
let crashDataPromise = crashPromise.then(([subject, data]) => {
ok(subject instanceof Ci.nsIPropertyBag2);
let dumpID;
if ('nsICrashReporter' in Ci) {
dumpID = subject.getPropertyAsAString('dumpID');
ok(dumpID, "dumpID is present and not an empty string");
}
let extra = null;
if (dumpID) {
let minidumpDirectory = getMinidumpDirectory();
let extrafile = minidumpDirectory.clone();
extrafile.append(dumpID + '.extra');
ok(extrafile.exists(), 'found .extra file');
extra = kv.parseKeyValuePairsFromFile(extrafile);
removeFile(minidumpDirectory, dumpID + '.dmp');
removeFile(minidumpDirectory, dumpID + '.extra');
}
return extra;
});
// This frame script will crash the remote browser as soon as it is
// evaluated.
let mm = browser.messageManager;
mm.loadFrameScript("data:,(" + frame_script.toString() + ")();", false);
return crashDataPromise;
}
/**
* Removes a file from a directory. This is a no-op if the file does not
* exist.
*
* @param directory
* The nsIFile representing the directory to remove from.
* @param filename
* A string for the file to remove from the directory.
*/
function removeFile(directory, filename) {
let file = directory.clone();
file.append(filename);
if (file.exists()) {
file.remove(false);
}
}
/**
* Returns the directory where crash dumps are stored.
*
* @return nsIFile
*/
function getMinidumpDirectory() {
let dir = Services.dirsvc.get('ProfD', Ci.nsIFile);
dir.append("minidumps");
return dir;
}
/**
* Checks that the URL is correctly annotated on a content process crash.
*/
add_task(function* test_content_url_annotation() {
let url = "https://example.com/browser/toolkit/content/tests/browser/file_redirect.html";
let redirect_url = "https://example.com/browser/toolkit/content/tests/browser/file_redirect_to.html";
yield BrowserTestUtils.withNewTab({
gBrowser: gBrowser
}, function* (browser) {
ok(browser.isRemoteBrowser, "Should be a remote browser");
// file_redirect.html should send us to file_redirect_to.html
let promise = ContentTask.spawn(browser, {}, function* () {
dump('ContentTask starting...\n');
yield new Promise((resolve) => {
addEventListener("RedirectDone", function listener() {
dump('Got RedirectDone\n');
removeEventListener("RedirectDone", listener);
resolve();
}, true, true);
});
});
browser.loadURI(url);
yield promise;
// Crash the tab
let annotations = yield crashBrowser(browser);
ok("URL" in annotations, "annotated a URL");
is(annotations.URL, redirect_url,
"Should have annotated the URL after redirect");
});
});

View File

@ -0,0 +1,13 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>redirecting...</title>
<script>
window.addEventListener("load",
() => window.location = "file_redirect_to.html");
</script>
<body>
redirectin u bro
</body>
</html>

View File

@ -0,0 +1,15 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>redirected!</title>
<script>
window.addEventListener("load", () => {
var event = new Event("RedirectDone");
document.dispatchEvent(event);
});
</script>
<body>
u got redirected, bro
</body>
</html>