From 5e3572023f453aab8dd4a5b80d6c26e63ad289be Mon Sep 17 00:00:00 2001 From: Alexandre Poirot Date: Tue, 14 Aug 2018 08:54:10 -0700 Subject: [PATCH] Bug 1482070 - Move StackTraceCollector to its own file. r=Honza Summary: Depends On D3603 Reviewers: Honza! Tags: #secure-revision Bug #: 1482070 Differential Revision: https://phabricator.services.mozilla.com/D3604 MozReview-Commit-ID: 53aaLHR6lv --- .../server/actors/network-monitor/moz.build | 1 + .../network-monitor/stack-trace-collector.js | 115 ++++++++++++++++++ devtools/server/actors/webconsole.js | 2 +- devtools/shared/webconsole/network-monitor.js | 98 --------------- 4 files changed, 117 insertions(+), 99 deletions(-) create mode 100644 devtools/server/actors/network-monitor/stack-trace-collector.js diff --git a/devtools/server/actors/network-monitor/moz.build b/devtools/server/actors/network-monitor/moz.build index 6558dec28e7e..e04c9075e3c5 100644 --- a/devtools/server/actors/network-monitor/moz.build +++ b/devtools/server/actors/network-monitor/moz.build @@ -6,4 +6,5 @@ DevToolsModules( 'channel-event-sink.js', + 'stack-trace-collector.js', ) diff --git a/devtools/server/actors/network-monitor/stack-trace-collector.js b/devtools/server/actors/network-monitor/stack-trace-collector.js new file mode 100644 index 000000000000..c7dc9cc27449 --- /dev/null +++ b/devtools/server/actors/network-monitor/stack-trace-collector.js @@ -0,0 +1,115 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* vim: set ft= javascript ts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +"use strict"; + +const {Ci, components} = require("chrome"); +const Services = require("Services"); + +loader.lazyRequireGetter(this, "ChannelEventSinkFactory", + "devtools/server/actors/network-monitor/channel-event-sink", + true); +loader.lazyRequireGetter(this, "matchRequest", + "devtools/server/actors/network-monitor/network-observer", + true); + +function StackTraceCollector(filters, netmonitors) { + this.filters = filters; + this.stacktracesById = new Map(); + this.netmonitors = netmonitors; +} + +StackTraceCollector.prototype = { + init() { + Services.obs.addObserver(this, "http-on-opening-request"); + ChannelEventSinkFactory.getService().registerCollector(this); + this.onGetStack = this.onGetStack.bind(this); + for (const { messageManager } of this.netmonitors) { + messageManager.addMessageListener("debug:request-stack", this.onGetStack); + } + }, + + destroy() { + Services.obs.removeObserver(this, "http-on-opening-request"); + ChannelEventSinkFactory.getService().unregisterCollector(this); + for (const { messageManager } of this.netmonitors) { + messageManager.removeMessageListener("debug:request-stack", this.onGetStack); + } + }, + + _saveStackTrace(channel, stacktrace) { + for (const { messageManager } of this.netmonitors) { + messageManager.sendAsyncMessage("debug:request-stack-available", { + channelId: channel.channelId, + stacktrace: stacktrace && stacktrace.length > 0 + }); + } + this.stacktracesById.set(channel.channelId, stacktrace); + }, + + observe(subject) { + const channel = subject.QueryInterface(Ci.nsIHttpChannel); + + if (!matchRequest(channel, this.filters)) { + return; + } + + // Convert the nsIStackFrame XPCOM objects to a nice JSON that can be + // passed around through message managers etc. + let frame = components.stack; + const stacktrace = []; + if (frame && frame.caller) { + frame = frame.caller; + while (frame) { + stacktrace.push({ + filename: frame.filename, + lineNumber: frame.lineNumber, + columnNumber: frame.columnNumber, + functionName: frame.name, + asyncCause: frame.asyncCause, + }); + frame = frame.caller || frame.asyncCaller; + } + } + + this._saveStackTrace(channel, stacktrace); + }, + + // eslint-disable-next-line no-shadow + onChannelRedirect(oldChannel, newChannel, flags) { + // We can be called with any nsIChannel, but are interested only in HTTP channels + try { + oldChannel.QueryInterface(Ci.nsIHttpChannel); + newChannel.QueryInterface(Ci.nsIHttpChannel); + } catch (ex) { + return; + } + + const oldId = oldChannel.channelId; + const stacktrace = this.stacktracesById.get(oldId); + if (stacktrace) { + this._saveStackTrace(newChannel, stacktrace); + } + }, + + getStackTrace(channelId) { + const trace = this.stacktracesById.get(channelId); + this.stacktracesById.delete(channelId); + return trace; + }, + + onGetStack(msg) { + const messageManager = msg.target; + const channelId = msg.data; + const stack = this.getStackTrace(channelId); + messageManager.sendAsyncMessage("debug:request-stack", { + channelId, + stack, + }); + }, +}; + +exports.StackTraceCollector = StackTraceCollector; diff --git a/devtools/server/actors/webconsole.js b/devtools/server/actors/webconsole.js index cec59ad1b1f1..72c848468b3f 100644 --- a/devtools/server/actors/webconsole.js +++ b/devtools/server/actors/webconsole.js @@ -21,7 +21,7 @@ const ErrorDocs = require("devtools/server/actors/errordocs"); loader.lazyRequireGetter(this, "NetworkMonitorActor", "devtools/server/actors/network-monitor", true); loader.lazyRequireGetter(this, "ConsoleProgressListener", "devtools/server/actors/webconsole/listeners/console-progress", true); -loader.lazyRequireGetter(this, "StackTraceCollector", "devtools/shared/webconsole/network-monitor", true); +loader.lazyRequireGetter(this, "StackTraceCollector", "devtools/server/actors/network-monitor/stack-trace-collector", true); loader.lazyRequireGetter(this, "JSPropertyProvider", "devtools/shared/webconsole/js-property-provider", true); loader.lazyRequireGetter(this, "Parser", "resource://devtools/shared/Parser.jsm", true); loader.lazyRequireGetter(this, "NetUtil", "resource://gre/modules/NetUtil.jsm", true); diff --git a/devtools/shared/webconsole/network-monitor.js b/devtools/shared/webconsole/network-monitor.js index e95e36a2e288..cffcf9f0880d 100644 --- a/devtools/shared/webconsole/network-monitor.js +++ b/devtools/shared/webconsole/network-monitor.js @@ -102,104 +102,6 @@ function matchRequest(channel, filters) { return false; } -function StackTraceCollector(filters, netmonitors) { - this.filters = filters; - this.stacktracesById = new Map(); - this.netmonitors = netmonitors; -} - -StackTraceCollector.prototype = { - init() { - Services.obs.addObserver(this, "http-on-opening-request"); - ChannelEventSinkFactory.getService().registerCollector(this); - this.onGetStack = this.onGetStack.bind(this); - for (const { messageManager } of this.netmonitors) { - messageManager.addMessageListener("debug:request-stack", this.onGetStack); - } - }, - - destroy() { - Services.obs.removeObserver(this, "http-on-opening-request"); - ChannelEventSinkFactory.getService().unregisterCollector(this); - for (const { messageManager } of this.netmonitors) { - messageManager.removeMessageListener("debug:request-stack", this.onGetStack); - } - }, - - _saveStackTrace(channel, stacktrace) { - for (const { messageManager } of this.netmonitors) { - messageManager.sendAsyncMessage("debug:request-stack-available", { - channelId: channel.channelId, - stacktrace: stacktrace && stacktrace.length > 0 - }); - } - this.stacktracesById.set(channel.channelId, stacktrace); - }, - - observe(subject) { - const channel = subject.QueryInterface(Ci.nsIHttpChannel); - - if (!matchRequest(channel, this.filters)) { - return; - } - - // Convert the nsIStackFrame XPCOM objects to a nice JSON that can be - // passed around through message managers etc. - let frame = components.stack; - const stacktrace = []; - if (frame && frame.caller) { - frame = frame.caller; - while (frame) { - stacktrace.push({ - filename: frame.filename, - lineNumber: frame.lineNumber, - columnNumber: frame.columnNumber, - functionName: frame.name, - asyncCause: frame.asyncCause, - }); - frame = frame.caller || frame.asyncCaller; - } - } - - this._saveStackTrace(channel, stacktrace); - }, - - // eslint-disable-next-line no-shadow - onChannelRedirect(oldChannel, newChannel, flags) { - // We can be called with any nsIChannel, but are interested only in HTTP channels - try { - oldChannel.QueryInterface(Ci.nsIHttpChannel); - newChannel.QueryInterface(Ci.nsIHttpChannel); - } catch (ex) { - return; - } - - const oldId = oldChannel.channelId; - const stacktrace = this.stacktracesById.get(oldId); - if (stacktrace) { - this._saveStackTrace(newChannel, stacktrace); - } - }, - - getStackTrace(channelId) { - const trace = this.stacktracesById.get(channelId); - this.stacktracesById.delete(channelId); - return trace; - }, - - onGetStack(msg) { - const messageManager = msg.target; - const channelId = msg.data; - const stack = this.getStackTrace(channelId); - messageManager.sendAsyncMessage("debug:request-stack", { - channelId, - stack, - }); - }, -}; - -exports.StackTraceCollector = StackTraceCollector; - /** * The network response listener implements the nsIStreamListener and * nsIRequestObserver interfaces. This is used within the NetworkMonitor feature