mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-17 07:15:46 +00:00
Bug 1214408 - Telemetry on SessionStore:update OOM;r=ttaubert
--HG-- extra : transplant_source : %3A%DB%3Cp%8Fj%24%CF%94%E9%5C%AA%17%0E%2C%03E%23%A2%98
This commit is contained in:
parent
9f82ed620a
commit
8292b78498
@ -72,6 +72,9 @@ const MESSAGES = [
|
||||
// A crashed tab was revived by navigating to a different page. Remove its
|
||||
// browser from the list of crashed browsers to stop ignoring its messages.
|
||||
"SessionStore:crashedTabRevived",
|
||||
|
||||
// The content script encountered an error.
|
||||
"SessionStore:error",
|
||||
];
|
||||
|
||||
// The list of messages we accept from <xul:browser>s that have no tab
|
||||
@ -85,6 +88,9 @@ const NOTAB_MESSAGES = new Set([
|
||||
|
||||
// For a description see above.
|
||||
"SessionStore:update",
|
||||
|
||||
// For a description see above.
|
||||
"SessionStore:error",
|
||||
]);
|
||||
|
||||
// The list of messages we accept without an "epoch" parameter.
|
||||
@ -95,6 +101,9 @@ const NOEPOCH_MESSAGES = new Set([
|
||||
|
||||
// For a description see above.
|
||||
"SessionStore:crashedTabRevived",
|
||||
|
||||
// For a description see above.
|
||||
"SessionStore:error",
|
||||
]);
|
||||
|
||||
// The list of messages we want to receive even during the short period after a
|
||||
@ -106,6 +115,9 @@ const CLOSED_MESSAGES = new Set([
|
||||
|
||||
// For a description see above.
|
||||
"SessionStore:update",
|
||||
|
||||
// For a description see above.
|
||||
"SessionStore:error",
|
||||
]);
|
||||
|
||||
// These are tab events that we listen to.
|
||||
@ -808,6 +820,9 @@ var SessionStoreInternal = {
|
||||
case "SessionStore:crashedTabRevived":
|
||||
this._crashedBrowsers.delete(browser.permanentKey);
|
||||
break;
|
||||
case "SessionStore:error":
|
||||
this.reportInternalError(data);
|
||||
break;
|
||||
default:
|
||||
throw new Error(`received unknown message '${aMessage.name}'`);
|
||||
break;
|
||||
@ -3848,6 +3863,19 @@ var SessionStoreInternal = {
|
||||
*/
|
||||
resetEpoch(browser) {
|
||||
this._browserEpochs.delete(browser.permanentKey);
|
||||
},
|
||||
|
||||
/**
|
||||
* Handle an error report from a content process.
|
||||
*/
|
||||
reportInternalError(data) {
|
||||
// For the moment, we only report errors through Telemetry.
|
||||
if (data.telemetry) {
|
||||
for (let key of Object.keys(data.telemetry)) {
|
||||
let histogram = Telemetry.getHistogramById(key);
|
||||
histogram.add(data.telemetry[key]);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -29,10 +29,6 @@ XPCOMUtils.defineLazyModuleGetter(this, "SessionHistory",
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "SessionStorage",
|
||||
"resource:///modules/sessionstore/SessionStorage.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyServiceGetter(this, "cpmm",
|
||||
"@mozilla.org/childprocessmessagemanager;1",
|
||||
"nsISyncMessageSender");
|
||||
|
||||
Cu.import("resource:///modules/sessionstore/FrameTree.jsm", this);
|
||||
var gFrameTree = new FrameTree(this);
|
||||
|
||||
@ -692,12 +688,21 @@ var MessageQueue = {
|
||||
FX_SESSION_RESTORE_CONTENT_COLLECT_DATA_LONGEST_OP_MS: durationMs
|
||||
}
|
||||
|
||||
// Send all data to the parent process.
|
||||
sendMessage("SessionStore:update", {
|
||||
id: this._id, data, telemetry, flushID,
|
||||
isFinal: options.isFinal || false,
|
||||
epoch: gCurrentEpoch
|
||||
});
|
||||
try {
|
||||
// Send all data to the parent process.
|
||||
sendMessage("SessionStore:update", {
|
||||
id: this._id, data, telemetry, flushID,
|
||||
isFinal: options.isFinal || false,
|
||||
epoch: gCurrentEpoch
|
||||
});
|
||||
} catch (ex if ex && ex.result == Cr.NS_ERROR_OUT_OF_MEMORY) {
|
||||
let telemetry = {
|
||||
FX_SESSION_RESTORE_SEND_UPDATE_CAUSED_OOM: 1
|
||||
};
|
||||
sendMessage("SessionStore:error", {
|
||||
telemetry
|
||||
});
|
||||
}
|
||||
|
||||
// Increase our unique message ID.
|
||||
this._id++;
|
||||
|
@ -211,3 +211,4 @@ skip-if = true
|
||||
skip-if = os == "mac"
|
||||
|
||||
[browser_911547.js]
|
||||
[browser_send_async_message_oom.js]
|
||||
|
@ -0,0 +1,71 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
const {Services} = Cu.import("resource://gre/modules/Services.jsm", {});
|
||||
|
||||
const HISTOGRAM_NAME = "FX_SESSION_RESTORE_SEND_UPDATE_CAUSED_OOM";
|
||||
|
||||
/**
|
||||
* Test that an OOM in sendAsyncMessage in a framescript will be reported
|
||||
* to Telemetry.
|
||||
*/
|
||||
|
||||
add_task(function* init() {
|
||||
Services.telemetry.canRecordExtended = true;
|
||||
});
|
||||
|
||||
function frameScript() {
|
||||
// Make send[A]syncMessage("SessionStore:update", ...) simulate OOM.
|
||||
// Other operations are unaffected.
|
||||
let mm = docShell.sameTypeRootTreeItem.
|
||||
QueryInterface(Ci.nsIDocShell).
|
||||
QueryInterface(Ci.nsIInterfaceRequestor).
|
||||
getInterface(Ci.nsIContentFrameMessageManager);
|
||||
|
||||
let wrap = function(original) {
|
||||
return function(name, ...args) {
|
||||
if (name != "SessionStore:update") {
|
||||
return original(name, ...args);
|
||||
}
|
||||
throw new Components.Exception("Simulated OOM", Cr.NS_ERROR_OUT_OF_MEMORY);
|
||||
}
|
||||
}
|
||||
|
||||
mm.sendAsyncMessage = wrap(mm.sendAsyncMessage);
|
||||
mm.sendSyncMessage = wrap(mm.sendSyncMessage);
|
||||
}
|
||||
|
||||
add_task(function*() {
|
||||
// Capture original state.
|
||||
let snapshot = Services.telemetry.getHistogramById(HISTOGRAM_NAME).snapshot();
|
||||
|
||||
// Open a browser, configure it to cause OOM.
|
||||
let newTab = gBrowser.addTab("about:robots");
|
||||
let browser = newTab.linkedBrowser;
|
||||
yield ContentTask.spawn(browser, null, frameScript);
|
||||
|
||||
|
||||
let promiseReported = new Promise(resolve => {
|
||||
browser.messageManager.addMessageListener("SessionStore:error", resolve);
|
||||
});
|
||||
|
||||
// Attempt to flush. This should fail.
|
||||
let promiseFlushed = TabStateFlusher.flush(browser);
|
||||
promiseFlushed.then(() => {throw new Error("Flush should have failed")});
|
||||
|
||||
// The frame script should report an error.
|
||||
yield promiseReported;
|
||||
|
||||
// Give us some time to handle that error.
|
||||
yield new Promise(resolve => setTimeout(resolve, 10));
|
||||
|
||||
// By now, Telemetry should have been updated.
|
||||
let snapshot2 = Services.telemetry.getHistogramById(HISTOGRAM_NAME).snapshot();
|
||||
gBrowser.removeTab(newTab);
|
||||
|
||||
Assert.ok(snapshot2.sum > snapshot.sum);
|
||||
});
|
||||
|
||||
add_task(function* cleanup() {
|
||||
Services.telemetry.canRecordExtended = false;
|
||||
});
|
@ -4352,6 +4352,12 @@
|
||||
"extended_statistics_ok": true,
|
||||
"description": "Session restore: Time spent blocking the main thread while restoring a window state (ms)"
|
||||
},
|
||||
"FX_SESSION_RESTORE_SEND_UPDATE_CAUSED_OOM": {
|
||||
"alert_emails": ["session-restore-telemetry-alerts@mozilla.com"],
|
||||
"expires_in_version": "default",
|
||||
"kind": "count",
|
||||
"description": "Count of messages sent by SessionRestore from child frames to the parent and that cannot be transmitted as they eat up too much memory."
|
||||
},
|
||||
"FX_TABLETMODE_PAGE_LOAD": {
|
||||
"expires_in_version": "47",
|
||||
"kind": "exponential",
|
||||
|
Loading…
Reference in New Issue
Block a user