From 14506a4282b6b9079280ec54f50f46ba041c0d10 Mon Sep 17 00:00:00 2001 From: David Snopek Date: Fri, 10 May 2024 12:07:21 -0500 Subject: [PATCH] GDExtension: Prevent crash during shutdown as singletons are deleted --- core/config/engine.cpp | 6 ++++++ core/config/engine.h | 2 +- core/extension/gdextension_manager.cpp | 3 +++ core/object/object.cpp | 10 +++++++--- 4 files changed, 17 insertions(+), 4 deletions(-) diff --git a/core/config/engine.cpp b/core/config/engine.cpp index f2f8aebe8b5..3574430cf75 100644 --- a/core/config/engine.cpp +++ b/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), diff --git a/core/config/engine.h b/core/config/engine.h index 8dece803e33..7e617d8773a 100644 --- a/core/config/engine.h +++ b/core/config/engine.h @@ -187,7 +187,7 @@ public: bool notify_frame_server_synced(); Engine(); - virtual ~Engine() {} + virtual ~Engine(); }; #endif // ENGINE_H diff --git a/core/extension/gdextension_manager.cpp b/core/extension/gdextension_manager.cpp index a4d032f22f7..1ee9de07768 100644 --- a/core/extension/gdextension_manager.cpp +++ b/core/extension/gdextension_manager.cpp @@ -295,6 +295,9 @@ GDExtensionManager::GDExtensionManager() { } GDExtensionManager::~GDExtensionManager() { + if (singleton == this) { + singleton = nullptr; + } #ifndef DISABLE_DEPRECATED GDExtensionCompatHashes::finalize(); #endif diff --git a/core/object/object.cpp b/core/object/object.cpp index dfc8e2a29aa..5125ab8a6ec 100644 --- a/core/object/object.cpp +++ b/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