Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

gdextension: singleton causes segfault on exit (although works in runtime) #62152

Closed
nathanfranke opened this issue Jun 17, 2022 · 6 comments · Fixed by #77633
Closed

gdextension: singleton causes segfault on exit (although works in runtime) #62152

nathanfranke opened this issue Jun 17, 2022 · 6 comments · Fixed by #77633

Comments

@nathanfranke
Copy link
Contributor

nathanfranke commented Jun 17, 2022

Godot version

v4.0.alpha.custom_build [4463dd9] (2022-06-17)
v4.0.alpha.custom_build [ebd966a] (2022-08-23)

System information

Arch on 5.15.46-1-lts

Issue description

"although works in runtime" means MySingleton still behaves correctly. MySingleton.hello_singleton() correctly prints text.

Code Snippet:

void gdextension_initialize(ModuleInitializationLevel p_level)
{
	if (p_level == MODULE_INITIALIZATION_LEVEL_SCENE)
	{
		ClassDB::register_class<MyNode>();
		ClassDB::register_class<MySingleton>();

		_my_singleton = memnew(MySingleton);
		Engine::get_singleton()->register_singleton("MySingleton", _my_singleton);
	}
}

void gdextension_terminate(ModuleInitializationLevel p_level)
{
	if (p_level == MODULE_INITIALIZATION_LEVEL_SCENE)
	{
		Engine::get_singleton()->unregister_singleton("MySingleton");
		memdelete(_my_singleton); // Segmentation fault with and without this line.
	}
}

Log:

Godot Engine v4.0.alpha.custom_build.4463dd9d8 - https://godotengine.org
Vulkan API 1.2.0 - Using Vulkan Device #0: AMD - AMD RADV SIENNA_CICHLID
 
WARNING: FBX file import is enabled, but no FBX2glTF path is configured. FBX files will not be imported.
     at: _editor_init (modules/gltf/register_types.cpp:92)

*** clicked exit ***

Segmentation fault (core dumped)

Valgrind:

==202520== Jump to the invalid address stated on the next line
==202520==    at 0xCB7D920: ???
==202520==    by 0x6DE1226: core_bind::Engine::~Engine() (core_bind.h:622)
==202520==    by 0x6DDD84E: void memdelete<core_bind::Engine>(core_bind::Engine*) (memory.h:108)
==202520==    by 0x6DD1E2F: unregister_core_types() (register_core_types.cpp:345)
==202520==    by 0x2316E8D: Main::cleanup(bool) (main.cpp:2994)
==202520==    by 0x22AE913: main (godot_linuxbsd.cpp:70)
==202520==  Address 0xcb7d920 is not stack'd, malloc'd or (recently) free'd
==202520== 
==202520== Invalid read of size 1
==202520==    at 0xB1AE72E: x86_64_fallback_frame_state (md-unwind-support.h:63)
==202520==    by 0xB1AE72E: uw_frame_state_for (unwind-dw2.c:1271)
==202520==    by 0xB1B04AA: _Unwind_Backtrace (unwind.inc:303)
==202520==    by 0xB2D78D2: backtrace (backtrace.c:78)
==202520==    by 0x22AF292: handle_crash(int) (crash_handler_linuxbsd.cpp:56)
==202520==    by 0xB1F78DF: ??? (in /usr/lib/libc.so.6)
==202520==    by 0xCB7D91F: ???
==202520==    by 0x6DE1226: core_bind::Engine::~Engine() (core_bind.h:622)
==202520==    by 0x6DDD84E: void memdelete<core_bind::Engine>(core_bind::Engine*) (memory.h:108)
==202520==    by 0x6DD1E2F: unregister_core_types() (register_core_types.cpp:345)
==202520==    by 0x2316E8D: Main::cleanup(bool) (main.cpp:2994)
==202520==    by 0x22AE913: main (godot_linuxbsd.cpp:70)
==202520==  Address 0xcb7d920 is not stack'd, malloc'd or (recently) free'd
==202520== 
==202520== 
==202520== Process terminating with default action of signal 11 (SIGSEGV): dumping core
==202520==  Access not within mapped region at address 0xCB7D920
==202520==    at 0xB1AE72E: x86_64_fallback_frame_state (md-unwind-support.h:63)
==202520==    by 0xB1AE72E: uw_frame_state_for (unwind-dw2.c:1271)
==202520==    by 0xB1B04AA: _Unwind_Backtrace (unwind.inc:303)
==202520==    by 0xB2D78D2: backtrace (backtrace.c:78)
==202520==    by 0x22AF292: handle_crash(int) (crash_handler_linuxbsd.cpp:56)
==202520==    by 0xB1F78DF: ??? (in /usr/lib/libc.so.6)
==202520==    by 0xCB7D91F: ???
==202520==    by 0x6DE1226: core_bind::Engine::~Engine() (core_bind.h:622)
==202520==    by 0x6DDD84E: void memdelete<core_bind::Engine>(core_bind::Engine*) (memory.h:108)
==202520==    by 0x6DD1E2F: unregister_core_types() (register_core_types.cpp:345)
==202520==    by 0x2316E8D: Main::cleanup(bool) (main.cpp:2994)
==202520==    by 0x22AE913: main (godot_linuxbsd.cpp:70)

Note: For those curious the MRP is a copy of my (experimental) self-contained gdextension template

Steps to reproduce

  1. Download and extract the MRP (It is a test godot project bundled with C++ code)
  2. Run scons in the MRP
  3. Open Godot, import and edit the MRP project
  4. Scene→Quit

Minimal reproduction project

gdextension-segfault.zip


Edit: Error is fixed now and it was unrelated.

@nathanfranke nathanfranke changed the title gdextension: singleton causes error and segfault on exit (although works in runtime) gdextension: singleton causes segfault on exit (although works in runtime) Aug 8, 2022
@bitbrain
Copy link
Contributor

My GDExtension is fairly similar and with the latest master @ eda6800 I do not have this issue. Perhaps it was fixed?

@nathanfranke
Copy link
Contributor Author

I am still getting a segfault in v4.0.alpha.custom_build [ebd966a]

I just regenerated the extension api and gdextension too.

Thread 1 "godot.linuxbsd." received signal SIGSEGV, Segmentation fault.
0x00007fffe668d840 in ?? ()
(gdb) bt
#0  0x00007fffe668d840 in ?? ()
#1  0x000055555c90d148 in Object::~Object (this=0x55555f620e70) at core/object/object.cpp:1825
#2  0x000055555c2454a7 in core_bind::Engine::~Engine (this=0x55555f620e70) at ./core/core_bind.h:632
#3  0x000055555c240fff in memdelete<core_bind::Engine> (p_class=0x55555f620e70) at ./core/os/memory.h:109
#4  0x000055555c235920 in unregister_core_types () at core/register_core_types.cpp:358
#5  0x00005555577b9619 in Main::cleanup (p_force=false) at main/main.cpp:3189
#6  0x000055555774265a in main (argc=4, argv=0x7fffffffe048) at platform/linuxbsd/godot_linuxbsd.cpp:74

@DmitriySalnikov
Copy link
Contributor

v4.0.beta.custom_build [afe1c89]
I have the same crash in these lines:

godot/core/object/object.cpp

Lines 1830 to 1834 in a16d362

for (uint32_t i = 0; i < _instance_binding_count; i++) {
if (_instance_bindings[i].free_callback) {
_instance_bindings[i].free_callback(_instance_bindings[i].token, this, _instance_bindings[i].binding);
}
}

godot.windows.editor.dev.x86_64.exe!Object::~Object() Line 1834	C++
[External Code]	
godot.windows.editor.dev.x86_64.exe!memdelete<core_bind::ResourceSaver>(core_bind::ResourceSaver * p_class) Line 112	C++
godot.windows.editor.dev.x86_64.exe!unregister_core_types() Line 372	C++
godot.windows.editor.dev.x86_64.exe!Main::cleanup(bool p_force) Line 3419	C++
godot.windows.editor.dev.x86_64.exe!widechar_main(int argc, wchar_t * * argv) Line 183	C++
godot.windows.editor.dev.x86_64.exe!_main() Line 203	C++
godot.windows.editor.dev.x86_64.exe!main(int argc, char * * argv) Line 217	C++
[External Code]	

In my case, this happens if a ResourceFormatSaver was added.

@Gramps
Copy link

Gramps commented Mar 22, 2023

Following @nathanfranke's example on 4.0-stable, with my project, I have an issue with singletons in GDExtension that result in: Failed to retrieve non-existent singleton 'Engine'.

Note that I am initializing the plug-in on the servers level, which may be more related to this issue. Changing it to scene level seems to fix this.

@MarioLiebisch
Copy link
Contributor

MarioLiebisch commented May 24, 2023

Experiencing the same with 4.03-stable (built from source and generated new header/JSON just to be sure).

Rebuilt current master, exported the latest API files etc. and rebuilt everything with debug symbols enabled:

================================================================
CrashHandlerException: Program crashed
Engine version: Godot Engine v4.1.dev.custom_build (094e88416ab84cc4e391703453fb46528739cd69)
Dumping the backtrace.
[0] <couldn't map PC to fn name>
[1] <couldn't map PC to fn name>
[2] Object::~Object (\Godot\core\object\object.cpp:1858)
[3] core_bind::Engine::~Engine
[4] core_bind::Engine::`scalar deleting destructor'
[5] memdelete<core_bind::Engine> (\Godot\core\os\memory.h:112)
[6] unregister_core_types (\Godot\core\register_core_types.cpp:375)
[7] Main::cleanup (\Godot\main\main.cpp:3650)
[8] widechar_main (\Godot\platform\windows\godot_windows.cpp:183)
[9] _main (\Godot\platform\windows\godot_windows.cpp:203)
[10] main (\Godot\platform\windows\godot_windows.cpp:217)
[11] WinMain (\Godot\platform\windows\godot_windows.cpp:231)
[12] __scrt_common_main_seh (D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:288)
[13] <couldn't map PC to fn name>
-- END OF BACKTRACE --
================================================================

This is the same location Dmitriy highlighted above.
Even if the registered singleton Object does nothing, as soon as it's registered, this happens once the engine closes.

@MarioLiebisch
Copy link
Contributor

To anyone still experiencing this issue, would be great if you could try the PR and see if it fixes the issue for you.

MarioLiebisch added a commit to MarioLiebisch/godot that referenced this issue May 30, 2023
@YuriSizov YuriSizov added this to the 4.1 milestone Jun 2, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants