Bug 981258 - Set the breakpoints in browser_dbg_breakpoints-break-on-last-line-of-script-on-reload.js before executng the IIFE so that the IIFE's Debugger.Script can't be GC'd before the breakpoints are set; r=past
authorNick Fitzgerald <fitzgen@gmail.com>
Sat, 15 Mar 2014 18:48:55 -0700
changeset 192046 f02f3bd008d4dc1b538ef3d1c9b857060c846a62
parent 192045 a6195a333647cb85ec41437ecdab9f64d328f47c
child 192047 f785999a6144a0886c7f39d8598f68e7e6d82163
push id474
push userasasaki@mozilla.com
push dateMon, 02 Jun 2014 21:01:02 +0000
treeherdermozilla-release@967f4cf1b31c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerspast
bugs981258
milestone30.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
Bug 981258 - Set the breakpoints in browser_dbg_breakpoints-break-on-last-line-of-script-on-reload.js before executng the IIFE so that the IIFE's Debugger.Script can't be GC'd before the breakpoints are set; r=past
browser/devtools/debugger/test/browser_dbg_breakpoints-break-on-last-line-of-script-on-reload.js
browser/devtools/debugger/test/code_breakpoints-break-on-last-line-of-script-on-reload.js
toolkit/devtools/server/actors/script.js
--- a/browser/devtools/debugger/test/browser_dbg_breakpoints-break-on-last-line-of-script-on-reload.js
+++ b/browser/devtools/debugger/test/browser_dbg_breakpoints-break-on-last-line-of-script-on-reload.js
@@ -18,49 +18,62 @@ function test() {
     gPanel = aPanel;
     gDebugger = gPanel.panelWin;
     gThreadClient = gDebugger.gThreadClient;
     gEvents = gDebugger.EVENTS;
 
     Task.spawn(function* () {
       try {
 
-        yield ensureSourceIs(gPanel, CODE_URL, true);
+        // Refresh and hit the debugger statement before the location we want to
+        // set our breakpoints. We have to pause before the breakpoint locations
+        // so that GC doesn't get a chance to kick in and collect the IIFE's
+        // script, which would causes us to receive a 'noScript' error from the
+        // server when we try to set the breakpoints.
+        const [paused, ] = yield promise.all([
+          waitForThreadEvents(gPanel, "paused"),
+          reloadActiveTab(gPanel, gEvents.SOURCE_SHOWN),
+        ]);
 
-        // Pause and set our breakpoints.
-        yield doInterrupt();
+        is(paused.why.type, "debuggerStatement");
+
+        // Set our breakpoints.
         const [bp1, bp2, bp3] = yield promise.all([
           setBreakpoint({
             url: CODE_URL,
-            line: 2
-          }),
-          setBreakpoint({
-            url: CODE_URL,
             line: 3
           }),
           setBreakpoint({
             url: CODE_URL,
             line: 4
+          }),
+          setBreakpoint({
+            url: CODE_URL,
+            line: 5
           })
         ]);
 
-        // Should hit the first breakpoint on reload.
+        // Refresh and hit the debugger statement again.
         yield promise.all([
           reloadActiveTab(gPanel, gEvents.SOURCE_SHOWN),
-          waitForCaretUpdated(gPanel, 2)
+          waitForCaretAndScopes(gPanel, 1)
         ]);
 
-        // And should hit the other breakpoints as we resume.
+        // And we should hit the breakpoints as we resume.
         yield promise.all([
           doResume(),
-          waitForCaretUpdated(gPanel, 3)
+          waitForCaretAndScopes(gPanel, 3)
         ]);
         yield promise.all([
           doResume(),
-          waitForCaretUpdated(gPanel, 4)
+          waitForCaretAndScopes(gPanel, 4)
+        ]);
+        yield promise.all([
+          doResume(),
+          waitForCaretAndScopes(gPanel, 5)
         ]);
 
         // Clean up the breakpoints.
         yield promise.all([
           rdpInvoke(bp1, bp1.remove),
           rdpInvoke(bp2, bp1.remove),
           rdpInvoke(bp3, bp1.remove),
         ]);
--- a/browser/devtools/debugger/test/code_breakpoints-break-on-last-line-of-script-on-reload.js
+++ b/browser/devtools/debugger/test/code_breakpoints-break-on-last-line-of-script-on-reload.js
@@ -1,5 +1,6 @@
+debugger;
 var a = (function(){
   var b = 9;
   console.log("x", b);
   return b;
 })();
--- a/toolkit/devtools/server/actors/script.js
+++ b/toolkit/devtools/server/actors/script.js
@@ -1357,17 +1357,23 @@ ThreadActor.prototype = {
           line: originalLine,
           column: originalColumn } = aRequest.location;
 
     let locationPromise = this.sources.getGeneratedLocation(aRequest.location);
     return locationPromise.then(({url, line, column}) => {
       if (line == null ||
           line < 0 ||
           this.dbg.findScripts({ url: url }).length == 0) {
-        return { error: "noScript" };
+        return {
+          error: "noScript",
+          message: "Requested setting a breakpoint on "
+            + url + ":" + line
+            + (column != null ? ":" + column : "")
+            + " but there is no Debugger.Script at that location"
+        };
       }
 
       let response = this._createAndStoreBreakpoint({
         url: url,
         line: line,
         column: column
       });
       // If the original location of our generated location is different from
@@ -1445,16 +1451,20 @@ ThreadActor.prototype = {
       this.threadLifetimePool.addActor(actor);
     }
 
     // Find all scripts matching the given location
     let scripts = this.dbg.findScripts(aLocation);
     if (scripts.length == 0) {
       return {
         error: "noScript",
+        message: "Requested setting a breakpoint on "
+          + aLocation.url + ":" + aLocation.line
+          + (aLocation.column != null ? ":" + aLocation.column : "")
+          + " but there is no Debugger.Script at that location",
         actor: actor.actorID
       };
     }
 
    /**
     * For each script, if the given line has at least one entry point, set a
     * breakpoint on the bytecode offets for each of them.
     */