Skip to content

Cleanup function state connections when destroying instance#65910

Merged
akien-mga merged 1 commit into
godotengine:masterfrom
KoBeWi:gdsus
Feb 3, 2023
Merged

Cleanup function state connections when destroying instance#65910
akien-mga merged 1 commit into
godotengine:masterfrom
KoBeWi:gdsus

Conversation

@KoBeWi
Copy link
Copy Markdown
Member

@KoBeWi KoBeWi commented Sep 16, 2022

Closes #24311

It can't be that simple, can it? 🤔

@KoBeWi KoBeWi added this to the 4.0 milestone Sep 16, 2022
@KoBeWi KoBeWi requested a review from a team as a code owner September 16, 2022 15:43
@KoBeWi KoBeWi force-pushed the gdsus branch 2 times, most recently from 59b8375 to df62298 Compare November 27, 2022 22:34
@KoBeWi
Copy link
Copy Markdown
Member Author

KoBeWi commented Nov 27, 2022

I rebased and the code is not valid anymore :/
It works, but sanitizer is not happy about it.

@adamscott
Copy link
Copy Markdown
Member

I suspect that the same GDScriptInstance::~GDScriptInstance() is ran twice. Try adding a destructing variable, like I did in GDScript::~GDScript().

@anvilfolk
Copy link
Copy Markdown
Contributor

anvilfolk commented Nov 28, 2022

I suspect that the same GDScriptInstance::~GDScriptInstance() is ran twice. Try adding a destructing variable, like I did in GDScript::~GDScript().

Curious to know how that would happen. I figured destructors would only ever run once!

@anvilfolk
Copy link
Copy Markdown
Contributor

I just tested adding destructing to GDScriptInstance but the issues persist unfortunately.

@adamscott
Copy link
Copy Markdown
Member

adamscott commented Nov 30, 2022

This patch makes the build pass the sanitizer.

diff --git a/modules/gdscript/gdscript.cpp b/modules/gdscript/gdscript.cpp
index 72d5bb23c5..dc87560fdd 100644
--- a/modules/gdscript/gdscript.cpp
+++ b/modules/gdscript/gdscript.cpp
@@ -1925,10 +1925,14 @@ GDScriptInstance::~GDScriptInstance() {
 
 	while (SelfList<GDScriptFunctionState> *E = pending_func_states.first()) {
 		// Order matters since clearing the stack may already cause
-		// the GDSCriptFunctionState to be destroyed and thus removed from the list.
+		// the GDScriptFunctionState to be destroyed and thus removed from the list.
 		pending_func_states.remove(E);
-		E->self()->_clear_connections();
-		E->self()->_clear_stack();
+		GDScriptFunctionState *state = E->self();
+		state->_clear_connections();
+		state = Object::cast_to<GDScriptFunctionState>(state);
+		if (state != nullptr) {
+			state->_clear_stack();
+		}
 	}
 
 	if (script.is_valid() && owner) {

@adamscott
Copy link
Copy Markdown
Member

Weird. My local build pass the clang test sanitizers.

@adamscott
Copy link
Copy Markdown
Member

adamscott commented Dec 1, 2022

My hunch says that this is more sane than casting AND it should fix the macos SIGSEGV.

diff --git a/modules/gdscript/gdscript.cpp b/modules/gdscript/gdscript.cpp
index df57749f76..fc3d42b1b0 100644
--- a/modules/gdscript/gdscript.cpp
+++ b/modules/gdscript/gdscript.cpp
@@ -1484,9 +1484,9 @@ GDScript::~GDScript() {
 			// the GDScriptFunctionState to be destroyed and thus removed from the list.
 			pending_func_states.remove(E);
 			GDScriptFunctionState *state = E->self();
+			ObjectID state_id = state->get_instance_id();
 			state->_clear_connections();
-			state = Object::cast_to<GDScriptFunctionState>(state);
-			if (state != nullptr) {
+			if (ObjectDB::get_instance(state_id) != nullptr) {
 				state->_clear_stack();
 			}
 		}
@@ -1932,9 +1932,9 @@ GDScriptInstance::~GDScriptInstance() {
 		// the GDSCriptFunctionState to be destroyed and thus removed from the list.
 		pending_func_states.remove(E);
 		GDScriptFunctionState *state = E->self();
+		ObjectID state_id = state->get_instance_id();
 		state->_clear_connections();
-		state = Object::cast_to<GDScriptFunctionState>(state);
-		if (state != nullptr) {
+		if (ObjectDB::get_instance(state_id) != nullptr) {
 			state->_clear_stack();
 		}
 	}

Co-authored-by: Adam Scott <ascott.ca@gmail.com>
Copy link
Copy Markdown
Member

@adamscott adamscott left a comment

Choose a reason for hiding this comment

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

Let's merge this!

Copy link
Copy Markdown
Member

@vnen vnen left a comment

Choose a reason for hiding this comment

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

I think this is okay.

@akien-mga akien-mga merged commit 604493e into godotengine:master Feb 3, 2023
@akien-mga
Copy link
Copy Markdown
Member

Thanks!

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Destroying an object running a coroutine (yield) should interrupt this coroutine properly

5 participants