Last Comment Bug 634150 - Infinite loop with increasing memory involving E4X and object.__proto__
: Infinite loop with increasing memory involving E4X and object.__proto__
Status: RESOLVED WONTFIX
:
Product: Core
Classification: Components
Component: JavaScript Engine (show other bugs)
: 1.9.2 Branch
: All All
: -- normal (vote)
: ---
Assigned To: general
:
Mentors:
: 636428 (view as bug list)
Depends on:
Blocks:
  Show dependency treegraph
 
Reported: 2011-02-14 17:36 PST by John J. Barton
Modified: 2011-02-24 11:02 PST (History)
7 users (show)
See Also:
Crash Signature:
(edit)
QA Whiteboard:
Iteration: ---
Points: ---
Has Regression Range: ---
Has STR: ---


Attachments

Description John J. Barton 2011-02-14 17:36:43 PST
I stumbled upon a way to hang Firefox 3.6 with Firebug 1.7a10.

Notes for me:
Open the test console and run the script/EX4 test case. 
It will time out.
Run it again. 
The tab will open and not make progress.
Close both test tabs.
Run the test a third time.

Their are probably other ways.

Here is where Boris comes in, I tracked down the problem to this code:

function instanceOf(object, Klass)
{
    while (object != null)
    {
        FBTrace.sysout("reps instanceOf ("+object+","+Klass+")");
        if (object == Klass.prototype)
           return true;
        object = object.__proto__;
    }
    return false;
}

We call this function only one place:
var found = (win && instanceOf(object,win.Error)) || (object instanceof ErrorCopy);

Where win is a content window.

In our FBTrace console we get lots of stuff then:

----
FTS0: reps instanceOf (<one>
  <two>hi</two>
</one>,function Error() {
    [native code]
}) 
FTS0: reps instanceOf (,function Error() {
    [native code]
}) 
FTS0: reps instanceOf (,function Error() {
    [native code]
}) 
FTS0: reps instanceOf (,function Error() {
    [native code]
}) 
...forever...
--------------

So it seems like the EX4 object has an __proto__ that is self referencing.

Obviously our code is not good here. It seems to me that any object can have a bad value for __proto__ and hose us. 

Boris can you suggest a better solution?  Note that this code is essentially on
https://developer.mozilla.org/en/Core_JavaScript_1.5_Guide/Details_of_the_Object_Model#Determining_Instance_Relationships
Comment 1 John J. Barton 2011-02-14 17:46:09 PST
I added two lines

function instanceOf(object, Klass)
{
    while (object != null)
    {
        FBTrace.sysout("reps instanceOf ("+object+","+Klass+")");
        if (object == Klass.prototype)
           return true;
        if ( !(object+"") ) // workaround bug https://bugzilla.mozilla.org/show_bug.cgi?id=634150
            return false;
        object = object.__proto__;
    }
    return false;
}

and the loop is broken. (I don't know if I also broke the function). 

And BTW our E4X test case passes now ;-)
Comment 2 Steve Roussey (:sroussey) 2011-02-14 18:58:32 PST
I put this in since instanceof doesn't work with wrappers in Firefox 3.6. I walked Andreas through this when studying and fixing equality issues with wrappers, so it is fixed in 4.0. Thus, Firebug 1.8 can remove it.

In the meantime, if all the Firebug tests pass, then your changes are OK, since there is an FBTest that covers this.
Comment 3 Boris Zbarsky [:bz] 2011-02-14 19:40:01 PST
> So it seems like the EX4 object has an __proto__ that is self referencing.

More precisely, _any_ property on that object is self-referencing.  Gotta love E4X.

I believe this can't happen with other objects.... though if script can define getters for __proto__ maybe it can.

For Gecko 2.0 you can use Object.getPrototypeOf, right?  For 1.9.2... I'm not sure.  Moving to the right component for this stuff.
Comment 4 Brendan Eich [:brendan] 2011-02-14 22:07:42 PST
Use Object.getPrototypeOf.

You're not hitting a __proto__ cycle, rather, you're extracting an empty XMLList from an empty list, and so on, up to the non-empty XML object

<one>
  <two>hi</two>
</one>

from which you extracted the first empty list, for the non-existent child named __proto__.

/be
Comment 5 Boris Zbarsky [:bz] 2011-02-14 23:07:35 PST
> Use Object.getPrototypeOf.

That doesn't help on the 3.6 end, right?  Is there a non-hacky solution for that, or just to not worry about it?
Comment 6 Brendan Eich [:brendan] 2011-02-15 07:37:25 PST
(In reply to comment #5)
> > Use Object.getPrototypeOf.
> 
> That doesn't help on the 3.6 end, right?  Is there a non-hacky solution for
> that, or just to not worry about it?

if (typeof object == "xml") return false

/be
Comment 7 Brendan Eich [:brendan] 2011-02-15 07:51:04 PST
function instanceOf(object, Klass)
{
    while (object != null)
    {
        FBTrace.sysout("reps instanceOf ("+object+","+Klass+")");
        if (object == Klass.prototype)
           return true;
        if (typeof object == 'xml')
           return Klass.prototype == XML.prototype;
        object = object.__proto__;
    }
    return false;
}

This relies on our implementation joining XML.prototype and XMLList.prototype.

/be
Comment 8 Brendan Eich [:brendan] 2011-02-24 11:00:52 PST
*** Bug 636428 has been marked as a duplicate of this bug. ***

Note You need to log in before you can comment on or make changes to this bug.