Closed
Bug 1217531
Opened 9 years ago
Closed 6 years ago
Leak with createShadowRoot, adoptNode
Categories
(Core :: DOM: Core & HTML, defect, P3)
Core
DOM: Core & HTML
Tracking
()
RESOLVED
WORKSFORME
Tracking | Status | |
---|---|---|
firefox44 | --- | affected |
People
(Reporter: jruderman, Unassigned, Mentored)
References
Details
(Keywords: memory-leak, testcase, Whiteboard: [tw-dom] btpp-active)
Attachments
(7 files, 5 obsolete files)
trace-refcnt reports leaked nsGlobalWindow, nsDocument, etc. (Using a Mac debug build with XPCOM_MEM_LEAK_LOG=2)
Whiteboard: [tw-dom]
Mentor: wchen
Assignee: nobody → shuang
The test case failed at line 13.
TypeError: div.createShadowRoot is not a function
var shadowroot = element.createShadowRoot();
(In reply to Shawn Huang [:shawnjohnjr] from comment #1)
> The test case failed at line 13.
> TypeError: div.createShadowRoot is not a function
>
> var shadowroot = element.createShadowRoot();
oh. I did not know i have to enable dom.webcomponents.enabled flag.
Attachment #8742730 -
Attachment is obsolete: true
Updated•9 years ago
|
Whiteboard: [tw-dom] → [tw-dom] btpp-active
https://bugzilla.mozilla.org/show_bug.cgi?id=957109#c27
I guess this issue is related to this comment.
"IsInDoc() handling of ShadowRoot need to be fixed, but
it isn't clear to me how it should work. Currently it certainly is wrong since
document.createElement("div").createShadowRoot() creates a thing which is in document, although the shadow host isn't in document."
Attachment #8743151 -
Attachment description: bug1217531.patch (WIP) → bug1217531 test
I don't know why running this, the output seems strange.
env XPCOM_MEM_LOG_CLASSES=nsGlobalWindow XPCOM_MEM_REFCNT_LOG=/home/shawnjohnjr/refcnt.txt ./mach mochitest dom/base/test/test_bug1217531.html
Attachment #8742748 -
Attachment is obsolete: true
$ python find_roots.py /tmp/cc-edges.6252.1461153426.log nsGlobalWindow
Parsing /tmp/cc-edges.6252.1461153426.log. Done loading graph.
0x7f6042534800 [nsGlobalWindow # 2147483652 outer http://mochi.test:8888/tests/dom/base/test/test_bug1217531.html]
Root 0x7f6042534800 is a ref counted object with 1 unknown edge(s).
known edges:
0x7f6042535000 [nsGlobalWindow # 2147483653 inner about:blank] --[mOuterWindow]--> 0x7f6042534800
0x7f604165fc00 [nsGlobalWindow # 2147483655 inner http://mochi.test:8888/tests/dom/base/test/test_bug1217531.html] --[mOuterWindow]--> 0x7f6042534800
0x7f60424a4c00 [nsGlobalWindow # 2147483654 inner about:blank] --[mOuterWindow]--> 0x7f6042534800
0x7f604251a7e0 [nsJSContext] --[mGlobalObjectRef]--> 0x7f6042534800
Is it correct to check nsGlobalWindow using find_roots.py for this case?
I followed the instruction[1], and run tools/rb/find_leakers.py, but I can't get the result. The refcnt report seems missing symbols.
[1]https://developer.mozilla.org/en-US/docs/Mozilla/Performance/Refcount_tracing_and_balancing
Flags: needinfo?(wchen)
refcnt.txt looks like:
<nsGlobalWindow> 0x7f48856be800 1 AddRef 1 [thread 0x7f48a699c4a0]
#01: ???[/home/shawnjohnjr/code/mozilla-inbound/obj-x86_64-pc-linux-gnu/dist/bin/libxul.so +0x175a323]
#02: ???[/home/shawnjohnjr/code/mozilla-inbound/obj-x86_64-pc-linux-gnu/dist/bin/libxul.so +0x176f404]
#03: ???[/home/shawnjohnjr/code/mozilla-inbound/obj-x86_64-pc-linux-gnu/dist/bin/libxul.so +0x2e5f9bb]
#04: ???[/home/shawnjohnjr/code/mozilla-inbound/obj-x86_64-pc-linux-gnu/dist/bin/libxul.so +0x2e3f89e]
#05: ???[/home/shawnjohnjr/code/mozilla-inbound/obj-x86_64-pc-linux-gnu/dist/bin/libxul.so +0x2e3faa0]
#06: ???[/home/shawnjohnjr/code/mozilla-inbound/obj-x86_64-pc-linux-gnu/dist/bin/libxul.so +0x2abe7f1]
#07: ???[/home/shawnjohnjr/code/mozilla-inbound/obj-x86_64-pc-linux-gnu/dist/bin/libxul.so +0x2e4c5b4]
#08: ???[/home/shawnjohnjr/code/mozilla-inbound/obj-x86_64-pc-linux-gnu/dist/bin/libxul.so +0x2eba583]
#09: ???[/home/shawnjohnjr/code/mozilla-inbound/obj-x86_64-pc-linux-gnu/dist/bin/libxul.so +0x2ebac88]
#10: ???[/home/shawnjohnjr/code/mozilla-inbound/obj-x86_64-pc-linux-gnu/dist/bin/libxul.so +0x2ebb0ff]
#11: ???[/home/shawnjohnjr/code/mozilla-inbound/obj-x86_64-pc-linux-gnu/dist/bin/libxul.so +0x30c324e]
#12: ???[/home/shawnjohnjr/code/mozilla-inbound/obj-x86_64-pc-linux-gnu/dist/bin/libxul.so +0x3113d97]
#13: ???[/home/shawnjohnjr/code/mozilla-inbound/obj-x86_64-pc-linux-gnu/dist/bin/libxul.so +0x3114468]
#14: XRE_main[/home/shawnjohnjr/code/mozilla-inbound/obj-x86_64-pc-linux-gnu/dist/bin/libxul.so +0x311472e]
#15: ???[/home/shawnjohnjr/code/mozilla-inbound/obj-x86_64-pc-linux-gnu/dist/bin/firefox +0x56f8]
#16: ???[/home/shawnjohnjr/code/mozilla-inbound/obj-x86_64-pc-linux-gnu/dist/bin/firefox +0x4ec5]
#17: __libc_start_main[/lib/x86_64-linux-gnu/libc.so.6 +0x20a40]
#18: _start[/home/shawnjohnjr/code/mozilla-inbound/obj-x86_64-pc-linux-gnu/dist/bin/firefox +0x4fe9]
#19: ??? (???:???)
tools/rb/find_leakers.py ~/refcnt.txt
Traceback (most recent call last):
File "tools/rb/find_leakers.py", line 99, in <module>
main()
File "tools/rb/find_leakers.py", line 93, in main
process_log(log_lines)
File "tools/rb/find_leakers.py", line 46, in process_log
count,) = log_line.strip('\r\n').split(' ')
ValueError: too many values to unpack
Maybe I misunderstood how to use this tool. Now I found something interesting.
find_roots.py /tmp/cc-edges.8152.1461210326.log 0x7fa190953380
Parsing /tmp/cc-edges.8152.1461210326.log. Done loading graph.
0x7fa18fb79400 [nsGlobalWindow # 2147483689 outer http://mochi.test:8888/tests/dom/base/test/test_bug1217531.html]
--[mContext]--> 0x7fa190953380 [nsJSContext]
Root 0x7fa18fb79400 is a ref counted object with 1 unknown edge(s).
known edges:
0x7fa190953380 [nsJSContext] --[mGlobalObjectRef]--> 0x7fa18fb79400
0x7fa1909c7000 [nsGlobalWindow # 2147483692 inner http://mochi.test:8888/tests/dom/base/test/test_bug1217531.html] --[mOuterWindow]--> 0x7fa18fb79400
find_roots.py /tmp/cc-edges.8152.1461210326.log 0x7fa1909c7000
Parsing /tmp/cc-edges.8152.1461210326.log. Done loading graph.
0x7fa198a17000 [nsDocument normal (xhtml) http://mochi.test:8888/tests/dom/base/test/test_bug1217531.html]
--[mScriptGlobalObject]--> 0x7fa1909c7000 [nsGlobalWindow # 2147483692 inner http://mochi.test:8888/tests/dom/base/test/test_bug1217531.html]
Root 0x7fa198a17000 is a ref counted object with 6 unknown edge(s).
known edges:
0x7fa19053a2e0 [JS Object (HTMLDocument)] --[UnwrapDOMObject(obj)]--> 0x7fa198a17000
0x7fa18fb79400 [nsGlobalWindow # 2147483689 outer http://mochi.test:8888/tests/dom/base/test/test_bug1217531.html] --[mDoc]--> 0x7fa198a17000
0x7fa190a9f000 [nsDocument normal (xhtml) http://mochi.test:8888/tests?autorun=1&consoleLevel=INFO&manifestFile=tests.json&dumpOutputDirectory=%2Ftmp] --[mSubDocuments entry->mSubDocument]--> 0x7fa198a17000
0x7fa1927e0b80 [nsXBLDocumentInfo] --[mDocument]--> 0x7fa198a17000
0x7fa18f2600a0 [nsNodeInfoManager] --[mDocument]--> 0x7fa198a17000
0x7fa18efe3160 [AnimationTimeline] --[mDocument]--> 0x7fa198a17000
0x7fa1909c7000 [nsGlobalWindow # 2147483692 inner http://mochi.test:8888/tests/dom/base/test/test_bug1217531.html] --[mDoc]--> 0x7fa198a17000
0x7fa191f3ffb0 [DOMImplementation] --[mOwner]--> 0x7fa198a17000
I listed all ShadowRoot.
> 0x7fa190325b00 ShadowRoot
> 0x7fa190426240 ShadowRoot
> 0x7fa1906c0b20 ShadowRoot
> 0x7fa1925d8e40 ShadowRoot
> 0x7fa19088ad80 ShadowRoot
> 0x7fa193952180 ShadowRoot
find_roots.py /tmp/cc-edges.8152.1461210326.log 0x7fa190325b00
Parsing /tmp/cc-edges.8152.1461210326.log. Done loading graph.
0x7fa190325b00 [JS Object (Function)]
Root 0x7fa190325b00 is a marked GC object.
find_roots.py /tmp/cc-edges.8152.1461210326.log 0x7fa190426240
Parsing /tmp/cc-edges.8152.1461210326.log. Done loading graph.
0x7fa190426240 [JS Object (Function)]
Root 0x7fa190426240 is a marked GC object.
find_roots.py /tmp/cc-edges.8152.1461210326.log 0x7fa1906c0b20
Parsing /tmp/cc-edges.8152.1461210326.log. Done loading graph.
0x7fa1906c0b20 [JS Object (Function)]
Root 0x7fa1906c0b20 is a marked GC object.
python find_roots.py /tmp/cc-edges.8152.1461210326.log 0x7fa1925d8e40
Parsing /tmp/cc-edges.8152.1461210326.log. Done loading graph.
0x7fa18fb41140 [nsNodeInfoManager]
--[mDocument]--> 0x7fa18fb47000 [nsDocument normal (xhtml) http://mochi.test:8888/tests/dom/base/test/test_bug1217531.html]
--[mExpandoAndGeneration.expando]--> 0x7fa191e4b1a0 [JS Object (Object)]
--[global]--> 0x7fa1925d62e0 [JS Object (Window)]
--[ShadowRoot, protoAndIfaceCache[i]]--> 0x7fa1925d8e40 [JS Object (Function)]
Root 0x7fa18fb41140 is a ref counted object with 1 unknown edge(s).
find_roots.py /tmp/cc-edges.8152.1461210326.log 0x7fa19088ad80
Parsing /tmp/cc-edges.8152.1461210326.log. Done loading graph.
0x7fa1922af080 [nsXBLDocumentInfo]
--[mDocument]--> 0x7fa1927c9000 [nsDocument normal (xhtml) http://mochi.test:8888/tests/dom/base/test/test_bug1217531.html]
--[mExpandoAndGeneration.expando]--> 0x7fa1908de400 [JS Object (Object)]
--[global]--> 0x7fa1925d67e0 [JS Object (Window)]
--[ShadowRoot, protoAndIfaceCache[i]]--> 0x7fa19088ad80 [JS Object (Function)]
Root 0x7fa1922af080 is a ref counted object with 1 unknown edge(s).
python find_roots.py /tmp/cc-edges.8152.1461210326.log 0x7fa193952180
Parsing /tmp/cc-edges.8152.1461210326.log. Done loading graph.
0x7fa18f25f200 [nsNodeInfoManager]
--[mDocument]--> 0x7fa195dff000 [nsDocument normal (xhtml) http://mochi.test:8888/tests/dom/base/test/test_bug1217531.html]
--[Preserved wrapper]--> 0x7fa1925e8400 [JS Object (HTMLDocument)]
--[global]--> 0x7fa1925d6560 [JS Object (Window)]
--[ShadowRoot, protoAndIfaceCache[i]]--> 0x7fa193952180 [JS Object (Function)]
Root 0x7fa18f25f200 is a ref counted object with 1 unknown edge(s).
I should minimize memory, so i will upload the log again.
Attachment #8743653 -
Attachment is obsolete: true
Comment 17•9 years ago
|
||
The GC & CC logs got after setting following envs and close the browser when the test finishes:
export MOZ_CC_LOG_DIRECTORY=...
export MOZ_CC_LOG_SHUTDOWN=1
export MOZ_CC_RUN_DURING_SHUTDOWN=1
Now there are something that we're interested:
0x7f6b5fc5e080 [rc=2] FragmentOrElement (xhtml) div (orphan) about:blank
> 0x7f6b5fc4c780 mNodeInfo
> 0x7f6b63a0cba0 mSlots->mXBLBinding
> 0x7f6b6076cf20 mSlots->mShadowRoot
0x7f6b6076cf20 [rc=3] FragmentOrElement ([none]) #document-fragment (orphan) http://mochi.test:8888/tests/dom/base/test/test_bug1217531.html
> 0x7f6b5fc4c600 mNodeInfo
> 0x7f6b6076cf20 mSlots->mContainingShadow
> 0x7f6b5fc5e080 mPoolHost
> 0x7f6b63a0cba0 mAssociatedBinding
Attachment 8743676 [details] was captured from about:memory "save verbose GC & CC logs", not sure why it does not contain the edges above though.
Attachment #8743676 -
Attachment is obsolete: true
clear ni, since i have more information to continue this problem.
Flags: needinfo?(wchen)
Hmm. Maybe I get cc dump before shutdowning so i can't see orphan keyword in the original cc dump.
0x7f0e5cddce50 [rc=2] FragmentOrElement (xhtml) div (orphan) about:blank
python find_roots.py ~/cc-edges-log/cc-edges.22430.log 0x7f0e5cddce50 <<<<FragmentOrElement (xhtml) div (orphan) about:blank>>>>
Parsing /home/shawnjohnjr/cc-edges-log/cc-edges.22430.log. Done loading graph.
0x7f0e5cddce50 [FragmentOrElement (xhtml) div (orphan) about:blank]
Root 0x7f0e5cddce50 is a ref counted object with 1 unknown edge(s).
known edges:
0x7f0e5cd77ad0 [FragmentOrElement ([none]) #document-fragment (orphan) http://mochi.test:8888/tests/dom/base/test/test_bug1217531.html] --[mPoolHost]--> 0x7f0e5cddce50
Checking FragmentOrElement now.
#0 mozilla::dom::FragmentOrElement::SetXBLBinding (this=0x7f40b2ff0350, aBinding=0x0, aOldBindingManager=0x7f40bdb6ace0)
at /home/shawnjohnjr/code/mozilla-inbound/dom/base/FragmentOrElement.cpp:1017
#1 0x00007f40e55bdb01 in nsBindingManager::RemovedFromDocumentInternal (this=0x7f40bdb6ace0, aContent=aContent@entry=0x7f40b2ff0350, aOldDocument=aOldDocument@entry=
0x7f40b95f8000, aDestructorHandling=aDestructorHandling@entry=nsBindingManager::eRunDtor) at /home/shawnjohnjr/code/mozilla-inbound/dom/xbl/nsBindingManager.cpp:216
#2 0x00007f40e46645be in nsBindingManager::RemovedFromDocument (aDestructorHandling=nsBindingManager::eRunDtor, aOldDocument=0x7f40b95f8000, aContent=0x7f40b2ff0350,
this=<optimized out>) at /home/shawnjohnjr/code/mozilla-inbound/dom/xbl/nsBindingManager.h:74
#3 mozilla::dom::FragmentOrElement::DestroyContent (this=0x7f40b2ff0350) at /home/shawnjohnjr/code/mozilla-inbound/dom/base/FragmentOrElement.cpp:1187
#4 0x00007f40e46645ff in mozilla::dom::FragmentOrElement::DestroyContent (this=0x7f40b96d8b00) at /home/shawnjohnjr/code/mozilla-inbound/dom/base/FragmentOrElement.cpp:1193
#5 0x00007f40e46e3edb in nsDocument::Destroy (this=0x7f40b95f8000) at /home/shawnjohnjr/code/mozilla-inbound/dom/base/nsDocument.cpp:8929
#6 0x00007f40e5963999 in nsDocumentViewer::Destroy (this=0x7f40b95fb1a0) at /home/shawnjohnjr/code/mozilla-inbound/layout/base/nsDocumentViewer.cpp:1641
#7 0x00007f40e5cd6ba0 in nsDocShell::Destroy (this=0x7f40b9656800) at /home/shawnjohnjr/code/mozilla-inbound/docshell/base/nsDocShell.cpp:5712
#8 0x00007f40e46e591b in nsFrameLoader::DestroyDocShell (this=0x7f40b96a4080) at /home/shawnjohnjr/code/mozilla-inbound/dom/base/nsFrameLoader.cpp:1576
If we remove the line "otherDoc.adoptNode(div)", "FragmentOrElement::SetXBLBinding" will be called. But if we call "otherDoc.adoptNode(div)" in the test case, we never set SetXBLBinding(nullptr).
Comment 25•9 years ago
|
||
In case you haven't found it yet, tools/rb/fix_linux_stack.py and fix_macosx_stack.py can be run on a refcount log in order to symbolize it, depending on the OS you are on. It is faster to run it on the result of make-tree.pl.
(In reply to Andrew McCreight [:mccr8] from comment #25)
> In case you haven't found it yet, tools/rb/fix_linux_stack.py and
> fix_macosx_stack.py can be run on a refcount log in order to symbolize it,
> depending on the OS you are on. It is faster to run it on the result of
> make-tree.pl.
oh! Now I see. Thanks a lot.
No progress on this bug for a week is due to i'm working on storage last week, I will continue on this bug this week.
So when we don't execute |adoptNode()| in the test case, |nsWebShellWindow::RequestWindowClose| will trigger to set FragmentOrElement::SetXBLBinding to nullptr.
Without calling adoptNode() in the test case. aBinding set to 0x0
Breakpoint 2, mozilla::dom::FragmentOrElement::SetXBLBinding (this=0x7f5b4bf79ee0, aBinding=0x0, aOldBindingManager=0x7f5b4bf03460)
at /home/shawnjohnjr/code/mozilla-inbound/dom/base/FragmentOrElement.cpp:1018
1018 if (aOldBindingManager) {
........
With calling adoptNode() in the test case,
I can only see SetXBLBinding been set after CreateShadowRoot.
#0 mozilla::dom::FragmentOrElement::SetXBLBinding (this=0x7f49d7ff4350, aBinding=0x7f49d7ff6290, aOldBindingManager=0x0)
at /home/shawnjohnjr/code/mozilla-inbound/dom/base/FragmentOrElement.cpp:1018
#1 0x00007f4a09721336 in mozilla::dom::Element::CreateShadowRoot (this=0x7f49d7ff4350, aError=...) at /home/shawnjohnjr/code/mozilla-inbound/dom/base/Element.cpp:1063
#2 0x00007f4a09ea6c4e in mozilla::dom::ElementBinding::createShadowRoot (cx=0x7f49da0ee800, obj=..., self=<optimized out>, args=...)
at /home/shawnjohnjr/code/mozilla-inbound/obj-x86_64-pc-linux-gnu/dom/bindings/ElementBinding.cpp:3189
#3 0x00007f4a09f95626 in mozilla::dom::GenericBindingMethod (cx=cx@entry=0x7f49da0ee800, argc=<optimized out>, vp=<optimized out>)
at /home/shawnjohnjr/code/mozilla-inbound/dom/bindings/BindingUtils.cpp:2778
#4 0x00007f4a0bbba771 in js::CallJSNative (cx=cx@entry=0x7f49da0ee800, native=0x7f4a09f954cd <mozilla::dom::GenericBindingMethod(JSContext*, unsigned int, JS::Value*)>, args=...)
at /home/shawnjohnjr/code/mozilla-inbound/js/src/jscntxtinlines.h:235
#5 0x00007f4a0bbb2e63 in js::InternalCallOrConstruct (cx=0x7f49da0ee800, args=..., construct=js::NO_CONSTRUCT)
at /home/shawnjohnjr/code/mozilla-inbound/js/src/vm/Interpreter.cpp:480
#6 0x00007f4a0bba49e0 in js::CallFromStack (args=..., cx=<optimized out>) at /home/shawnjohnjr/code/mozilla-inbound/js/src/vm/Interpreter.cpp:531
#7 Interpret (cx=0x7f49da0ee800, state=...) at /home/shawnjohnjr/code/mozilla-inbound/js/src/vm/Interpreter.cpp:2831
#8 0x00007f4a0bbb2c3b in js::RunScript (cx=cx@entry=0x7f49da0ee800, state=...) at /home/shawnjohnjr/code/mozilla-inbound/js/src/vm/Interpreter.cpp:426
#9 0x00007f4a0bbb2f06 in js::InternalCallOrConstruct (cx=cx@entry=0x7f49da0ee800, args=..., construct=construct@entry=js::NO_CONSTRUCT)
at /home/shawnjohnjr/code/mozilla-inbound/js/src/vm/Interpreter.cpp:498
Ting, thanks for the hint.
So removing |!GetShadowRoot()| can enforce RemoveFromBindingManagerRunnable be executed.
if (document) {
// Notify XBL- & nsIAnonymousContentCreator-generated
// anonymous content that the document is changing.
// Unlike XBL, bindings for web components shadow DOM
// do not get uninstalled.
- if (HasFlag(NODE_MAY_BE_IN_BINDING_MNGR) && !GetShadowRoot()) {
+ if (HasFlag(NODE_MAY_BE_IN_BINDING_MNGR)) {
nsContentUtils::AddScriptRunner(
new RemoveFromBindingManagerRunnable(document->BindingManager(), this,
document));
}
I guess we have shadow root and XBL binding both on the same node, and since we don't remove binding from BindingManager, XBL binding leaks.
Maybe unknown edge is called "[via binding manager] mBoundContentSet entry".
https://dxr.mozilla.org/mozilla-central/source/dom/xbl/nsBindingManager.cpp#1006
Hi William,
It looks like we keep the XBL binding on purpose in bug 1076784. So I'm wondering if we really want keep XBL Binding here. Do you have any suggestion?
https://dxr.mozilla.org/mozilla-central/source/dom/base/Element.cpp#1813
Flags: needinfo?(wchen)
Comment 33•9 years ago
|
||
(In reply to Shawn Huang [:shawnjohnjr] from comment #32)
> Hi William,
> It looks like we keep the XBL binding on purpose in bug 1076784. So I'm
> wondering if we really want keep XBL Binding here. Do you have any
> suggestion?
>
> https://dxr.mozilla.org/mozilla-central/source/dom/base/Element.cpp#1813
ShadowRoot use XBL bindings to implement its behavior so we should always have a XBL binding when there is a ShadowRoot. In the code you reference, we do still want to keep the binding in the shadow root case. That code is there because XBL uninstalls bindings when you remove the bound node from the document. The shadow DOM spec does not say to do this.
Flags: needinfo?(wchen)
Assignee: shuang → nobody
Updated•6 years ago
|
Priority: -- → P3
Comment 34•6 years ago
|
||
Since createShadownRoot was removed, is this bug still valid?
Flags: needinfo?(emilio)
Comment 35•6 years ago
|
||
we need to see if it repros with attachShadow. But Shadow DOM and XBL were decoupled long ago, so I suspect it won't repro.
Flags: needinfo?(emilio)
Comment 36•6 years ago
|
||
Attachment #8677599 -
Attachment is obsolete: true
Updated•6 years ago
|
Status: NEW → RESOLVED
Closed: 6 years ago
Resolution: --- → WORKSFORME
Assignee | ||
Updated•6 years ago
|
Component: DOM → DOM: Core & HTML
You need to log in
before you can comment on or make changes to this bug.
Description
•