godot: Crash during engine shutdown if `get_tree()` is ever called from GDNative

Godot version: 3.3 stable

OS/device including version: Windows 10

Issue description: If get_tree() is ever called from a GDNative plugin then Godot will crash on shutdown when you quit your game.

The crash occurs in NativeScriptLanguage::free_instance_binding_data.

free_instance_binding_data is entered but godot_gdnative_terminate has already been called at this point so the function pointer is invalid.

This doesn’t happen in Godot 3.2.

Steps to reproduce: Call get_tree() from a GDNative class, run your game with a debugger attached and quit.

Minimal reproduction project: gdnative_get_tree_crash.zip

This is the only relevant part AFAIK:

class Test : public godot::Node {
	GODOT_CLASS(Test, godot::Node);
public:
	static void _register_methods() {
		register_method("_ready", &Test::_ready);
	}
	void _init(){}
	void _ready() {
		get_tree();
		// Godot will now crash in NativeScriptLanguage::free_instance_binding_data() 
	}
};

About this issue

  • Original URL
  • State: open
  • Created 3 years ago
  • Reactions: 3
  • Comments: 23 (9 by maintainers)

Commits related to this issue

Most upvoted comments

It appears this workaround can be added to user code to suppress the crash

extern "C" void GDN_EXPORT godot_gdnative_terminate(godot_gdnative_terminate_options * o)
{
	Godot::nativescript_terminate(godot::_RegisterState::nativescript_handle); // Add this line
	Godot::gdnative_terminate(o);
}

I tried again and I finally managed to reproduce the crash on Linux. It doesn’t seem to happen when running the project through the editor, but it does when running standalone.

Here’s a fixed MRP so that it builds properly against godot-cpp godot-3.3.3-stable (with renamed godot_headers to godot-headers, and fixed path for Linux library).

gdnative_get_tree_crash.zip

How to use:

cd godot-cpp
cmake -DCMAKE_BUILD_TYPE=Debug .
make -j
cd ..
cmake -DCMAKE_BUILD_TYPE=Debug -DGODOT_CPP_ROOT=godot-cpp .
make -j
cd project
godot

Crash backtrace (from 3.3.4 RC e4df8a68fa9d2e35c1710dd952b1f9337e7e2f46, but that’s close enough to 3.3.3 stable):

#0  0x00007fffa01e3497 in ?? ()
#1  0x0000000001bb284f in NativeScriptLanguage::free_instance_binding_data (this=0x7667dc0, p_data=0x7e995a0) at modules/gdnative/nativescript/nativescript.cpp:1363
#2  0x0000000004304168 in Object::~Object (this=0x7adcc60, __in_chrg=<optimized out>) at core/object.cpp:2047
#3  0x00000000044349bc in MainLoop::~MainLoop (this=0x7adcc60, __in_chrg=<optimized out>) at core/os/main_loop.cpp:81
#4  0x000000000348063e in SceneTree::~SceneTree (this=0x7adcc60, __in_chrg=<optimized out>) at scene/main/scene_tree.cpp:2176
#5  0x000000000170fd8d in memdelete<MainLoop> (p_class=0x7adcc60) at ./core/os/memory.h:117
#6  0x0000000001708b12 in OS_X11::delete_main_loop (this=0x7fffffffce20) at platform/x11/os_x11.cpp:2913
#7  0x000000000174522d in Main::cleanup (p_force=false) at main/main.cpp:2241
#8  0x00000000016fa7e9 in main (argc=1, argv=0x7fffffffd728) at platform/x11/godot_x11.cpp:57

Note that godot-cpp hasn’t been updated yet to match the 3.3-stable release, so that may be part of the problem.

This might get solved once this update is done.

Note that godot-cpp hasn’t been updated yet to match the 3.3-stable release, so that may be part of the problem.

This might get solved once this update is done.

Is there any effort towards figuring out how to synchronize this stuff better? It sounds like there is always going to be a window of several weeks after every Godot release where c++ projects are not going to work. Frustrating for existing developers who do not realise that they need to wait for godot-cpp to catch up, and confusing for new c++ developers who are simply following the instructions in the godot-cpp readme.

I can confirm this happens with godot-cpp (Win10 + MSVC, using the cpp gdnative-demos codebase) but doesn’t happen with godot-nim or with the C godot-headers. I only have basic familiarity with godot-cpp, but I’ll try to help debug this.