Closed Bug 883649 Opened 6 years ago Closed 6 years ago

Console freezes when accessing a DeadObject's property

Categories

(DevTools :: Console, defect)

23 Branch
defect
Not set

Tracking

(firefox22 unaffected, firefox23 ?, firefox24 ?)

RESOLVED FIXED
Firefox 24
Tracking Status
firefox22 --- unaffected
firefox23 --- ?
firefox24 --- ?

People

(Reporter: obrufau, Assigned: msucan)

References

Details

(Keywords: regression, Whiteboard: [fixed-in-fx-team])

Attachments

(1 file)

User Agent: Mozilla/5.0 (Windows NT 5.1; rv:24.0) Gecko/20130615 Firefox/24.0 (Nightly/Aurora)
Build ID: 20130615031212

Steps to reproduce:

Open a new tab (to avoid pop-up blocker)
Open the console
Enter the following to the console:
> var win = window.open('about:blank','blank');
  < undefined
> win.close()
  < undefined
> win
  < [object DeadObject]
> win.freezeConsole // Or win.whatever


Actual results:

The console becomes frozen: `win.freezeConsole` doesn't return anything, and if you enter something else (like `window`) it doesn't work neither.


Expected results:

It shouldn't freeze. Instead, I guess that it should throw "TypeError: can't access dead object", like it does on Firefox Stable 21.

I don't know if it's related, but on FF 21 `win` becomes `undefined` instead of `[object DeadObject]`.
Regression range:
good=2013-04-16
bad=2013-04-17
http://hg.mozilla.org/mozilla-central/pushloghtml?fromchange=1d9c510b3742&tochange=50ab959f4bd1

Maybe bug 851231 is the culprit.
Status: UNCONFIRMED → NEW
Component: Untriaged → Developer Tools: Console
Ever confirmed: true
Version: 24 Branch → 23 Branch
In local build
Last Good: 8c8c9b98d6c1
First Bad: 70caf37070d3

Regressed by:
70caf37070d3	Nick Fitzgerald — Bug 772119 - expose source mapped sources over the remote debugging protocol; r=past
I cannot reproduce this bug with the latest Firefox nightly.
(In reply to Mihai Sucan [:msucan] from comment #3)
> I cannot reproduce this bug with the latest Firefox nightly.

I'm still able to repro it. What's your OS? Mine is Win 7.
I'm on Ubuntu 12.04. What do you use: the web console or the browser console? I tried the STR with the web console.
I can reproduce in following latest Nightly on ubunto12.04.
http://hg.mozilla.org/mozilla-central/rev/4e5983de6e3b
Mozilla/5.0 (X11; Linux i686; rv:24.0) Gecko/20130618 Firefox/24.0 ID:20130618031335

It happens with Web Console (Ctrl+Shift+K).
(In reply to obrufau from comment #0)
> Expected results:
> 
> It shouldn't freeze. Instead, I guess that it should throw "TypeError: can't
> access dead object", like it does on Firefox Stable 21.
> 
> I don't know if it's related, but on FF 21 `win` becomes `undefined` instead
> of `[object DeadObject]`.
Not sure dead objects are part of any standard. It must be an internal thing and I worry about this type of information leaking into something web developers can see.
Needinfo'ing Kyle Huey (as I believe he introduced this idea of dead objects) to get his opinion (or to find someone else if he isn't the right person to ask)
Flags: needinfo?(khuey)
(In reply to David Bruant from comment #7)
> (In reply to obrufau from comment #0)
> > Expected results:
> > 
> > It shouldn't freeze. Instead, I guess that it should throw "TypeError: can't
> > access dead object", like it does on Firefox Stable 21.
> > 
> > I don't know if it's related, but on FF 21 `win` becomes `undefined` instead
> > of `[object DeadObject]`.
> Not sure dead objects are part of any standard. It must be an internal thing
> and I worry about this type of information leaking into something web
> developers can see.

DeadObjects are not part of any standard.  They're an internal implementation detail of a memory saving technique that should only be visible to chrome code.

You'll notice that if you do this with google.com or something loaded in the tab you don't see a DeadObject.  But the new tab page runs with chrome privileges so ...

Anyways the DeadObject behavior here is correct, afaict.  Sounds like the console code needs to deal with the exception somehow.
Flags: needinfo?(khuey)
Thank you Kyle for the info. That helped me understand the problem and to find a way to reproduce the bug. Will look into fixing it.
Assignee: nobody → mihai.sucan
Status: NEW → ASSIGNED
OS: Windows XP → All
Hardware: x86 → All
Attached patch proposed patchSplinter Review
DeadObjects are cross-compartment wrappers that point to objects which have been destroyed. This can only happen with a privileged web console or browser console instance when you hold a reference to some object that comes from a different compartment.

I tried to use Cu.isDeadWrapper(obj) but that did not return true, which meant I had to use try-catches for the important parts.
Attachment #765497 - Flags: review?(past)
Depends on: 878186
Comment on attachment 765497 [details] [diff] [review]
proposed patch

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

It's sad that isDeadWrapper doesn't work as expected in this case. I was wondering whether the Debugger API does some wrapping of its own that confuses isDeadWrapper, but none of the following was identified as a dead wrapper:

- obj (the Debugger.Object)
- obj.unsafeDereference()
- obj.unwrap()
- obj.unwrap().unsafeDereference()

This is fine as a fix for now, but I think that we should file a followup for isDeadWrapper to take this case into consideration, and adopt it when it gets fixed.

::: toolkit/devtools/server/actors/script.js
@@ +1664,5 @@
> +      // The above can throw if this.obj points to a dead object.
> +      return { from: this.actorID,
> +               prototype: this.threadActor.createValueGrip(null),
> +               ownProperties: ownProperties,
> +               safeGetterValues: Object.create(null) };

Ignorable nit: an empty object literal would be fine in this case, if you don't want to be pedantic :-)
Attachment #765497 - Flags: review?(past) → review+
jimb or bholley should know if Cu.isDeadWrapper needs fixing in a followup.
Panos, thanks for the review.

More testing:

Execute the following code in the browser console:

  gBrowser.selectedTab = gBrowser.addTab("about:blank");
  foobarz = content.document;
  gBrowser.removeCurrentTab();
  foobarz;
  Cu.isDeadWrapper(foobarz);

Please do so, line by line.

You will see [object DeadObject] and isDeadWrapper() returns |true|. If you change onPropertiesAndPrototype() in the ObjectActor to check if |obj| isDeadWrapper() you always get |false|. I tried with XPCNativeWrapper.unwrap(this.obj.unsafeDereference()). No luck. However if I try dump() for that object, I do get the "dead object" exception, so the object I have is certainly dead at that point in execution, yet isDeadWrapper() it's not.

Do we get some kind of cross-compartment wrapper that is always live? Is this why isDeadWrapper() returns false? It seems to return true only if it is executed in the compartment that holds the dead object reference.
Once a wrapper is nuked, it ceases to become a wrapper at all. This means that passing the nuked wrapper across compartment boundaries will end up with a CCW to a DeadObjectProxy, rather than another DeadObjectProxy.

If it would be helpful, we could make Cu.IsDeadWrapper unwrap CCWs, so if would give the right answer here. If it would, please file a bug and CC me.
It would help us to avoid using try-catches around our code if we can just check if the objects we work with are dead or not. In what component should we file the bug? Thanks!
XPConnect.
Yesterday I filed bug 885800.
Landed: https://hg.mozilla.org/integration/fx-team/rev/8174f98e2cdc
Whiteboard: [fixed-in-fx-team]
https://hg.mozilla.org/mozilla-central/rev/8174f98e2cdc
Status: ASSIGNED → RESOLVED
Closed: 6 years ago
Resolution: --- → FIXED
Target Milestone: --- → Firefox 24
Product: Firefox → DevTools
You need to log in before you can comment on or make changes to this bug.