godotengine / godot

Godot Engine – Multi-platform 2D and 3D game engine
https://godotengine.org
MIT License
90.1k stars 21.15k forks source link

[GDExtension] Crash in `unregister_core_types()` in `Main::cleanup()` if have accessed `GDExtensionManager`, `ResourceUID` or `IP` singletons in GDExtension. #81030

Open Daylily-Zeleen opened 1 year ago

Daylily-Zeleen commented 1 year ago

Godot version

4.2.dev

System information

Windows 10, Vulkan, GTX1060

Issue description

GDExtensionManager, ResourceUID or IP singletons can be accessed in GDExtension, but will make godot crash in Main::cleanup().

And I notice that, in "register_core_types.cpp", these three singletons is different from other singletons.

Steps to reproduce

Just access them in GDExtension.

For example, just change "register_types.cpp" in godot-cpp's test like this.

/* godot-cpp integration testing project.
 *
 * This is free and unencumbered software released into the public domain.
 */

#include "register_types.h"

#include <gdextension_interface.h>

#include <godot_cpp/classes/gd_extension_manager.hpp>
#include <godot_cpp/classes/ip.hpp>
#include <godot_cpp/classes/resource_uid.hpp>
#include <godot_cpp/variant/utility_functions.hpp>

using namespace godot;

void initialize_example_module(ModuleInitializationLevel p_level) {
    if (p_level != MODULE_INITIALIZATION_LEVEL_SCENE) {
        return;
    }

    UtilityFunctions::print(GDExtensionManager::get_singleton());
    UtilityFunctions::print(ResourceUID::get_singleton());
    UtilityFunctions::print(IP::get_singleton());
}

void uninitialize_example_module(ModuleInitializationLevel p_level) {
    if (p_level != MODULE_INITIALIZATION_LEVEL_SCENE) {
        return;
    }
}

extern "C" {
// Initialization.
GDExtensionBool GDE_EXPORT example_library_init(GDExtensionInterfaceGetProcAddress p_get_proc_address, GDExtensionClassLibraryPtr p_library, GDExtensionInitialization *r_initialization) {
    godot::GDExtensionBinding::InitObject init_obj(p_get_proc_address, p_library, r_initialization);

    init_obj.register_initializer(initialize_example_module);
    init_obj.register_terminator(uninitialize_example_module);
    init_obj.set_minimum_library_initialization_level(MODULE_INITIALIZATION_LEVEL_SCENE);

    return init_obj.init();
}
}

Minimal reproduction project

project.zip

dsnopek commented 1 year ago

This sounds very similar to https://github.com/godotengine/godot-cpp/issues/889

Daylily-Zeleen commented 1 year ago

I'm not sure, the crash position about gdestension_manager is same as #889, but in my case, only GDExtensionManager, ResourceUID and IP will lead to crash.