After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 712694 - Strong circular references between CodeContext and resolver/analyzer/flow_analyzer
Strong circular references between CodeContext and resolver/analyzer/flow_ana...
Status: RESOLVED OBSOLETE
Product: vala
Classification: Core
Component: Semantic Analyzer
unspecified
Other Linux
: High blocker
: 1.0
Assigned To: Daniel Espinosa
Vala maintainers
Depends on:
Blocks: 768817
 
 
Reported: 2013-11-19 16:20 UTC by jessevdk@gmail.com
Modified: 2018-05-22 14:59 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
Fix for bug 712694 (7.08 KB, patch)
2017-02-23 02:05 UTC, Daniel Espinosa
none Details | Review
vala: Use CodeContext.root instead of SemanticAnalyzer.root_symbol (2.70 KB, patch)
2017-12-14 11:47 UTC, Rico Tzschichholz
committed Details | Review
Release taken references to CodeContext after using it (5.15 KB, patch)
2017-12-14 11:48 UTC, Rico Tzschichholz
committed Details | Review

Description jessevdk@gmail.com 2013-11-19 16:20:58 UTC
The SymbolResolver, SemanticAnalyzer and FlowAnalyzer classes all three hold a strong reference to the CodeContext passed in on respectively resolve, analyze and analyze (stored in the respective objects). Since the CodeContext in turn holds strong references to these objects, memory is never released after CodeContext.check. It would be nice if either 1) the resolver/analyzer classes could store a weak reference, or 2) the resolver/analyzer classes would release the stored reference after they are done resolving/analyzing.
Comment 1 Luca Bruno 2013-11-19 19:14:52 UTC
This is not trivial to fix. Though making CodeContext weak may appear to be safe, it might be not. Think of an application using libvala that creates the CodeContex and forgets it. It now runs, but changing to weak may lead to crashes.
On the other hand, making resolver/analyzer/etc weak is not suitable either.

For now it's better to keep things as is, and let the application nullify resolver/analyzer/etc by hand to avoid leaks.
Comment 2 jessevdk@gmail.com 2013-11-19 19:44:14 UTC
So the recommended way to do this is not to use context.check(), but instead construct your own instances of resolver/analyzer instead?
Comment 3 Luca Bruno 2013-11-19 20:05:06 UTC
context.check() is fine, it's only that we don't know if existing applications rely on the owned references.
Comment 4 jessevdk@gmail.com 2013-11-19 21:17:56 UTC
However, note that if you use context.check() then you need to rely on some hoops to make sure the CodeContext will properly release. What I currently do is this to make that happen:

context.resolver.resolve(new CodeContext());
context.analyzer.context = null;
context.flow_analyzer.analyze(new CodeContext());

Which is a pretty non-obvious thing to do. Also, I explicitly need to set context.analyzer to null, instead of trying to analyze an empty CodeContext since that will spew a lot of null warnings.
Comment 5 Daniel Espinosa 2017-02-23 02:05:49 UTC
Created attachment 346523 [details] [review]
Fix for bug 712694

Vala resolver, analyzer, flow_analyzer and used_attr, requires a context just in to check, analyze or resolve, then at the end of each method, this patch set context to null, this is save if context is used to start check, analyze and resolve.

This should resolve lot of segfaults at compile time, because resources not released.
Comment 6 Rico Tzschichholz 2017-02-23 08:41:23 UTC
@daniel: So your 6 patches boil down to adding "this.context = null;" in three places. Those look absolutely valid, but I don't see how this fixes segfaults. Although it might introduce null-references as a side-effect.
Comment 7 Daniel Espinosa 2017-02-23 14:30:16 UTC
Well may is too early to say that these patches will prevent crashes. At GXml compilation time I saw valac crashes all the time but alleatory. I saw same crashes in GNOME Builder either.


So while is true a bug, as explained by reporter, this will make to have un released resources, even by valac itself making possible to fall in crashes due to  lack of resources.

Then we need to deprecate context properties for analyzer, resolver and checks, because they can be created at check() call in context, allowing to unref them when finished.

We need to deprecate analyzers context property and advice users that this property will be null all the time, except when an analysis or check is in progress.

In long term, all these objects should work alone, to run independent each other, forcing users to keep their own reference of the object.

To accomplish above, we need to remove context's properties for analyzers and checkers, to avoid circular references.
Comment 8 Rico Tzschichholz 2017-12-14 11:47:59 UTC
Created attachment 365527 [details] [review]
vala: Use CodeContext.root instead of SemanticAnalyzer.root_symbol
Comment 9 Rico Tzschichholz 2017-12-14 11:48:13 UTC
Created attachment 365528 [details] [review]
Release taken references to CodeContext after using it
Comment 10 Daniel Espinosa 2018-01-05 19:55:33 UTC
These patches have been pushed upstream, so they resolve the issue described here. Closing it. If a redesign/change is required a new bug should be opened.

https://git.gnome.org/browse/vala/commit/?id=2dc47785171f8f62f7f017939681e0d5cf3e9847


https://git.gnome.org/browse/vala/commit/?id=0c05b6e39d2a1f10cdd3f155c85d39f7a563080b
Comment 11 Rico Tzschichholz 2018-01-06 13:35:25 UTC
I left this bug open on purpose while I am not sure this is all needed to be fixed.
Comment 12 Rico Tzschichholz 2018-01-06 13:38:03 UTC
@ben: Can you share your experience regarding https://github.com/benwaffle/vala-language-server/blob/master/vala038_workarounds.vala ?
Comment 13 Ben 2018-01-06 20:16:53 UTC
Princeton wrote that code
Comment 14 Princeton Ferro 2018-01-07 01:30:14 UTC
(In reply to Rico Tzschichholz from comment #12)
> @ben: Can you share your experience regarding
> https://github.com/benwaffle/vala-language-server/blob/master/
> vala038_workarounds.vala ?

(In reply to Ben from comment #13)
> Princeton wrote that code

That "solution" I came to partially by inspection of libvala's code, and partially by experimenting. Some of that code might not be strictly necessary (perhaps the stuff that "breaks" Namespace references).

By inspection I found the three major circular references between CodeContext's and resolver/analyzer/flow_analyzer. (see https://github.com/benwaffle/vala-language-server/blob/master/vala038_workarounds.vala#L69) I also noticed that each Vala.Symbol has a strong ref to a Vala.Scope, which holds a container (Map<string,Symbol>) of strong refs to Symbols. So I clear the symbol table of each Scope just to be sure.

Without this fix, each time the language server compiles on just a single keyboard press, an extra 80-140 MiB (!) is leaked. With this fix, typically around 5 MiB.

I also noticed there are some members that are private (like Scope.anonymous_members), that might be candidates for circular refs.
Comment 15 GNOME Infrastructure Team 2018-05-22 14:59:46 UTC
-- GitLab Migration Automatic Message --

This bug has been migrated to GNOME's GitLab instance and has been closed from further activity.

You can subscribe and participate further through the new bug through this link to our GitLab instance: https://gitlab.gnome.org/GNOME/vala/issues/418.