Closed Bug 292027 Opened 20 years ago Closed 20 years ago

code to release nsISupportsWeakReference wrapped JS objects crashes when GC repeats

Categories

(Core :: XPConnect, defect, P1)

defect

Tracking

()

RESOLVED FIXED
mozilla1.8beta2

People

(Reporter: dbaron, Assigned: dbaron)

References

Details

(Whiteboard: [patch])

Attachments

(1 file)

The code to handling nsXPCWrappedJS objects that implement nsISupportsWeakReference can crash when js_GC does more than one pass of garbage collection. I'm running into this crash with my patch to bug 241518. The problem is the following: XPCJSRuntime::GCCallback deals with self->mWrappedJSToReleaseArray in two places, a JSGC_MARK_END callback and a JSGC_END callback. In the first, it calls JS_IsAboutToBeFinalized on the JS object for each wrapper that could be finalized. In the second, it releases those wrappers. This all works fine if js_GC doesn't "goto repeat". However, when it does, JSGC_MARK_END can be called multiple times before JSGC_END is called. When the second call happens, the objects for which JS_IsAboutToBeFinalized was true have *already* been finalized, but the nsXPCWrappedJS has a dangling mJSObj pointer, so we crash calling JS_IsAboutToBeFinalized on a JSObject that was already finalized: js_IsAboutToBeFinalized JS_IsAboutToBeFinalized (/builds/trunk/mozilla/js/src/jsapi.c:1796) WrappedJSDyingJSObjectFinder (/builds/trunk/mozilla/js/src/xpconnect/src/xpcjsruntime.cpp:92) JS_DHashTableEnumerate (/builds/trunk/mozilla/js/src/jsdhash.c:619) JSObject2WrappedJSMap::Enumerate(JSDHashOperator (*)(JSDHashTable*, JSDHashEntryHdr*, unsigned int, void*), void*) (/builds/trunk/mozilla/js/src/xpconnect/src/xpcmaps.h:156) XPCJSRuntime::GCCallback(JSContext*, JSGCStatus) (/builds/trunk/mozilla/js/src/xpconnect/src/xpcjsruntime.cpp:290) DOMGCCallback (/builds/trunk/mozilla/dom/src/base/nsJSEnvironment.cpp:2107) js_GC (/builds/trunk/mozilla/js/src/jsgc.c:1780)
So, after looking back at bug 66950, JSGC_FINALIZE_END didn't exist back then, so the choice to use JSGC_END rather than JSGC_FINALIZE_END may not have been as intentional as it seemed from looking at the current code. It actually almost seems better to me to do the releases in the JSGC_FINALIZE_END callback -- the destruction of the wrapped JS and the call to ClearWeakReferences are probably better off happening sooner than later, and shouldn't be able to cause any cascading destructors, and the removal from the JSObject2WrappedJS map is what would fix this bug. The only issue seems to me to be potential cascading destructors from releasing mOuter (and maybe mClass). Perhaps they could use XPCJSRuntime::DeferredRelease while GC is running (via a boolean we note on the runtime using the GC callback)?
Severity: normal → critical
Status: NEW → ASSIGNED
Priority: -- → P1
Whiteboard: [patch]
Target Milestone: --- → mozilla1.8beta2
Attachment #182006 - Flags: review?(dbradley) → review?(jst)
Attachment #182006 - Flags: review?(jst) → review+
Comment on attachment 182006 [details] [diff] [review] patch sr+a=me, thanks for the in-person explanation -- a trip down cvs-annotate memory lane! /be
Attachment #182006 - Flags: superreview?(brendan)
Attachment #182006 - Flags: superreview+
Attachment #182006 - Flags: approval1.8b3+
Fix checked in to trunk, 2005-06-14 17:21/23 -0700.
Status: ASSIGNED → RESOLVED
Closed: 20 years ago
Resolution: --- → FIXED
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: