Skip to content

GDScript: Fix interrupted coroutines not clearing#116711

Merged
Repiteo merged 1 commit into
godotengine:masterfrom
dalexeev:gds-fix-coroutine-clearing
Feb 25, 2026
Merged

GDScript: Fix interrupted coroutines not clearing#116711
Repiteo merged 1 commit into
godotengine:masterfrom
dalexeev:gds-fix-coroutine-clearing

Conversation

@dalexeev
Copy link
Copy Markdown
Member

@dalexeev dalexeev commented Feb 24, 2026

@dalexeev dalexeev added this to the 4.7 milestone Feb 24, 2026
@dalexeev dalexeev requested review from a team as code owners February 24, 2026 09:07
@HolonProduction
Copy link
Copy Markdown
Member

Just to check if I'm understanding this correctly. The purpose of those code snippets:

if (ObjectDB::get_instance(state_id)) {
state->_clear_stack();
}

if (ObjectDB::get_instance(state_id)) {
state->_clear_stack();
}

is to break reference cycles when a function state is referenced from its stack?

@dalexeev
Copy link
Copy Markdown
Member Author

The purpose of those code snippets <...> is to break reference cycles when a function state is referenced from its stack?

See #65910. I'm not sure, but probably the logic behind this is that during _clear_connections() the above obtained GDScriptFunctionState might be freed, so using the raw pointer state again might be unsafe.

GDScriptFunctionState *state = E->self();
ObjectID state_id = state->get_instance_id();
state->_clear_connections();
if (ObjectDB::get_instance(state_id)) {
state->_clear_stack();
}

I tested this and looked at the code a bit more. It looks like it works correctly. Perhaps the crashes were caused by the _clear_stack() call not being protected by a mutex, and the memory leaks were caused by #65910 not being implemented yet. Or maybe it was fixed in a later PR.

The current behavior is clearly wrong, and re-adding the _clear_stack() call to the GDScriptFunctionState destructor seems correct to me. If the instance whose signal GDScriptFunctionState is connected to has been freed, the coroutine cannot be resumed under any circumstances, so the saved stack must be cleared regardless of whether the function has completed.

@dalexeev
Copy link
Copy Markdown
Member Author

dalexeev commented Feb 24, 2026

Copy link
Copy Markdown
Member

@HolonProduction HolonProduction left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense to me

@Repiteo Repiteo merged commit 017e690 into godotengine:master Feb 25, 2026
20 checks passed
@Repiteo
Copy link
Copy Markdown
Contributor

Repiteo commented Feb 25, 2026

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

3 participants