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

Freed autoload object causes debugger to crash without a meaningful error message (GDScript) #92607

Closed
cyanglaz opened this issue May 31, 2024 · 2 comments · Fixed by #89274
Closed

Comments

@cyanglaz
Copy link

cyanglaz commented May 31, 2024

Tested versions

Reproducible in 4.0.x, .4.1.x, 4.2.x, 4.3.x.

System information

Godot 4.2.2 - Windows 11 Vulkan Forward+, Godot 4.2.2 - MacOS 14.5 Vulkan Forward+. With GDSCript as language

Issue description

When an autoload object is freed, the debugger will crash without any meaningful error message.
I have only observed the issue using GDScript and have not validated it in other languages.
The root cause is a forced cast happened here:https://github.com/godotengine/godot/blob/master/modules/gdscript/gdscript_editor.cpp#L406
When obj is invalid, the cast will cause a crash.

Crash log (commit hash: 705b7a0):

[1] 1   libsystem_platform.dylib            0x000000018d13f584 _sigtramp + 56
[2] 2   libc++abi.dylib                     0x000000018d0c67b0 __dynamic_cast + 56
[3] GDScriptLanguage::debug_get_globals(List<String, DefaultAllocator>*, List<Variant, DefaultAllocator>*, int, int) (in godot.macos.editor.dev.arm64) (gdscript_editor.cpp:406)
[4] RemoteDebugger::debug(bool, bool) (in godot.macos.editor.dev.arm64) (remote_debugger.cpp:505)
[5] ScriptDebugger::debug(ScriptLanguage*, bool, bool) (in godot.macos.editor.dev.arm64) (script_debugger.cpp:85)
[6] GDScriptLanguage::debug_break(String const&, bool) (in godot.macos.editor.dev.arm64) (gdscript_editor.cpp:270)
[7] GDScriptFunction::call(GDScriptInstance*, Variant const**, int, Callable::CallError&, GDScriptFunction::CallState*) (in godot.macos.editor.dev.arm64) (gdscript_vm.cpp:3599)
[8] GDScriptFunctionState::resume(Variant const&) (in godot.macos.editor.dev.arm64) (gdscript_function.cpp:216)
[9] GDScriptFunctionState::_signal_callback(Variant const**, int, Callable::CallError&) (in godot.macos.editor.dev.arm64) (gdscript_function.cpp:166)
[10] MethodBindVarArgTR<GDScriptFunctionState, Variant>::call(Object*, Variant const**, int, Callable::CallError&) const (in godot.macos.editor.dev.arm64) (method_bind.h:271)
[11] Object::callp(StringName const&, Variant const**, int, Callable::CallError&) (in godot.macos.editor.dev.arm64) (object.cpp:841)
[12] Callable::callp(Variant const**, int, Variant&, Callable::CallError&) const (in godot.macos.editor.dev.arm64) (callable.cpp:69)
[13] CallableCustomBind::call(Variant const**, int, Variant&, Callable::CallError&) const (in godot.macos.editor.dev.arm64) (callable_bind.cpp:153)
[14] Callable::callp(Variant const**, int, Variant&, Callable::CallError&) const (in godot.macos.editor.dev.arm64) (callable.cpp:58)
[15] Object::emit_signalp(StringName const&, Variant const**, int) (in godot.macos.editor.dev.arm64) (object.cpp:1219)
[16] Error Object::emit_signal<>(StringName const&) (in godot.macos.editor.dev.arm64) (object.h:936)
[17] SceneTree::process_timers(double, bool) (in godot.macos.editor.dev.arm64) (scene_tree.cpp:599)
[18] SceneTree::process(double) (in godot.macos.editor.dev.arm64) (scene_tree.cpp:538)
[19] Main::iteration() (in godot.macos.editor.dev.arm64) (main.cpp:4075)
[20] OS_MacOS::run() (in godot.macos.editor.dev.arm64) (os_macos.mm:778)
[21] main (in godot.macos.editor.dev.arm64) (godot_main_macos.mm:84)
[22] 22  dyld                                0x000000018cd860e0 start + 2360
-- END OF BACKTRACE --

Steps to reproduce

##Use MRP##

  1. Open the project.
  2. Open res://game_node.gd
  3. Put a break point at the line: func _ready() -> print("after 1 second")
  4. Run the scene res://game_node.tscn
  5. Wait for the debugger to stop
  6. Observe that the Filter Stack Variables show nothing.
  7. Wait for some time, see the debugger crashed.

Without MRP

  1. Create an autoload object, add queue_free() in its _ready() function
  2. Put a breakpoint at any place in the game (at least after Autoloads are loaded)
  3. Start the game.
  4. Wait for the debugger to stop
  5. Observe that the Filter Stack Variables show nothing.
  6. Wait for some time, see the debugger crashed.

Minimal reproduction project (MRP)

autoloadqueuefree copy.zip

@cyanglaz
Copy link
Author

I created a potential fix here: #92608

@dalexeev dalexeev added this to the 4.3 milestone Jun 1, 2024
@github-project-automation github-project-automation bot moved this to For team assessment in GDScript Issue Triage Jun 4, 2024
@dalexeev dalexeev moved this from For team assessment to Fix pending review in GDScript Issue Triage Jun 4, 2024
@KoBeWi KoBeWi removed this from the 4.3 milestone Jul 30, 2024
@dalexeev
Copy link
Member

dalexeev commented Aug 8, 2024

@dalexeev dalexeev closed this as completed Aug 8, 2024
@github-project-automation github-project-automation bot moved this from Fix pending review to Done in GDScript Issue Triage Aug 8, 2024
@AThousandShips AThousandShips added this to the 4.3 milestone Aug 8, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment