Closed Bug 75140 Opened 24 years ago Closed 7 years ago

Evil looking assertion in xpconnect

Categories

(Core :: XPConnect, defect)

x86
All
defect
Not set
normal

Tracking

()

RESOLVED INVALID
Future

People

(Reporter: slogan, Unassigned)

Details

Tripped on this again tonight. The assertion is something along the lines of no component found in scope. Here is the stack: NTDLL! 77f7629c() nsDebug::Assertion(const char * 0x03c5bc84, const char * 0x03c5bc80, const char * 0x03c5bc34, int 202) line 286 + 13 bytes nsXPCWrappedNativeScope::FindInJSObjectScope(XPCContext * 0x04e90bc0, JSObject * 0x00eadc40) line 202 + 35 bytes XPCConvert::NativeInterface2JSObject(JSContext * 0x04e9c110, nsIXPConnectJSObjectHolder * * 0x0012e188, nsISupports * 0x05bc5ce0, const nsID * 0x07c24b80, JSObject * 0x00ffe6f8, unsigned int * 0x00000000) line 886 + 36 bytes XPCConvert::NativeData2JS(JSContext * 0x04e9c110, long * 0x0012e528, const void * 0x0012e620, const nsXPTType & {...}, const nsID * 0x07c24b80, JSObject * 0x00ffe6f8, unsigned int * 0x00000000) line 405 + 49 bytes nsXPCWrappedJSClass::CallMethod(nsXPCWrappedJSClass * const 0x05bcee90, nsXPCWrappedJS * 0x07c8c700, unsigned short 4, const nsXPTMethodInfo * 0x00d7eaa4, nsXPTCMiniVariant * 0x0012e620) line 746 + 37 bytes nsXPCWrappedJS::CallMethod(nsXPCWrappedJS * const 0x07c8c700, unsigned short 4, const nsXPTMethodInfo * 0x00d7eaa4, nsXPTCMiniVariant * 0x0012e620) line 432 PrepareAndDispatch(nsXPTCStubBase * 0x07c8c700, unsigned int 4, unsigned int * 0x0012e6d0, unsigned int * 0x0012e6c0) line 100 + 31 bytes SharedStub() line 124 InMemoryDataSource::Unassert(InMemoryDataSource * const 0x05bc5ce0, nsIRDFResource * 0x05bc38c0, nsIRDFResource * 0x05bc3800, nsIRDFNode * 0x05bc46a0) line 1296
###!!! ASSERTION: No 'Components' in scope!: '0', file E:\projects\raptor\mozill a\js\src\xpconnect\src\xpcwrappednativescope.cpp, line 202 ###!!! Break: at file E:\projects\raptor\mozilla\js\src\xpconnect\src\xpcwrapped nativescope.cpp, line 202
Also see bug 54461 and bug 71173. I don't know if they're still valid though.
I dunno what's going on here, nor really why it's assigned to me. jband: any thoughts? Fixed by the xpcdom-branch silver bullet?
I have yet to see an instance of a botch of this assertion that did not uncover a problem in code elsewhere. Here's the deal... When you make a call from C++ to a method of a wrapped JSObject and you pass an interface pointer as a parameter then xpconnect needs to build a wrapper (or find an existing wrapper) for the parameter. Wrappers are always associated with an xpcscope which parents them to some particular JS global object; i.e. the window. In order to find the appropriate xpcscope for the new wrapper xpconnect looks for the xpcscope of the wrapper on which we are making the method call. It does this by walking the wrapper's JSObject's parent chain until it gets to the global object and then does a JS lookup for the global's 'Components' property. That Components object is an xpconnect wrapped native that is one-to-one with the JS global object and contains a pointer to the xpcscope that we are looking for. The assert botches when the wrapper's global object does not *have* a 'Components' property. Since that property is attached as permanant/readonly, this can only happen if that global object's properties have been cleared by a call to JS_ClearScope. Our window code does this when unloading a document - either before loading another document or closing the window. Now, the very fact that there exists a wrapper - rooted by virtue of the fact that it is reachable from native code - whose JSObject's parent chain terminates in such a global object will prevent that global object from being garbage collected. Often this can be entraining *tons* of stuff. It is generally bad to be holding a reference to such a wrapper. So, the question really is *why* are we making a call from native code into this particular wrapped JS at this time? I have seen cases where we had inadvertantly failed to unregister a listener in the document onunload. This caused the window to be leaked. This assert brought that to our attention. What is going on here? The stack inlined above is only partial. Also note that wrapped JSObjects now support nsISupportsWeakReference (if the JSObject itself allows it). So it is possible to use weak references to the wrapped JSObject in listener cases and avoid the leaking (and this assert). To answer shaver's question: Yes, this scheme is changed on the xpcdom branch. In this newer code we have a faster path from the global object to the xpcscope. So, the JS lookup of 'Components' is unnecessary. For better or worse, this assert is no more. People will need other tools to discover potentially broken usage patterns.
Should shaver still own this? I think not. /be
You don't say what higher-level code triggers this, syd, and I'm swayed by jband's painfully-gained experience here, so I'm giving you back the bug. You might want to reassign it to whoever owns the code that causes script to execute in a cleared scope.
Assignee: shaver → syd
Target Milestone: --- → M1
Target Milestone: M1 → Future
QA Contact: pschwartau → xpconnect
(In reply to comment #6) > You don't say what higher-level code triggers this, syd, and I'm swayed by > jband's painfully-gained experience here, so I'm giving you back the bug. syd is gone
Assignee: slogan → nobody
This is no longer relevant.
Status: NEW → RESOLVED
Closed: 7 years ago
Resolution: --- → INVALID
You need to log in before you can comment on or make changes to this bug.