godotengine / godot-cpp

C++ bindings for the Godot script API
MIT License
1.75k stars 580 forks source link

Editor plugin crashes editor on unfocus editor window then refocus when reloadable is on #535

Open derekdai opened 3 years ago

derekdai commented 3 years ago

With this editor plugin loaded (make sure reloadable is on in .gdnlib), unfocus editor window (now the plugin is unloaded), then refocus editor window (plugin now reload again), then click on "Main Screen" button on top of window, editor should crash with segmentation fault.

After refocus editor, exit from godot editor results in editor segmentation fault at different place.

My guess is there are something pass from plugin into godot and been kept over plugin unloading and reloading, then editor touches these invalid addresses causes segmentation fault.

Here is my source code, only plugin name and icon returned

// MainScreen.hpp
#include <Godot.hpp>
#include <String.hpp>
#include <Control.hpp>
#include <EditorPlugin.hpp>

using namespace godot;

class MainScreen : public EditorPlugin {
    GODOTCLASS(MainScreen, EditorPlugin)

public:
    static void _registermethods();

    bool has_main_screen();

    Ref<Texture> get_plugin_icon();

    String get_plugin_name();
};
// MainScreen.cpp
#include <Godot.hpp>
#include <EditorInterface.hpp>

#include "MainScreen.hpp"

using namespace godot;

void MainScreen::_register_methods() {
    register_method("has_main_screen", &MainScreen::has_main_screen);
    register_method("get_plugin_icon", &MainScreen::get_plugin_icon);
    register_method("get_plugin_name", &MainScreen::get_plugin_name);
}

bool MainScreen::has_main_screen()
{
    return true;
}

godot::String MainScreen::get_plugin_name()
{
    return String("Main Screen");   
}

Ref<Texture> MainScreen::get_plugin_icon()
{
  return get_editor_interface()->get_base_control()->get_icon("Node", "EditorIcons");
}

extern "C" void GDN_EXPORT godot_gdnative_init(godot_gdnative_init_options *o) {
    godot::Godot::gdnative_init(o);
}

extern "C" void GDN_EXPORT godot_nativescript_init(void *handle) {
    godot::Godot::nativescript_init(handle);

    godot::register_tool_class<MainScreen>();
}

extern "C" void GDN_EXPORT godot_gdnative_terminate(godot_gdnative_terminate_options *o) {
    godot::Godot::gdnative_terminate(o);
}
# mainscreen.gdnlib
[general]

singleton=false
load_once=true
symbol_prefix="godot_"
reloadable=true

[entry]

X11.64="res://bin/libmain_screen.so"

[dependencies]

X11.64=[  ]
# mainscreen.gdns
[gd_resource type="NativeScript" load_steps=2 format=2]

[ext_resource path="res://addons/mainscreen/mainscreen.gdnlib" type="GDNativeLibrary" id=1]

[resource]
class_name = "MainScreen"
library = ExtResource( 1 )
Calinou commented 3 years ago

See also https://github.com/godotengine/godot/issues/19686 and https://github.com/godotengine/godot/issues/36139.

This sounds like an engine issue which should be reported on the main Godot repository. Make sure to include a complete minimal reproduction project there.