Add clearing of static_gdscript_cache
to GDScriptCache
#104281
Merged
+1
−0
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
As talked about on Rocket Chat, this relates to an issue that I've been trying to debug for a few days now, but have so far been unsuccessful in figuring out what the exact cause is, hence why I can't provide an issue/MRP for it.
Description
In short, in the relatively large project I'm working with there seems to be some issue where a significant amount of
GDScript
instances are somehow ending up in a strange state where they're being kept alive byGDScriptCache::static_gdscript_cache
, but are somehow not inGDScriptLanguage::script_list
, which (as far as I can tell) should rightfully hold every non-freedGDScript
instance.This then leads to these
GDScript
instances havingGDScript::clear
called on them too late in the program flow, resulting in this error being tripped inSelfList::List::remove
, for every single function in these classes, due to redundant removals fromGDScriptLanguage::function_list
:godot/core/templates/self_list.h
Line 79 in 9e6ee9c
The common denominator between these classes seems to be that they all have
static
variables in them.I've so far only seen this problem manifest when deleting the
.godot
folder and opening the project in the editor and then closing it, meaning it's reproducible with--import
, with or without--headless
, which means we're getting a lot of these errors when doing--headless --import
in a CI context.As best I can tell, this is most likely a regression in 4.4, as this only started happening after we migrated this project from 4.3-stable to 4.4-stable, and latest
master
(4ef0cd6 as of writing this) does not resolve the issue.Unfortunately, bisecting this particular issue would take a considerable amount of effort, due to the time it takes to do a clean import in this particular project, along with some other complications, so I can't tell you where the regression originated from at this time.
Sequence of events
As mentioned, the loop here in
GDScriptLanguage::finish
never seems to iterate over these particularGDScript
instances, for reasons I don't quite understand:godot/modules/gdscript/gdscript.cpp
Lines 2330 to 2357 in 9e6ee9c
... which means that
GDScript::clear
isn't called for them here:godot/modules/gdscript/gdscript.cpp
Line 2354 in 9e6ee9c
... which means that their member functions are not freed as part of that either, as found here:
godot/modules/gdscript/gdscript.cpp
Lines 1615 to 1617 in 9e6ee9c
... which means we'll end up clearing
GDScriptLanguage::function_list
before anyGDScript::clear
happens:godot/modules/gdscript/gdscript.cpp
Line 2359 in 9e6ee9c
... and then
GDScriptCache
will end up being freed as part ofuninitialize_gdscript_module
, here:godot/modules/gdscript/register_types.cpp
Lines 174 to 176 in 9e6ee9c
... which will cause
GDScriptCache::static_gdscript_cache
to be destroyed as well, thereby freeing theRef<GDScript>
it seems to be holding, which in turn leads toGDScript::clear
being called from its destructor, as seen here:godot/modules/gdscript/gdscript.cpp
Line 1641 in 9e6ee9c
... which then actually frees the member functions (too late) and emits the error from
SelfList::List::remove
:godot/modules/gdscript/gdscript.cpp
Lines 1615 to 1617 in 9e6ee9c
Fix/workaround
This pull request fixes this issue by adding what seems to be a missing clearing of
GDScriptCache::static_gdscript_cache
inGDScriptCache::clear
, which according to @vnen might have been left out by mistake.This results in the affected
GDScript
instances being freed/cleared as part ofGDScriptCache::clear
before we go to clearGDScriptLanguage::function_list
, thereby preventing this redundant removal from happening, and thus preventing theSelfList
error from being reported.While this change does resolve the problem, and might still be warranted on its own, it still seems like a bit of a workaround to what might be a bigger issue here.