Closed Bug 771655 Opened 12 years ago Closed 12 years ago

Debugger does not show up if any progress listener (e.g. NoScript) reads the WebProgress argument's DOMWindow property in onStateChange()

Categories

(DevTools :: Debugger, defect, P2)

15 Branch
x86
All
defect

Tracking

(Not tracked)

RESOLVED FIXED
Firefox 19

People

(Reporter: gaby2300, Assigned: past)

Details

(Whiteboard: [testday-20120706])

Attachments

(1 file, 4 obsolete files)

Steps to reproduce:

1. Open Aurora in a profile with NoScript installed.
2. Go to Aurora>Web Developer>Debugger or press Ctrl+Shift+S.
3. Notice a white flash in the lower part of the window but no debugger showing up.
4. Open the Addons Manager.
5. Disable or remove NoScript.
6. Go to Aurora>Web Developer>Debugger or press Ctrl+Shift+S.
7. The debugger shows up.

The expected would be the debugger showing up no matter what addon is installed.

Windows 7 and Mozilla/5.0 (Windows NT 6.1; rv:15.0) Gecko/20120706 Firefox/15.0a2
Severity: normal → critical
OS: Windows 7 → All
Whiteboard: [testday-20120706]
I don't know why NoScript does this, but it's apparently blocking the debugger's fetching of the scripts in the page, and forcibly closes the UI. CC'ing the author.
Contrived test case to be executed in the browser chrome context, e.g. via Scratchpad (shift+F4) with "Browser" as the Environment:

<SNIPPET>

if ("_testPL" in window)
  Cc['@mozilla.org/docloaderservice;1'].getService(Ci.nsIWebProgress)
    .removeProgressListener(_testPL);

window._testPL = {
  START_DOC: Ci.nsIWebProgressListener.STATE_START | Ci.nsIWebProgressListener.STATE_IS_DOCUMENT,
  onStateChange: function(wp, req, stateFlags, status) {
    // if (/^data:/.test(req.name)) return;
    if ((stateFlags & this.START_DOC) === this.START_DOC) {
      wp.DOMWindow;
    }
  },
  QueryInterface: function(iid) {
    if (iid.equals(Ci.nsISupportsWeakReference) || 
        iid.equals(Ci.nsIWebProgressListener))
      return this;
    throw Cr.NS_ERROR_NO_INTERFACE;
  }
}

Cc['@mozilla.org/docloaderservice;1'].getService(Ci.nsIWebProgress)
  .addProgressListener(_testPL, Ci.nsIWebProgress.NOTIFY_STATE_REQUEST);

</SNIPPET>

After installing this progress listener, which just attempts to read the DOMWindow property from the first argument of onStateChange() when a document loads, the debugger doesn't show up. Notice that no exception is thrown when the property is read (it correctly evaluates to a ChromeWindow).

NoScript 2.4.7 and below happened to have a progress listener which triggers this bug (worked around in 2.4.8), and we can't exclude other extensions do as well.
Summary: Debugger does not show up with NoScript installed → Debugger does not show up if any progress listener (e.g. NoScript) reads the WebProgress argument's DOMWindow property in onStateChange()
Assignee: nobody → past
Status: NEW → ASSIGNED
Priority: -- → P2
I can't say if it's because of a progress listener, but I am on Firefox 15 and when I try to open the debugger using the Tools menu (or keyboard shortcut), it shows up blank at the bottom of the screen for less than a second.
The debugger doesn't show up (well it opens and immediately closes) if Roboform is installed.  I don't know if that's caused by this issue or not though since Roboform obfuscates its code.
Roboform!
(In reply to Rob Campbell [:rc] (:robcee) from comment #5)
> Roboform!

I've contacted Roboform support and pointed them towards this bug and they can confirm they are triggering this bug by reading DOMWindow property on a onStateChange to catch Basic Auth requests.  They don't believe there's any other way to do so so they can't work around the bug.
Attached patch Patch v1 (obsolete) — Splinter Review
So the problem is that something fires an unload event on the debugger iframe and that causes the frontend to shut down. I am avoiding this in this patch by returning early from the unload handler, but I haven't really figured out what triggers the unload event in the first place.
Attached patch Patch v2 (obsolete) — Splinter Review
This is a better fix for ignoring spurious unload events before the debugger has finished initializing. I still don't have a theory to explain why touching the DOMWindow from an nsIWebProgressListener triggers an unload event in the debugger iframe.
Attachment #669627 - Attachment is obsolete: true
Attachment #669908 - Flags: review?(rcampbell)
Comment on attachment 669908 [details] [diff] [review]
Patch v2

   _startupDebugger: function DC__startupDebugger() {
     if (this._isInitialized) {
       return;
     }
     this._isInitialized = true;
     window.removeEventListener("DOMContentLoaded", this._startupDebugger, true);
+    this._isLoaded = false;
+    window.addEventListener("Debugger:Loaded", this._onInitFinished, false);

I would love to see a unittest that can duplicate this condition. I'm a little worried about additional raciness adding two stages of load listeners. It's conceivable that these could fire pretty close together. Might be better putting the Debugger:Loaded listener before the DOMContentLoaded listener to ensure it doesn't get missed.

+   * initializing, so that _shutdowDebugger can ignore spurious unload events.

_shutdownDebugger - typo.
Attached patch Patch v3 (obsolete) — Splinter Review
Added test and made all suggested changes.

(In reply to Rob Campbell [:rc] (:robcee) from comment #9)
> I would love to see a unittest that can duplicate this condition. I'm a
> little worried about additional raciness adding two stages of load
> listeners. It's conceivable that these could fire pretty close together.
> Might be better putting the Debugger:Loaded listener before the
> DOMContentLoaded listener to ensure it doesn't get missed.

I did that even though I don't see how this could possibly happen, given that the second event is fired by the handler of the first one, effectively serializing the sequence. Nevertheless, better safe than sorry.

Try run: https://tbpl.mozilla.org/?tree=Try&rev=3d06e53d68f1
Attachment #669908 - Attachment is obsolete: true
Attachment #669908 - Flags: review?(rcampbell)
Attachment #672748 - Flags: review?(rcampbell)
Comment on attachment 672748 [details] [diff] [review]
Patch v3

Review of attachment 672748 [details] [diff] [review]:
-----------------------------------------------------------------

this likely needs to be rebased. Canceling review.
Attachment #672748 - Flags: review?(rcampbell)
Attached patch Patch v4 (obsolete) — Splinter Review
Rebased.
Attachment #672748 - Attachment is obsolete: true
Attachment #677000 - Flags: review?(rcampbell)
Comment on attachment 677000 [details] [diff] [review]
Patch v4

asking victor to take a pass through this.
Attachment #677000 - Flags: review?(vporof)
Attached patch v5Splinter Review
As suspected, the extra listeners weren't necessary anymore. I stripped out them and kept the test to be safe.
Attachment #677000 - Attachment is obsolete: true
Attachment #677000 - Flags: review?(vporof)
Attachment #677000 - Flags: review?(rcampbell)
Attachment #677022 - Flags: review+
https://hg.mozilla.org/integration/fx-team/rev/aeb34ce13c59
Whiteboard: [testday-20120706] → [testday-20120706][fixed-in-fx-team]
https://hg.mozilla.org/mozilla-central/rev/aeb34ce13c59
Status: ASSIGNED → RESOLVED
Closed: 12 years ago
Flags: in-testsuite+
Resolution: --- → FIXED
Whiteboard: [testday-20120706][fixed-in-fx-team] → [testday-20120706]
Target Milestone: --- → Firefox 19
Product: Firefox → DevTools
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: