Bug 1552453 - Breakpoint doesnt pause in file during page load. r=loganfsmyth a=jcristau
authorJason Laster <jlaster@mozilla.com>
Thu, 23 May 2019 12:52:34 +0000
changeset 536535 7465d0005ada7a518cd7cc1b542473bbfb356ff6
parent 536534 2841c37353a5c50fdecf0284007308409e0c3474
child 536536 01dbfca9942768deb70050c03e5692ab9b8a711f
push id2082
push userffxbld-merge
push dateMon, 01 Jul 2019 08:34:18 +0000
treeherdermozilla-release@2fb19d0466d2 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersloganfsmyth, jcristau
bugs1552453
milestone68.0
Bug 1552453 - Breakpoint doesnt pause in file during page load. r=loganfsmyth a=jcristau Differential Revision: https://phabricator.services.mozilla.com/D32161
devtools/server/actors/thread.js
devtools/server/tests/unit/test_breakpoint-23.js
devtools/server/tests/unit/xpcshell.ini
devtools/shared/client/thread-client.js
--- a/devtools/server/actors/thread.js
+++ b/devtools/server/actors/thread.js
@@ -1659,24 +1659,25 @@ const ThreadActor = ActorClassWithSpec(t
     // and so we also need to be sure that there is still a source actor for the source.
     let sourceActor;
     if (this._debuggerSourcesSeen.has(source) && this.sources.hasSourceActor(source)) {
       sourceActor = this.sources.getSourceActor(source);
     } else {
       sourceActor = this.sources.createSourceActor(source);
     }
 
-    if (this._onLoadBreakpointURLs.has(source.url)) {
-      this.setBreakpoint({ sourceUrl: source.url, line: 1 }, {});
+    const sourceUrl = sourceActor.url;
+    if (this._onLoadBreakpointURLs.has(sourceUrl)) {
+      this.setBreakpoint({ sourceUrl, line: 1 }, {});
     }
 
     const bpActors = this.breakpointActorMap.findActors()
-    .filter((actor) => {
-      return actor.location.sourceUrl && actor.location.sourceUrl == source.url;
-    });
+    .filter((actor) =>
+      actor.location.sourceUrl && actor.location.sourceUrl == sourceUrl
+    );
 
     for (const actor of bpActors) {
       sourceActor.applyBreakpoint(actor);
     }
 
     this._debuggerSourcesSeen.add(source);
     return true;
   },
new file mode 100644
--- /dev/null
+++ b/devtools/server/tests/unit/test_breakpoint-23.js
@@ -0,0 +1,29 @@
+/* eslint-disable max-nested-callbacks */
+/* Any copyright is dedicated to the Public Domain.
+   http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+/**
+ * Bug 1552453 - Verify that breakpoints are hit for evaluated
+ * scripts that contain a source url pragma.
+ */
+add_task(threadClientTest(async ({ threadClient, targetFront }) => {
+  await threadClient.setBreakpoint(
+    { sourceUrl: "http://example.com/code.js", line: 2, column: 1 },
+    {}
+  );
+
+  info("Create a new script with the displayUrl code.js");
+  const consoleFront = await targetFront.getFront("console");
+  consoleFront.evaluateJSAsync("function f() {\n return 5; \n}\n//# sourceURL=http://example.com/code.js");
+
+  const sourcePacket = await waitForEvent(threadClient, "newSource");
+  equal(sourcePacket.source.url, "http://example.com/code.js");
+
+  info("Evaluate f() and pause at line 2");
+  consoleFront.evaluateJSAsync("f()");
+  const pausedPacket = await waitForPause(threadClient);
+  equal(pausedPacket.why.type, "breakpoint");
+  equal(pausedPacket.frame.where.line, 2);
+}));
--- a/devtools/server/tests/unit/xpcshell.ini
+++ b/devtools/server/tests/unit/xpcshell.ini
@@ -127,16 +127,17 @@ skip-if = true # tests for breakpoint ac
 [test_breakpoint-18.js]
 [test_breakpoint-19.js]
 skip-if = true
 reason = bug 1104838
 [test_breakpoint-20.js]
 [test_breakpoint-21.js]
 [test_breakpoint-22.js]
 skip-if = true # breakpoint sliding is not supported bug 1525685
+[test_breakpoint-23.js]
 [test_conditional_breakpoint-01.js]
 [test_conditional_breakpoint-02.js]
 [test_conditional_breakpoint-03.js]
 [test_logpoint-01.js]
 [test_logpoint-02.js]
 [test_listsources-01.js]
 [test_listsources-02.js]
 [test_listsources-03.js]
--- a/devtools/shared/client/thread-client.js
+++ b/devtools/shared/client/thread-client.js
@@ -1,21 +1,33 @@
 /* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
 /* 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 {arg, DebuggerClient} = require("devtools/shared/client/debugger-client");
+const {
+  arg,
+  DebuggerClient,
+} = require("devtools/shared/client/debugger-client");
 const eventSource = require("devtools/shared/client/event-source");
-const {ThreadStateTypes} = require("devtools/shared/client/constants");
+const { ThreadStateTypes } = require("devtools/shared/client/constants");
 
-loader.lazyRequireGetter(this, "ObjectClient", "devtools/shared/client/object-client");
-loader.lazyRequireGetter(this, "SourceFront", "devtools/shared/fronts/source", true);
+loader.lazyRequireGetter(
+  this,
+  "ObjectClient",
+  "devtools/shared/client/object-client"
+);
+loader.lazyRequireGetter(
+  this,
+  "SourceFront",
+  "devtools/shared/fronts/source",
+  true
+);
 
 /**
  * Creates a thread client for the remote debugging protocol server. This client
  * is a front to the thread actor created in the server side, hiding the
  * protocol details in a traditional JavaScript API.
  *
  * @param client DebuggerClient
  * @param actor string
@@ -45,63 +57,68 @@ ThreadClient.prototype = {
   },
 
   get _transport() {
     return this.client._transport;
   },
 
   _assertPaused: function(command) {
     if (!this.paused) {
-      throw Error(command + " command sent while not paused. Currently " + this._state);
+      throw Error(
+        command + " command sent while not paused. Currently " + this._state
+      );
     }
   },
 
   /**
    * Resume a paused thread. If the optional limit parameter is present, then
    * the thread will also pause when that limit is reached.
    *
    * @param [optional] object limit
    *        An object with a type property set to the appropriate limit (next,
    *        step, or finish) per the remote debugging protocol specification.
    *        Use null to specify no limit.
    * @param bool aRewind
    *        Whether execution should rewind until the limit is reached, rather
    *        than proceeding forwards. This parameter has no effect if the
    *        server does not support rewinding.
    */
-  _doResume: DebuggerClient.requester({
-    type: "resume",
-    resumeLimit: arg(0),
-    rewind: arg(1),
-  }, {
-    before: function(packet) {
-      this._assertPaused("resume");
-
-      // Put the client in a tentative "resuming" state so we can prevent
-      // further requests that should only be sent in the paused state.
-      this._previousState = this._state;
-      this._state = "resuming";
-
-      return packet;
+  _doResume: DebuggerClient.requester(
+    {
+      type: "resume",
+      resumeLimit: arg(0),
+      rewind: arg(1),
     },
-    after: function(response) {
-      if (response.error && this._state == "resuming") {
-        // There was an error resuming, update the state to the new one
-        // reported by the server, if given (only on wrongState), otherwise
-        // reset back to the previous state.
-        if (response.state) {
-          this._state = ThreadStateTypes[response.state];
-        } else {
-          this._state = this._previousState;
+    {
+      before: function(packet) {
+        this._assertPaused("resume");
+
+        // Put the client in a tentative "resuming" state so we can prevent
+        // further requests that should only be sent in the paused state.
+        this._previousState = this._state;
+        this._state = "resuming";
+
+        return packet;
+      },
+      after: function(response) {
+        if (response.error && this._state == "resuming") {
+          // There was an error resuming, update the state to the new one
+          // reported by the server, if given (only on wrongState), otherwise
+          // reset back to the previous state.
+          if (response.state) {
+            this._state = ThreadStateTypes[response.state];
+          } else {
+            this._state = this._previousState;
+          }
         }
-      }
-      delete this._previousState;
-      return response;
-    },
-  }),
+        delete this._previousState;
+        return response;
+      },
+    }
+  ),
 
   /**
    * Reconfigure the thread actor.
    *
    * @param object options
    *        A dictionary object of the new options to use in the thread actor.
    */
   reconfigure: DebuggerClient.requester({
@@ -209,24 +226,27 @@ ThreadClient.prototype = {
     type: "pauseOnExceptions",
     pauseOnExceptions: arg(0),
     ignoreCaughtExceptions: arg(1),
   }),
 
   /**
    * Detach from the thread actor.
    */
-  detach: DebuggerClient.requester({
-    type: "detach",
-  }, {
-    after: function(response) {
-      this.client.unregisterClient(this);
-      return response;
+  detach: DebuggerClient.requester(
+    {
+      type: "detach",
     },
-  }),
+    {
+      after: function(response) {
+        this.client.unregisterClient(this);
+        return response;
+      },
+    }
+  ),
 
   /**
    * Promote multiple pause-lifetime object actors to thread-lifetime ones.
    *
    * @param array actors
    *        An array with actor IDs to promote.
    */
   threadGrips: DebuggerClient.requester({