Skip to content

Crash on shutdown if certain singletons were used in extension #889

Description

@mihe

When using certain singletons like OS::get_singleton() from within a GDExtension it seems like internal::gdn_interface->object_get_instance_binding in the generated get_singleton() ends up storing callbacks on the editor side to OS::___binding_callbacks which point to functions on the extension side.

These callbacks (___binding_free_callback specifically) end up getting invoked on editor shutdown (at Object::~Object()) during memdelete(_os) in unregister_core_types(). The problem is that by then we've already unloaded the extension libraries in memdelete(native_extension_manager), resulting in trying to call a function that no longer exists, leading to an access violation crash.

This also applies to Engine::get_singleton(). More singletons might be affected that I haven't run into yet.

Editor: v4.0.beta.custom_build (ca25c6e0a)
Architecture: x86_64
Compiler: MSVC (v19.33.31630)
OS: Windows 11 (v10.0.22621)

Minimal repro:

#include <godot/gdnative_interface.h>

#include <godot_cpp/classes/os.hpp>
#include <godot_cpp/core/class_db.hpp>
#include <godot_cpp/core/defs.hpp>
#include <godot_cpp/godot.hpp>

using namespace godot;

void initialize_example_module(ModuleInitializationLevel p_level) {
    if (p_level == MODULE_INITIALIZATION_LEVEL_SCENE) {
        OS::get_singleton();
    }
}

extern "C" {

GDNativeBool GDN_EXPORT example_library_init(
    const GDNativeInterface* p_native_iface,
    const GDNativeExtensionClassLibraryPtr p_native_lib,
    GDNativeInitialization* p_native_init
) {
    GDExtensionBinding::InitObject init_obj(p_native_iface, p_native_lib, p_native_init);
    init_obj.register_initializer(initialize_example_module);
    init_obj.set_minimum_library_initialization_level(MODULE_INITIALIZATION_LEVEL_SCENE);
    return init_obj.init();
}

} // extern "C"

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugThis has been identified as a bugconfirmedcrashtopic:gdextensionThis relates to the new Godot 4 extension implementation

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions