This is a continuation of crbug.com/747382 . Now that crbug.com/747382 is fixed, this issue is the main blocker for using DevTools to investigate real world iframe leaks.
Setup:
The attached html file leaks iframes by saving them in
window.retaining_path.child1.child2.child3.child4.leaking_frames array.
That is the only real retaining path. All other retaining paths should contain it as a prefix. DevTools, however, shows a retaining path from Document DOM tree that is shorter than the real retaining path.
Steps to reproduce:
1) Open the attached html file. Wait until it leaks at least 1 iframe.
2) Open DevTools and take a heap snapshot.
3) Looks for the retainers of "Window" objects corresponding to the leaking iframes.
Expected:
- The topmost retaining path is window.retaining_path.child1.child2.child3.child4.leaking_frames.
- All other retaining paths contain the real retaining path as prefix.
What happens actually:
- The topmost retaining path originates from Document DOM tree (see screenshot) and is shorter than the real retaining path.
|
Deleted:
false-dom-retaining-path.html
1.4 KB
|
|
Deleted:
false-dom-retaining-path.png
55.2 KB
|
Comment 1 by u...@chromium.org
, Jul 27 2017The issue is in treatment of the native object groups. If I comment out processing of the native groups, then the retaining path looks exactly like I would expect. bool HeapSnapshotGenerator::FillReferences() { SnapshotFiller filler(snapshot_, &entries_); return v8_heap_explorer_.IterateAndExtractReferences(&filler); // && dom_explorer_.IterateAndExtractReferences(&filler); } Looks like objects in native object groups are simply added as strong roots in the heap snapshot. They should instead be treated similar to ephemerons: 1) If any object in a group is reachable, then the whole group is reachable. 2) If all objects in a group are unreachable, then the group is unreachable. This is how V8 GC treated objects groups before we switched to more precise wrapper tracing. I don't see a quick fix for this issue. There two options: 1) For dom wrappers somehow get retainer info from V8 GC by instrumenting it. 2) Add a notion of object group in heap snapshot and implement ephemeron handling in the frontend.