Don't set tracing hooks until tracing has started (bug 1049248). r=fitzgen
authorPanos Astithas <past@mozilla.com>
Wed, 17 Sep 2014 20:00:40 +0300
changeset 206051 26fede342996e0459ec99cb9b648fa256181fa42
parent 206050 8a6e14c73d94dd2c4dadbf94f12c03f41f49b8e6
child 206052 d6f78faaefcc1dddf3a3f0e484bfa7dcb5997501
child 206169 18ac09aeaf6cc09cbb866119de16312aaac9ec3a
push id49338
push userkwierso@gmail.com
push dateThu, 18 Sep 2014 23:10:09 +0000
treeherdermozilla-inbound@245051c6a7ed [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersfitzgen
bugs1049248
milestone35.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Don't set tracing hooks until tracing has started (bug 1049248). r=fitzgen
browser/devtools/debugger/test/browser.ini
browser/devtools/debugger/test/browser_dbg_tracing-08.js
toolkit/devtools/server/actors/tracer.js
--- a/browser/devtools/debugger/test/browser.ini
+++ b/browser/devtools/debugger/test/browser.ini
@@ -262,16 +262,17 @@ skip-if = os == "linux" || e10s # Bug 88
 [browser_dbg_terminate-on-tab-close.js]
 [browser_dbg_tracing-01.js]
 [browser_dbg_tracing-02.js]
 [browser_dbg_tracing-03.js]
 [browser_dbg_tracing-04.js]
 [browser_dbg_tracing-05.js]
 [browser_dbg_tracing-06.js]
 [browser_dbg_tracing-07.js]
+[browser_dbg_tracing-08.js]
 [browser_dbg_variables-view-01.js]
 [browser_dbg_variables-view-02.js]
 [browser_dbg_variables-view-03.js]
 [browser_dbg_variables-view-04.js]
 [browser_dbg_variables-view-05.js]
 [browser_dbg_variables-view-accessibility.js]
 [browser_dbg_variables-view-data.js]
 [browser_dbg_variables-view-edit-cancel.js]
new file mode 100644
--- /dev/null
+++ b/browser/devtools/debugger/test/browser_dbg_tracing-08.js
@@ -0,0 +1,59 @@
+/* Any copyright is dedicated to the Public Domain.
+   http://creativecommons.org/publicdomain/zero/1.0/ */
+
+/**
+ * Test that tracing about:config doesn't produce errors.
+ */
+
+const TAB_URL = "about:config";
+
+let gPanel, gDoneChecks;
+
+function test() {
+  gDoneChecks = promise.defer();
+  const tracerPref = promise.defer();
+  const configPref = promise.defer();
+  SpecialPowers.pushPrefEnv({'set': [["devtools.debugger.tracer", true]]}, tracerPref.resolve);
+  SpecialPowers.pushPrefEnv({'set': [["general.warnOnAboutConfig", false]]}, configPref.resolve);
+  promise.all([tracerPref.promise, configPref.promise]).then(() => {
+    initDebugger(TAB_URL).then(([,, aPanel]) => {
+      gPanel = aPanel;
+      gPanel.panelWin.gClient.addOneTimeListener("traces", testTraceLogs);
+    }).then(() => startTracing(gPanel))
+      .then(generateTrace)
+      .then(() => waitForClientEvents(gPanel, "traces"))
+      .then(() => gDoneChecks.promise)
+      .then(() => stopTracing(gPanel))
+      .then(resetPreferences)
+      .then(() => closeDebuggerAndFinish(gPanel))
+      .then(null, aError => {
+        ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
+      });
+  });
+}
+
+function testTraceLogs(name, packet) {
+  info("Traces: " + packet.traces.length);
+  ok(packet.traces.length > 0, "Got some traces.");
+  ok(packet.traces.every(t => t.type != "enteredFrame" || !!t.location),
+     "All enteredFrame traces contain location.");
+  gDoneChecks.resolve();
+}
+
+function generateTrace(name, packet) {
+  // Interact with the page to cause JS execution.
+  let search = content.document.getElementById("textbox");
+  info("Interacting with the page.");
+  search.value = "devtools";
+}
+
+function resetPreferences() {
+  const deferred = promise.defer();
+  SpecialPowers.popPrefEnv(() => SpecialPowers.popPrefEnv(deferred.resolve));
+  return deferred.promise;
+}
+
+registerCleanupFunction(function() {
+  gPanel = null;
+  gDoneChecks = null;
+});
--- a/toolkit/devtools/server/actors/tracer.js
+++ b/toolkit/devtools/server/actors/tracer.js
@@ -101,17 +101,16 @@ TracerActor.prototype = {
 
   get attached() { return this._attached; },
   get idle()     { return this._attached && this._activeTraces.size === 0; },
   get tracing()  { return this._attached && this._activeTraces.size > 0; },
 
   get dbg() {
     if (!this._dbg) {
       this._dbg = this._parent.makeDebugger();
-      this._dbg.onEnterFrame = this.onEnterFrame;
     }
     return this._dbg;
   },
 
   /**
    * Buffer traces and only send them every BUFFER_SEND_DELAY milliseconds.
    */
   _send: function(aPacket) {
@@ -183,16 +182,17 @@ TracerActor.prototype = {
         return {
           error: "badParameterType",
           message: "No such trace type: " + traceType
         };
       }
     }
 
     if (this.idle) {
+      this.dbg.onEnterFrame = this.onEnterFrame;
       this.dbg.enabled = true;
       this._sequence = 0;
       this._startTime = Date.now();
     }
 
     // Start recording all requested trace types.
     for (let traceType of aRequest.trace) {
       this._requestsForTraceType[traceType]++;
@@ -239,16 +239,17 @@ TracerActor.prototype = {
     }
 
     // Clear hit counts if no trace is requesting them.
     if (!this._requestsForTraceType.hitCount) {
       this._hitCounts.clear();
     }
 
     if (this.idle) {
+      this._dbg.onEnterFrame = undefined;
       this.dbg.enabled = false;
     }
 
     return {
       type: "stoppedTrace",
       why: "requested",
       name
     };
@@ -259,21 +260,21 @@ TracerActor.prototype = {
   /**
    * Called by the engine when a frame is entered. Sends an unsolicited packet
    * to the client carrying requested trace information.
    *
    * @param aFrame Debugger.Frame
    *        The stack frame that was entered.
    */
   onEnterFrame: function(aFrame) {
+    if (aFrame.script && aFrame.script.url == "self-hosted") {
+      return;
+    }
+
     Task.spawn(function*() {
-      if (aFrame.script && aFrame.script.url == "self-hosted") {
-        return;
-      }
-
       // This function might request original (i.e. source-mapped) location,
       // which is asynchronous. We need to ensure that packets are sent out
       // in the correct order.
       let runInOrder = this._packetScheduler.schedule();
 
       let packet = {
         type: "enteredFrame",
         sequence: this._sequence++