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

[C#] Game crashes because of _UnhandledInput when exiting the game with Command + Q on MacOS #83973

Closed
chutneyio opened this issue Oct 26, 2023 · 6 comments · Fixed by #92201
Closed

Comments

@chutneyio
Copy link

Godot version

v4.1.2.stable.mono.official [399c9dc]

System information

Godot v4.1.2.stable.mono - macOS 14.0.0 - Vulkan (Forward+) - dedicated AMD Radeon Pro 555X - Intel(R) Core(TM) i7-8750H CPU @ 2.20GHz (12 Threads)

Issue description

Overriding _UnhandledInput on any node makes the game crashes when exiting with Command + Q keyboard shortcut on MacOS. It only happens on exported game or when I'm running from VSCode, using C#. I could not reproduce when running from the editor or using GDScript.

Error message from VSCode:

[1] sigill_handler(int, __siginfo*, void*)
[2] 2   libsystem_platform.dylib            0x00007ff804e2c37d _sigtramp + 29
[3] 3   ???                                 0x0000000000000000 0x0 + 0
[4] Object::can_translate_messages() const
[5] JSON::get_data() const
[6] JSON::get_data() const
[7] JSON::get_data() const
[8] RendererCompositorRD::_create_current()
[9] RendererCompositorRD::_create_current()
[10] 10  dyld                                0x00007ff804a763a6 start + 1942
-- END OF BACKTRACE --
================================================================

Steps to reproduce

  • Override _UnhandledInput
  • Run the exported game or run from VSCode
  • Quit the game with Command + Q
  • Game crashes

Minimal reproduction project

reproduce.zip

@msiedlarek
Copy link

Just stumbled upon this myself on 4.2.1-stable (b09f793).

Overriding _UnhandledInput or _Input, even doing absolutely nothing inside, causes a crash on engine quit while cleaning up a HashSet<Ref<InputEvent>> in Input destructor.

ERROR: FATAL: Condition "!rc_owner" is true.
   at: _instance_binding_reference_callback (modules/mono/csharp_script.cpp:1379)
Process 45056 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BREAKPOINT (code=1, subcode=0x100b280d4)
    frame #0: 0x0000000100b280d4 bug`CSharpLanguage::_instance_binding_reference_callback(p_token=0x000000011a7d7830, p_binding=0x0000600001d76af0, p_reference='\0') at csharp_script.cpp:1379:2
   1376		RefCounted *rc_owner = Object::cast_to<RefCounted>(script_binding.owner);
   1377
   1378	#ifdef DEBUG_ENABLED
-> 1379		CRASH_COND(!rc_owner);
   1380	#endif
   1381
   1382		MonoGCHandleData &gchandle = script_binding.gchandle;
Target 0: (bug) stopped.
(lldb) bt
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BREAKPOINT (code=1, subcode=0x100b280d4)
  * frame #0: 0x0000000100b280d4 bug`CSharpLanguage::_instance_binding_reference_callback(p_token=0x000000011a7d7830, p_binding=0x0000600001d76af0, p_reference='\0') at csharp_script.cpp:1379:2
    frame #1: 0x0000000103bfee70 bug`Object::_instance_binding_reference(this=0x000000010c908e40, p_reference=false) at object.h:678:11
    frame #2: 0x0000000103bfe938 bug`RefCounted::unreference(this=0x000000010c908e40) at ref_counted.cpp:89:22
    frame #3: 0x000000010040e384 bug`Ref<InputEvent>::unref(this=0x0000600000d53dd0) at ref_counted.h:209:31
    frame #4: 0x000000010040e420 bug`Ref<InputEvent>::~Ref(this=0x0000600000d53dd0) at ref_counted.h:222:3
    frame #5: 0x00000001003daebc bug`Ref<InputEvent>::~Ref(this=0x0000600000d53dd0) at ref_counted.h:221:9
    frame #6: 0x00000001037c7f08 bug`HashSet<Ref<InputEvent>, HashMapHasherDefault, HashMapComparatorDefault<Ref<InputEvent>>>::clear(this=0x000000011f191340) at hash_set.h:248:13
    frame #7: 0x00000001037e9ac8 bug`HashSet<Ref<InputEvent>, HashMapHasherDefault, HashMapComparatorDefault<Ref<InputEvent>>>::~HashSet(this=0x000000011f191340) at hash_set.h:465:3
    frame #8: 0x00000001037cb814 bug`HashSet<Ref<InputEvent>, HashMapHasherDefault, HashMapComparatorDefault<Ref<InputEvent>>>::~HashSet(this=0x000000011f191340) at hash_set.h:464:13
    frame #9: 0x00000001037cb744 bug`Input::~Input(this=0x000000011f190fb0) at input.cpp:1639:1
    frame #10: 0x00000001037cb9a0 bug`Input::~Input(this=0x000000011f190fb0) at input.cpp:1637:17
    frame #11: 0x0000000100450570 bug`void memdelete<Input>(p_class=0x000000011f190fb0) at memory.h:109:13
    frame #12: 0x0000000100450148 bug`Main::cleanup(p_force=false) at main.cpp:3841:3
    frame #13: 0x000000010042d594 bug`main(argc=1, argv=0x000000016fdff390) at godot_main_macos.mm:80:2
    frame #14: 0x00000001869f10e0 dyld`start + 2360

@knightofiam
Copy link

knightofiam commented May 20, 2024

Related to #89188, #92076.

@knightofiam
Copy link

knightofiam commented May 20, 2024

Update: I've been able to reproduce the original bug reported here by adding and removing the _UnhandledInput override.

I'm going to double post this here since I realized my issue is the same as this.

I'm getting a similar crash on macOS Sonoma 14.0. It's in Spine's Godot 4.2.2.stable.mono but I'm not reporting there as this bug already occurs in the standard engine build.

It seems like during input cleanup, a destructor tries to access a dangling pointer to a mouse cursor that was already freed.

ERROR: FATAL: Condition "!rc_owner" is true.
   at: _instance_binding_reference_callback (modules/mono/csharp_script.cpp:1379)

================================================================
handle_crash: Program crashed with signal 4
Engine version: Godot Engine v4.2.2.stable.mono.custom_build (15073afe3856abd2aa1622492fe50026c7d63dc1)
Dumping the backtrace. Please include this when reporting the bug to the project developer.
[1] invoke_previous_action(sigaction*, int, __siginfo*, void*, bool)
[2] 2   libsystem_platform.dylib            0x00007ff80cb6737d _sigtramp + 29
[3] 3   libsystem_c.dylib                   0x00007ff80c9df93b __sfvwrite + 387
[4] CSharpLanguage::_instance_binding_reference_callback(void*, void*, unsigned char) (in Godot) + 283
[5] RefCounted::unreference() (in Godot) + 206
[6] Input::get_default_cursor_shape() const
[7] Input::~Input() (in Godot) + 42
[8] Main::cleanup(bool) (in Godot) + 1079
[9] main (in Godot) + 320
[10] 10  dyld                                0x00007ff80c7b13a6 start + 1942
-- END OF BACKTRACE --
================================================================

I don't think the root issue has anything to with mouse cursors, audio, or styleboxes as in #92076 - they're merely triggering it. Also looks like it's in the macOS-specific code, & probably C# - specific.

I'm using JetBrains Rider, and it only crashes when closing the main window from there or the macOS native executable, not from the Godot editor.

@knightofiam
Copy link

knightofiam commented May 20, 2024

Probably not the root cause, but as far as I could get. According to this line in Viewport::_gui_input_event, it seems like the viewport tries to continue processing a mouse motion input event after ~Input() was called (i.e., during cleanup), leading to it attempting to get a reference to the default cursor shape after Input has already been freed.

@akien-mga
Copy link
Member

Tested on Linux with 4.2.2.stable.mono and 4.3.dev6.mono and couldn't reproduce, but all reports seem to point at a macOS specific issue. Given the number of reports/comments, I'll mark this as confirmed.

CC @godotengine/macos @godotengine/dotnet

@bruvzg
Copy link
Member

bruvzg commented May 21, 2024

I can reproduce it on macOS.

get_default_cursor_shape seems to be unrelated, in's out of place, so it's likely misidentified inline function.

The issue seems to be caused by Input::frame_parsed_events which is still holding InputEvents which were created by C# code and have C# instance free callback attached at the exit (seems like it's holding last event indefinitely). Issue should be reproducible only in debug builds, since this code is disabled in release.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment