Closed
Bug 1416296
Opened 7 years ago
Closed 7 years ago
Leak of the world when the crashtest from bug 1415021 has dom.webcomponents.enabled=true.
Categories
(Core :: DOM: Core & HTML, enhancement, P2)
Core
DOM: Core & HTML
Tracking
()
RESOLVED
FIXED
mozilla60
Tracking | Status | |
---|---|---|
firefox60 | --- | fixed |
People
(Reporter: emilio, Assigned: smaug)
References
Details
Attachments
(1 file)
(deleted),
text/html
|
Details |
Reporter | ||
Comment 1•7 years ago
|
||
https://hg.mozilla.org/integration/mozilla-inbound/rev/91a4c7a72f31
Should get reverted.
Given the messages from the log:
WARNING: YOU ARE LEAKING THE WORLD (at least one JSRuntime and everything alive inside it, that is) AT JS_ShutDown TIME. FIX THIS!
###!!! ASSERTION: Component Manager being held past XPCOM shutdown.: 'cnt == 0', file /builds/worker/workspace/build/src/xpcom/build/XPCOMInit.cpp, line 1026
This is likely not a layout bug, but a DOM bug. Andrew, any chance you can find anybody to own this?
Flags: needinfo?(overholt)
Comment 2•7 years ago
|
||
(Adding dependency on bug 1415021, since that's where we landed the crashtest that's causing trouble here.)
Direct link to the testcase: https://bug1415021.bmoattachments.org/attachment.cgi?id=8925763
The crashtest does a bunch of different things in sequence (because it's fuzzer-generated), but AFAIK the key part for webcomponents usage is:
> try { o16 = document.createElement('area') } catch(e) { }
> try { o14 = document.createElement('body') } catch(e) { }
> try { o17 = o14.createShadowRoot() } catch(e) { }
> try { try { o17.appendChild(o16) } catch(e) { document.documentElement.appendChild(o16) } } catch(e) { }
We create a "body" element, and then call createShadowRoot to it, and then try to append an 'area' to that shadow-root. (And then try to append the area to our <html> element if that fails -- but it probably doesn't fail, I'd guess.)
I'll bet the rest of the testcase is unnecessary for the purposes of triggering this leak, and this ^^ is the key piece that triggers problematic leaky behavior.
Depends on: 1415021
Reporter | ||
Comment 3•7 years ago
|
||
(In reply to Daniel Holbert [:dholbert] from comment #2)
> > try { o16 = document.createElement('area') } catch(e) { }
> > try { o14 = document.createElement('body') } catch(e) { }
> > try { o17 = o14.createShadowRoot() } catch(e) { }
> > try { try { o17.appendChild(o16) } catch(e) { document.documentElement.appendChild(o16) } } catch(e) { }
>
> We create a "body" element, and then call createShadowRoot to it, and then
> try to append an 'area' to that shadow-root. (And then try to append the
> area to our <html> element if that fails -- but it probably doesn't fail,
> I'd guess.)
>
> I'll bet the rest of the testcase is unnecessary for the purposes of
> triggering this leak, and this ^^ is the key piece that triggers problematic
> leaky behavior.
Well, there may be other bit which may or may not make a difference, which is the body getting inserted into the document:
> try { document.documentElement.appendChild(o14) } catch(e) { }
But yeah, I agree that the leak is probably reducible :)
Comment 4•7 years ago
|
||
createShadowRoot isn't what we're implementing. Can we change the test?
Flags: needinfo?(overholt)
Priority: -- → P2
Reporter | ||
Comment 5•7 years ago
|
||
(In reply to Andrew Overholt [:overholt] from comment #4)
> createShadowRoot isn't what we're implementing. Can we change the test?
I mean, sure, it should work the same way with attachShadow({ mode: "open" }), so not a big deal in that regard.
Comment 6•7 years ago
|
||
Yes, it's reproducible with attachShadow `attachShadow({ mode: "open" })` too.
And I found that if I replace the following line:
> try { o15.content.append(document.documentElement, "") } catch(e) { }
with this:
> try { o15.content.append(document.documentElement) } catch(e) { }
the leak is gone.
The difference is: if you append more than one node at a time, a DocumentFragment is created to handle this, the nodes to append are moved to this DocumentFragment [1]. However, the above line will fail later due to "HierarchyRequestError".
I tried to append to another element, which also causes "HierarchyRequestError", e.g.
> try { o1.append(document.documentElement, "") } catch(e) { }
and the leak is gone too.
So, I have no idea so far :(
[1] https://searchfox.org/mozilla-central/rev/fe75164c55321e011d9d13b6d05c1e00d0a640be/dom/base/nsINode.cpp#1722-1732
Reporter | ||
Comment 7•7 years ago
|
||
(In reply to Jessica Jong [:jessica] from comment #6)
> I tried to append to another element, which also causes
> "HierarchyRequestError", e.g.
>
> > try { o1.append(document.documentElement, "") } catch(e) { }
>
> and the leak is gone too.
> So, I have no idea so far :(
So, that's a pretty neat observation, I think, actually.
o15 is a template element, and that has a document fragment that doesn't look cycle collected:
https://searchfox.org/mozilla-central/rev/bab833ebeef6b2202e71f81d225b968283521fd6/dom/html/HTMLTemplateElement.h#42
That probably should be cycle collected and the leak should go away, I would think...
But if this leaks it is because we insert incorrectly in the first place, and there are a couple of checks that look particularly fishy. In particular, we allow any document fragment to get inserted into an element[1], even if they contain an element with a shadow root. Looks to me that we can't really do that early-out, since we check for shadow roots and template elements in [2].
[1]: https://searchfox.org/mozilla-central/rev/bab833ebeef6b2202e71f81d225b968283521fd6/dom/base/nsINode.cpp#2075
[2]: https://searchfox.org/mozilla-central/rev/bab833ebeef6b2202e71f81d225b968283521fd6/dom/base/nsINode.cpp#1978
Comment 8•7 years ago
|
||
(In reply to Emilio Cobos Álvarez [:emilio] from comment #7)
> So, that's a pretty neat observation, I think, actually.
>
> o15 is a template element, and that has a document fragment that doesn't
> look cycle collected:
>
>
> https://searchfox.org/mozilla-central/rev/
> bab833ebeef6b2202e71f81d225b968283521fd6/dom/html/HTMLTemplateElement.h#42
>
> That probably should be cycle collected and the leak should go away, I would
> think...
I think the HTMLTemplateContent does cycle collect its `content` here:
https://searchfox.org/mozilla-central/rev/a662f122c37704456457a526af90db4e3c0fd10e/dom/html/HTMLTemplateElement.cpp#46-57
or is anything wrong here?
>
> But if this leaks it is because we insert incorrectly in the first place,
> and there are a couple of checks that look particularly fishy. In
> particular, we allow any document fragment to get inserted into an
> element[1], even if they contain an element with a shadow root. Looks to me
> that we can't really do that early-out, since we check for shadow roots and
> template elements in [2].
>
> [1]:
> https://searchfox.org/mozilla-central/rev/
> bab833ebeef6b2202e71f81d225b968283521fd6/dom/base/nsINode.cpp#2075
> [2]:
> https://searchfox.org/mozilla-central/rev/
> bab833ebeef6b2202e71f81d225b968283521fd6/dom/base/nsINode.cpp#1978
Actually, when doing:
> try { o15.content.append(document.documentElement, "") } catch(e) { }
or
> try { o1.append(document.documentElement, "") } catch(e) { }
the elements are not really appended to either o15.content or o1, since the code early returns here:
https://searchfox.org/mozilla-central/rev/a662f122c37704456457a526af90db4e3c0fd10e/dom/base/nsINode.cpp#2217
so I'm not sure why their outcome differs.
In summary, the 2 conditions causing the leak are:
- o15.content.append(document.documentElement, "")
- o17 = o14.attachShadow({ mode: "open" })
It looks like the shadow host is causing the elements not to be released. So, I looked at the part where we attach shadow, and found that if we remove the `!GetShadowRoot()` check and force to use `OwnerDoc()` instead of `document` in `Element::UnbindFromTree`:
https://searchfox.org/mozilla-central/rev/a662f122c37704456457a526af90db4e3c0fd10e/dom/base/Element.cpp#2067-2079
the leak is gone!
But I still can't explain why `o1.append(document.documentElement, "")` has no such problem...
Reporter | ||
Comment 9•7 years ago
|
||
(In reply to Jessica Jong [:jessica] from comment #8)
> (In reply to Emilio Cobos Álvarez [:emilio] from comment #7)
> > So, that's a pretty neat observation, I think, actually.
> >
> > o15 is a template element, and that has a document fragment that doesn't
> > look cycle collected:
> >
> >
> > https://searchfox.org/mozilla-central/rev/
> > bab833ebeef6b2202e71f81d225b968283521fd6/dom/html/HTMLTemplateElement.h#42
> >
> > That probably should be cycle collected and the leak should go away, I would
> > think...
>
> I think the HTMLTemplateContent does cycle collect its `content` here:
>
> https://searchfox.org/mozilla-central/rev/
> a662f122c37704456457a526af90db4e3c0fd10e/dom/html/HTMLTemplateElement.cpp#46-
> 57
>
> or is anything wrong here?
Err, your 110% right, I'll never learn to look at the right place for the cycle collection macros.
> > try { o15.content.append(document.documentElement, "") } catch(e) { }
> or
> > try { o1.append(document.documentElement, "") } catch(e) { }
>
> the elements are not really appended to either o15.content or o1, since the
> code early returns here:
>
> https://searchfox.org/mozilla-central/rev/
> a662f122c37704456457a526af90db4e3c0fd10e/dom/base/nsINode.cpp#2217
Hmm... So do we really reject appending the fragment, I guess... I'm about to debug it a bit more closely, but if I'm not wrong:
* aNewChild is a document fragment containing document.documentElement and an empty textnode.
* aParent is the template's doc fragment.
So we go through the ContentIsHostIncludingDescendantOf, and it fails...
> It looks like the shadow host is causing the elements not to be released.
> So, I looked at the part where we attach shadow, and found that if we remove
> the `!GetShadowRoot()` check and force to use `OwnerDoc()` instead of
> `document` in `Element::UnbindFromTree`:
>
> https://searchfox.org/mozilla-central/rev/
> a662f122c37704456457a526af90db4e3c0fd10e/dom/base/Element.cpp#2067-2079
>
> the leak is gone!
>
> But I still can't explain why `o1.append(document.documentElement, "")` has
> no such problem...
Yeah... I'm investigating a bit more now. But we really don't want to do that. This is the kind of thing why using XBL for shadow dom gets annoying :(
See also bug 1217531, which may be a duplicate of this bug actually.
Comment 10•7 years ago
|
||
(In reply to Emilio Cobos Álvarez [:emilio] from comment #9)
>
> Hmm... So do we really reject appending the fragment, I guess... I'm about
> to debug it a bit more closely, but if I'm not wrong:
>
> * aNewChild is a document fragment containing document.documentElement and
> an empty textnode.
> * aParent is the template's doc fragment.
>
> So we go through the ContentIsHostIncludingDescendantOf, and it fails...
Exactly, and that's the same for `o15.content.append` or `o1.append`.
>
> > It looks like the shadow host is causing the elements not to be released.
> > So, I looked at the part where we attach shadow, and found that if we remove
> > the `!GetShadowRoot()` check and force to use `OwnerDoc()` instead of
> > `document` in `Element::UnbindFromTree`:
> >
> > https://searchfox.org/mozilla-central/rev/
> > a662f122c37704456457a526af90db4e3c0fd10e/dom/base/Element.cpp#2067-2079
> >
> > the leak is gone!
> >
> > But I still can't explain why `o1.append(document.documentElement, "")` has
> > no such problem...
>
> Yeah... I'm investigating a bit more now. But we really don't want to do
> that. This is the kind of thing why using XBL for shadow dom gets annoying :(
>
> See also bug 1217531, which may be a duplicate of this bug actually.
Yeah, looks like the same problem...
Assignee | ||
Comment 11•7 years ago
|
||
So is there a minimal testcase for the leak?
Reporter | ||
Comment 12•7 years ago
|
||
Here's a naive reduced test-case from the crashtest.
Assignee: nobody → emilio
Reporter | ||
Comment 13•7 years ago
|
||
err... didn't plan to take it, at least not just yet.
Assignee: emilio → nobody
Reporter | ||
Updated•7 years ago
|
Attachment #8928623 -
Attachment mime type: text/plain → text/html
Assignee | ||
Updated•7 years ago
|
Assignee: nobody → bugs
Comment 14•7 years ago
|
||
Pushed by ecoal95@gmail.com:
https://hg.mozilla.org/integration/autoland/rev/53072cbdc184
Enable shadow DOM in the crashtest now that it doesn't leak the XBL stuff. r=me
Comment 15•7 years ago
|
||
bugherder |
Status: NEW → RESOLVED
Closed: 7 years ago
status-firefox60:
--- → fixed
Resolution: --- → FIXED
Target Milestone: --- → mozilla60
You need to log in
before you can comment on or make changes to this bug.
Description
•