Closed Bug 882106 Opened 11 years ago Closed 3 years ago

Crash [@ js::DestroyContext(JSContext * cx, js::DestroyContextMode mode) ] when removing node from mutation observer

Categories

(Core :: JavaScript Engine, defect)

x86
Windows 7
defect
Not set
critical

Tracking

()

RESOLVED WORKSFORME

People

(Reporter: Gijs, Unassigned)

References

Details

(Keywords: crash, Whiteboard: qa-not-actionable)

Crash Data

Attachments

(2 files)

Attached file Crash stack
I can reproduce this reliably, but I've not managed to get a simple .html testcase so far, unfortunately... Happy to get more data insofar as this report doesn't yet have it, though.

Scenario: I'm removing the add-on bar and replacing it with a widget that has its own mutation observer and essentially moves nodes that are added to it elsewhere.

The Add-on SDK has widgets that contain iframes, and it sets the src attribute for this after it adds them to the node which it's just put in the add-on bar:

http://hg.mozilla.org/mozilla-central/annotate/9ca690835a5e/addon-sdk/source/lib/sdk/widget.js#l581
http://hg.mozilla.org/mozilla-central/annotate/9ca690835a5e/addon-sdk/source/lib/sdk/widget.js#l736
http://hg.mozilla.org/mozilla-central/annotate/9ca690835a5e/addon-sdk/source/lib/sdk/widget.js#l769
http://mxr.mozilla.org/mozilla-central/source/addon-sdk/source/lib/sdk/content/symbiont.js#106

AFAICT, all this code runs, and when the iframe stops loading about:blank in order to load the URL passed in setAttribute("src", "resource://..."), the code then also fires the mutation observer. 

For the load stop, this is the JS stack, according to DumpJSStack():

0 _initFrame() ["resource://gre/modules/XPIProvider.jsm -> jar:file:///C:/Users/gkruitbosch/AppData/Roaming/Mozilla/Firefox/Profiles/eoave6mv.ux/extensions/memchaser@quality.mozilla.org.xpi!/bootstrap.js -> resource://memchaser-at-quality-dot-mozilla-dot-org/addon-sdk/lib/toolkit/loader.js -> resource://memchaser-at-quality-dot-mozilla-dot-org/addon-sdk/lib/sdk/content/symbiont.js":110]
    this = [object Symbiont]
1 Symbiont() ["resource://gre/modules/XPIProvider.jsm -> jar:file:///C:/Users/gkruitbosch/AppData/Roaming/Mozilla/Firefox/Profiles/eoave6mv.ux/extensions/memchaser@quality.mozilla.org.xpi!/bootstrap.js -> resource://memchaser-at-quality-dot-mozilla-dot-org/addon-sdk/lib/toolkit/loader.js -> resource://memchaser-at-quality-dot-mozilla-dot-org/addon-sdk/lib/sdk/content/symbiont.js":62]
    this = [object Symbiont]
2 Trait(self = undefined, arguments = undefined) ["resource://gre/modules/XPIProvider.jsm -> jar:file:///C:/Users/gkruitbosch/AppData/Roaming/Mozilla/Firefox/Profiles/eoave6mv.ux/extensions/memchaser@quality.mozilla.org.xpi!/bootstrap.js -> resource://memchaser-at-quality-dot-mozilla-dot-org/addon-sdk/lib/toolkit/loader.js -> resource://memchaser-at-quality-dot-mozilla-dot-org/addon-sdk/lib/sdk/deprecated/traits.js":114]
    self = undefined
    arguments = undefined
    <failed to get 'this' value>
3 WC_setContent() ["resource://gre/modules/XPIProvider.jsm -> jar:file:///C:/Users/gkruitbosch/AppData/Roaming/Mozilla/Firefox/Profiles/eoave6mv.ux/extensions/memchaser@quality.mozilla.org.xpi!/bootstrap.js -> resource://memchaser-at-quality-dot-mozilla-dot-org/addon-sdk/lib/toolkit/loader.js -> resource://memchaser-at-quality-dot-mozilla-dot-org/addon-sdk/lib/sdk/widget.js":818]
    this = [object Object]
4 WC_fill() ["resource://gre/modules/XPIProvider.jsm -> jar:file:///C:/Users/gkruitbosch/AppData/Roaming/Mozilla/Firefox/Profiles/eoave6mv.ux/extensions/memchaser@quality.mozilla.org.xpi!/bootstrap.js -> resource://memchaser-at-quality-dot-mozilla-dot-org/addon-sdk/lib/toolkit/loader.js -> resour<void>

(the line numbers seem to be slightly off here... and I can't figure out how to tell VS2012/xpconnect not to cut off the stack) :-( )

Then the current load seems to be stopped, we initiate a new one, and somewhere after that fire mutation observers.

This removes the node, and that then blows up, with the top of the stack looking like:

 	mozjs.dll!js::DestroyContext(JSContext * cx, js::DestroyContextMode mode) Line 341	C++
 	mozjs.dll!JS_DestroyContextNoGC(JSContext * cx) Line 1294	C++
>	xul.dll!nsXPConnect::ReleaseJSContext(JSContext * aJSContext, bool noGC) Line 1579	C++
 	xul.dll!nsFrameScriptExecutor::DestroyCx() Line 953	C++
 	xul.dll!nsInProcessTabChildGlobal::DelayedDisconnect() Line 254	C++
 	xul.dll!nsRunnableMethodImpl<void (__thiscall mozilla::dom::quota::QuotaManager::*)(void),1>::Run() Line 351	C++
 	xul.dll!nsContentUtils::RemoveScriptBlocker() Line 4805	C++
 	xul.dll!nsDocument::EndUpdate(unsigned int aUpdateType) Line 4394	C++
 	xul.dll!mozilla::dom::XULDocument::EndUpdate(unsigned int aUpdateType) Line 3365	C++
 	xul.dll!mozAutoDocUpdate::~mozAutoDocUpdate() Line 40	C++
 	xul.dll!nsINode::ReplaceOrInsertBefore(bool aReplace, nsINode * aNewChild, nsINode * aRefChild, mozilla::ErrorResult & aError) Line 1732	C++
 	xul.dll!nsINode::InsertBefore(nsINode & aNode, nsINode * aChild, mozilla::ErrorResult & aError) Line 1543	C++
 	xul.dll!nsINode::AppendChild(nsINode & aNode, mozilla::ErrorResult & aError) Line 1547	C++
 	xul.dll!mozilla::dom::NodeBinding::appendChild(JSContext * cx, JS::Handle<JSObject *> obj, nsINode * self, const JSJitMethodCallArgs & args) Line 579	C++
 	xul.dll!mozilla::dom::NodeBinding::genericMethod(JSContext * cx, unsigned int argc, JS::Value * vp) Line 1333	C++
 	mozjs.dll!js::CallJSNative(JSContext * cx, int (JSContext *, unsigned int, JS::Value *) * native, const JS::CallArgs & args) Line 349	C++
 	mozjs.dll!js::Invoke(JSContext * cx, JS::CallArgs args, js::MaybeConstruct construct) Line 389	C++
 	mozjs.dll!js::Interpret(JSContext * cx, js::StackFrame * entryFrame, js::InterpMode interpMode, bool useNewType) Line 2211	C++
 	mozjs.dll!js::RunScript(JSContext * cx, js::StackFrame * fp) Line 346	C++
 	mozjs.dll!js::Invoke(JSContext * cx, JS::CallArgs args, js::MaybeConstruct construct) Line 402	C++
 	mozjs.dll!js::CallOrConstructBoundFunction(JSContext * cx, unsigned int argc, JS::Value * vp) Line 1159	C++
 	mozjs.dll!js::CallJSNative(JSContext * cx, int (JSContext *, unsigned int, JS::Value *) * native, const JS::CallArgs & args) Line 349	C++
 	mozjs.dll!js::Invoke(JSContext * cx, JS::CallArgs args, js::MaybeConstruct construct) Line 389	C++
 	mozjs.dll!js::Invoke(JSContext * cx, const JS::Value & thisv, const JS::Value & fval, unsigned int argc, JS::Value * argv, JS::Value * rval) Line 435	C++
 	mozjs.dll!JS_CallFunctionValue(JSContext * cx, JSObject * objArg, JS::Value fval, unsigned int argc, JS::Value * argv, JS::Value * rval) Line 5885	C++
 	xul.dll!mozilla::dom::MutationCallback::Call(JSContext * cx, JS::Handle<JSObject *> aThisObj, const mozilla::dom::Sequence<mozilla::dom::OwningNonNull<nsDOMMutationRecord> > & mutations, nsDOMMutationObserver & observer, mozilla::ErrorResult & aRv) Line 412	C++
 	xul.dll!mozilla::dom::MutationCallback::Call<nsDOMMutationObserver *>(nsDOMMutationObserver * const & thisObj, const mozilla::dom::Sequence<mozilla::dom::OwningNonNull<nsDOMMutationRecord> > & mutations, nsDOMMutationObserver & observer, mozilla::ErrorResult & aRv, mozilla::dom::CallbackObject::ExceptionHandling aExceptionHandling) Line 149	C++
 	xul.dll!nsDOMMutationObserver::HandleMutation() Line 575	C++
 	xul.dll!nsDOMMutationObserver::HandleMutationsInternal() Line 614	C++
 	xul.dll!nsDOMMutationObserver::HandleMutations() Line 389	C++
 	xul.dll!nsContentUtils::LeaveMicroTask() Line 4842	C++
 	xul.dll!nsAutoMicroTask::~nsAutoMicroTask() Line 2309	C++
 	xul.dll!nsEventListenerManager::HandleEventSubType(nsListenerStruct * aListenerStruct, const mozilla::dom::CallbackObjectHolder<mozilla::dom::EventListener,nsIDOMEventListener> & aListener, nsIDOMEvent * aDOMEvent, mozilla::dom::EventTarget * aCurrentTarget, nsCxPusher * aPusher) Line 941	C++
 	xul.dll!nsEventListenerManager::HandleEventInternal(nsPresContext * aPresContext, nsEvent * aEvent, nsIDOMEvent * * aDOMEvent, mozilla::dom::EventTarget * aCurrentTarget, nsEventStatus * aEventStatus, nsCxPusher * aPusher) Line 1009	C++
 	xul.dll!nsEventListenerManager::HandleEvent(nsPresContext * aPresContext, nsEvent * aEvent, nsIDOMEvent * * aDOMEvent, mozilla::dom::EventTarget * aCurrentTarget, nsEventStatus * aEventStatus, nsCxPusher * aPusher) Line 329	C++
 	xul.dll!nsEventTargetChainItem::HandleEvent(nsEventChainPostVisitor & aVisitor, bool aMayHaveNewListenerManagers, nsCxPusher * aPusher) Line 204	C++
 	xul.dll!nsEventTargetChainItem::HandleEventTargetChain(nsEventChainPostVisitor & aVisitor, nsDispatchingCallback * aCallback, bool aMayHaveNewListenerManagers, nsCxPusher * aPusher) Line 331	C++
 	xul.dll!nsEventDispatcher::Dispatch(nsISupports * aTarget, nsPresContext * aPresContext, nsEvent * aEvent, nsIDOMEvent * aDOMEvent, nsEventStatus * aEventStatus, nsDispatchingCallback * aCallback, nsCOMArray<mozilla::dom::EventTarget> * aTargets) Line 635	C++
 	xul.dll!nsEventDispatcher::DispatchDOMEvent(nsISupports * aTarget, nsEvent * aEvent, nsIDOMEvent * aDOMEvent, nsPresContext * aPresContext, nsEventStatus * aEventStatus) Line 693	C++
 	xul.dll!nsWindowRoot::DispatchDOMEvent(nsEvent * aEvent, nsIDOMEvent * aDOMEvent, nsPresContext * aPresContext, nsEventStatus * aEventStatus) Line 94	C++
 	xul.dll!nsContentUtils::DispatchChromeEvent(nsIDocument * aDoc, nsISupports * aTarget, const nsAString_internal & aEventName, bool aCanBubble, bool aCancelable, bool * aDefaultAction) Line 3387	C++
 	xul.dll!nsGlobalWindow::DispatchDOMWindowCreated() Line 2611	C++
 	xul.dll!nsRunnableMethodImpl<void (__thiscall mozilla::dom::quota::QuotaManager::*)(void),1>::Run() Line 351	C++
 	xul.dll!nsContentUtils::RemoveScriptBlocker() Line 4805	C++
 	xul.dll!nsAutoScriptBlocker::~nsAutoScriptBlocker() Line 2279	C++
 	xul.dll!nsDocumentViewer::InitInternal(nsIWidget * aParentWidget, nsISupports * aState, const nsIntRect & aBounds, bool aDoCreation, bool aNeedMakeCX, bool aForceSetNewDocument) Line 950	C++
 	xul.dll!nsDocumentViewer::Init(nsIWidget * aParentWidget, const nsIntRect & aBounds) Line 684	C++
 	xul.dll!nsDocShell::SetupNewViewer(nsIContentViewer * aNewViewer) Line 8264	C++
 	xul.dll!nsDocShell::Embed(nsIContentViewer * aContentViewer, const char * aCommand, nsISupports * aExtraInfo) Line 6271	C++
 	xul.dll!nsDocShell::CreateAboutBlankContentViewer(nsIPrincipal * aPrincipal, nsIURI * aBaseURI, bool aTryToSaveOldPresentation) Line 7050	C++
 	xul.dll!nsDocShell::EnsureContentViewer() Line 6931	C++
 	xul.dll!nsDocShell::GetInterface(const nsID & aIID, void * * aSink) Line 948	C++
 	xul.dll!nsGetInterface::operator()(const nsID & aIID, void * * aInstancePtr) Line 19	C++
 	xul.dll!nsCOMPtr_base::assign_from_helper(const nsCOMPtr_helper & helper, const nsID & iid) Line 110	C++
 	xul.dll!nsCOMPtr<nsIDOMDocument>::nsCOMPtr<nsIDOMDocument>(const nsCOMPtr_helper & helper) Line 659	C++
 	xul.dll!nsDocLoader::DocLoaderIsEmpty(bool aFlushLayout) Line 694	C++
 	xul.dll!nsDocLoader::OnStopRequest(nsIRequest * aRequest, nsISupports * aCtxt, tag_nsresult aStatus) Line 642	C++
 	xul.dll!nsLoadGroup::RemoveRequest(nsIRequest * request, nsISupports * ctxt, tag_nsresult aStatus) Line 684	C++
 	xul.dll!nsLoadGroup::Cancel(tag_nsresult status) Line 289	C++
 	xul.dll!nsDocLoader::Stop() Line 268	C++
 	xul.dll!nsDocShell::Stop() Line 194	C++
 	xul.dll!nsDocShell::Stop(unsigned int aStopFlags) Line 4666	C++
 	xul.dll!nsDocShell::InternalLoad(nsIURI * aURI, nsIURI * aReferrer, nsISupports * aOwner, unsigned int aFlags, const wchar_t * aWindowTarget, const char * aTypeHint, const nsAString_internal & aFileName, nsIInputStream * aPostData, nsIInputStream * aHeadersData, unsigned int aLoadType, nsISHEntry * aSHEntry, bool aFirstParty, nsIDocShell * * aDocShell, nsIRequest * * aRequest) Line 9209	C++
 	xul.dll!nsDocShell::LoadURI(nsIURI * aURI, nsIDocShellLoadInfo * aLoadInfo, unsigned int aLoadFlags, bool aFirstParty) Line 1527	C++
 	xul.dll!nsFrameLoader::ReallyStartLoadingInternal() Line 493	C++
 	xul.dll!nsFrameLoader::ReallyStartLoading() Line 398	C++
 	xul.dll!nsDocument::MaybeInitializeFinalizeFrameLoaders() Line 6260	C++
 	xul.dll!nsRunnableMethodImpl<void (__thiscall mozilla::dom::quota::QuotaManager::*)(void),1>::Run() Line 351	C++
 	xul.dll!nsContentUtils::RemoveScriptBlocker() Line 4805	C++
 	xul.dll!nsAutoScriptBlocker::~nsAutoScriptBlocker() Line 2279	C++
 	xul.dll!mozilla::dom::Element::SetAttr(int aNamespaceID, nsIAtom * aName, nsIAtom * aPrefix, const nsAString_internal & aValue, bool aNotify) Line 1728	C++
 	xul.dll!nsGenericHTMLElement::SetAttr(int aNameSpaceID, nsIAtom * aName, const nsAString_internal & aValue, bool aNotify) Line 345	C++
 	xul.dll!mozilla::dom::Element::SetAttribute(const nsAString_internal & aName, const nsAString_internal & aValue, mozilla::ErrorResult & aError) Line 750	C++
 	xul.dll!mozilla::dom::ElementBinding::setAttribute(JSContext * cx, JS::Handle<JSObject *> obj, mozilla::dom::Element * self, const JSJitMethodCallArgs & args) Line 255	C++
 	xul.dll!mozilla::dom::ElementBinding::genericMethod(JSContext * cx, unsigned int argc, JS::Value * vp) Line 1980	C++
 	mozjs.dll!js::CallJSNative(JSContext * cx, int (JSContext *, unsigned int, JS::Value *) * native, const JS::CallArgs & args) Line 349	C++
 	mozjs.dll!js::Invoke(JSContext * cx, JS::CallArgs args, js::MaybeConstruct construct) Line 389	C++
 	mozjs.dll!js::Invoke(JSContext * cx, const JS::Value & thisv, const JS::Value & fval, unsigned int argc, JS::Value * argv, JS::Value * rval) Line 435	C++


Obviously in an ideal situation this should not crash. However, I'm really unsure what the cause of the issue is here and/or where to look further. I'll rebase my patches on m-c (currently they're against the UX branch), fold them and attach the result, and attach a full stack for the crash in case that's helpful. Installing the memchaser SDK add-on, qpushing the patch and rebuild browser/base, browser/components, browser/themes, browser/locales should be enough to trigger this crash on startup.
Crash Signature: [@ js::DestroyContext(JSContext * cx, js::DestroyContextMode mode) ]
Summary: Crash [@ jsContext::DestroyContext(JSContext*, js::DestoryContextMode) ] when removing node from mutation observer → Crash [@ js::DestroyContext(JSContext * cx, js::DestroyContextMode mode) ] when removing node from mutation observer
Attached patch Testcase patchSplinter Review
Sadly this bitrots reasonably regularly because of how often people touch browser.css stuff... but anyway, this is an uptodate patch with which I can reproduce the crash with an m-c build and memchaser: https://addons.mozilla.org/En-us/firefox/addon/memchaser/ .
Blocks: 868377
Severity: normal → critical
Crash Signature: [@ js::DestroyContext(JSContext * cx, js::DestroyContextMode mode) ] → [@ js::DestroyContext(JSContext*, js::DestroyContextMode) ]
This crash happens because a context is being destroyed that has an outstanding request.  This either means that somebody forgot to balance an add request with a drop request or whatever they are called (see bug 865915), or because we're executing something on a JSContext without addreffing the context.  For the latter problem, the way to find it is basically to examine the entire stack for places where we start executing script, and see if they are doing an AutoRequest or whatever the right method is right now for holding onto a JSContext.
This is because the current mechanism used by the message manager to decide when to destroy its jscontext is wrong. I have patches to fix this in bug 865745, but smaug wants me to do bug 880917 first. That bug is almost finished, so this should probably be all landed before the end of the week.
Blocks: 865745
Er, this.
No longer blocks: 865745
Depends on: 865745
Assignee: general → nobody
Crash Signature: [@ js::DestroyContext(JSContext*, js::DestroyContextMode) ] → [@ js::DestroyContext(JSContext*, js::DestroyContextMode) ] [@ js::DestroyContext ]
Whiteboard: qa-not-actionable

Crashes on recent versions look different than the stack in comment 0, and comment 4 says this was expected to have been fixed by some patches that landed a long time ago.

Status: NEW → RESOLVED
Closed: 3 years ago
Resolution: --- → WORKSFORME
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: