Kaynağa Gözat

GDExtension: Prevent crash during shutdown as singletons are deleted

David Snopek 1 yıl önce
ebeveyn
işleme
14506a4282

+ 6 - 0
core/config/engine.cpp

@@ -384,6 +384,12 @@ Engine::Engine() {
 	singleton = this;
 }
 
+Engine::~Engine() {
+	if (singleton == this) {
+		singleton = nullptr;
+	}
+}
+
 Engine::Singleton::Singleton(const StringName &p_name, Object *p_ptr, const StringName &p_class_name) :
 		name(p_name),
 		ptr(p_ptr),

+ 1 - 1
core/config/engine.h

@@ -187,7 +187,7 @@ public:
 	bool notify_frame_server_synced();
 
 	Engine();
-	virtual ~Engine() {}
+	virtual ~Engine();
 };
 
 #endif // ENGINE_H

+ 3 - 0
core/extension/gdextension_manager.cpp

@@ -295,6 +295,9 @@ GDExtensionManager::GDExtensionManager() {
 }
 
 GDExtensionManager::~GDExtensionManager() {
+	if (singleton == this) {
+		singleton = nullptr;
+	}
 #ifndef DISABLE_DEPRECATED
 	GDExtensionCompatHashes::finalize();
 #endif

+ 7 - 3
core/object/object.cpp

@@ -2095,9 +2095,13 @@ Object::~Object() {
 		_extension_instance = nullptr;
 	}
 #ifdef TOOLS_ENABLED
-	else if (_instance_bindings != nullptr && Engine::get_singleton()->is_extension_reloading_enabled()) {
-		for (uint32_t i = 0; i < _instance_binding_count; i++) {
-			GDExtensionManager::get_singleton()->untrack_instance_binding(_instance_bindings[i].token, this);
+	else if (_instance_bindings != nullptr) {
+		Engine *engine = Engine::get_singleton();
+		GDExtensionManager *gdextension_manager = GDExtensionManager::get_singleton();
+		if (engine && gdextension_manager && engine->is_extension_reloading_enabled()) {
+			for (uint32_t i = 0; i < _instance_binding_count; i++) {
+				gdextension_manager->untrack_instance_binding(_instance_bindings[i].token, this);
+			}
 		}
 	}
 #endif