Skip to content

Allow finding the source location for GC roots #43025

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
natebosch opened this issue Aug 12, 2020 · 5 comments
Closed

Allow finding the source location for GC roots #43025

natebosch opened this issue Aug 12, 2020 · 5 comments
Assignees
Labels
area-vm Use area-vm for VM related issues, including code coverage, and the AOT and JIT backends. P2 A bug or feature request we're likely to work on type-enhancement A request for a change that isn't a bug

Comments

@natebosch
Copy link
Member

When using the VM service protocol or the Observatory UI it's possible to track the retaining path of a given object, but once it's traced to a GC root there is no way to get further information or know where in the source code to look for the root.

For instance, a Future might hold a reference to arbitrary closures that await it. In Observatory the retaining path would end with something like:

retained by _context@0150898 of Closure (async_op) {  ⊞  }
retained by _awaiter@4048458 of _Future {  ⊞  }
retained by a GC root (static fields table)

I can't find more information about this instance of _Future.The Closure (async_op) reference can show me the source code containing the await. It doesn't tell me which await is interesting (this would also be useful) but it's possible to narrow it down manually. The Future that I'm awaiting in this instance is not a top level or static variable.

Is it possible to find the source code for the static field holding this _Future?

@mit-mit mit-mit added the area-vm Use area-vm for VM related issues, including code coverage, and the AOT and JIT backends. label Aug 12, 2020
@mkustermann
Copy link
Member

Is the intention to find async stacks of un-awaited Futures?

Finding await'ers for futures is inherently tied to the specific core libraries used. Finding out where a closure is awaiting (i.e. it's source position) is stored in VM specific metadata. Furthermore we already have such unwinding code in the VM for generating async stacks.

It might be best to add a vm-service API to allow querying for un-awaited async stacks. Some time ago I've made a prototype of this, see cl/141603.

Now that lazy async stacks (which does the very same unwinding) is being turned on by-default everywhere, it would be a natural step to consider introducing such an API.

Maybe @cskau-g could work on this (/cc @mraleph )

@natebosch
Copy link
Member Author

natebosch commented Aug 12, 2020

Is the intention to find async stacks of un-awaited Futures?

No. The intention is to find the places and reasons that we are "leaking" references to heavy objects. If I can figure out exactly where we have a static field referring to a Future which is holding references to instances that we want to be garbage collected I might be able to refactor into a different pattern.

Specifically #42457 and #42458 are two ways that a Future can cause unintended references that prevent garbage collection of other objects. Since a Future instance holds references I can't control I am trying to find refactorings like dart-lang/test#1318 to drop the reference to the future and allow GC of everything else.

@a-siva
Copy link
Contributor

a-siva commented Aug 12, 2020

/cc @rmacnak-google

@a-siva a-siva added type-enhancement A request for a change that isn't a bug P2 A bug or feature request we're likely to work on labels Aug 12, 2020
@mraleph
Copy link
Member

mraleph commented Sep 11, 2020

I think this is a serious regression in functionality caused by the refactoring we did to static fields, seeing something like:

Screenshot 2020-09-11 at 13 31 12

is not very helpful (especially when trying to understand issues with code base you are less familiar with).

@mkustermann
Copy link
Member

Tentatively assigning to @aam who moved field state out of RawField into an array. We could change the VM to, instead of tracing through the global fields array, trace from each static RawField to it's value in the fields array (make an artificial edge from RawField)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-vm Use area-vm for VM related issues, including code coverage, and the AOT and JIT backends. P2 A bug or feature request we're likely to work on type-enhancement A request for a change that isn't a bug
Projects
None yet
Development

No branches or pull requests

6 participants