godotengine / godot

Godot Engine – Multi-platform 2D and 3D game engine
https://godotengine.org
MIT License
91.35k stars 21.25k forks source link

[GDScript] Crash with Scripting Error #98665

Open Delsin-Yu opened 3 weeks ago

Delsin-Yu commented 3 weeks ago

Tested versions

v4.3.stable.official [77dcf97d8] v4.4.dev.custom_build [8004c7524] (master)

System information

Godot v4.4.dev (8004c7524) - Windows 10.0.17763 - Multi-window, 4 monitors - Vulkan (Forward+) - dedicated NVIDIA GeForce RTX 4060 Ti (NVIDIA; 32.0.15.6109) - AMD Ryzen 9 5900X 12-Core Processor (24 threads)

Issue description

A plugin I'm working on encountered this issue. I tried to repeat the MRP for several times and get a sets of different stack traces as follows:

The code snippets related to this issue:

# L822
func _find_texture_in_dir(source_tex : Texture2D, directory : EditorFileSystemDirectory, scan_result : Array[EditingAtlasTextureInfo]): 
# L823
    var file_count := directory.get_file_count();
# L824
    for i in range(file_count):
# L825
        var file_path := directory.get_file_path(i);
# L826
        var resource := ResourceLoader.load(file_path, "", ResourceLoader.CACHE_MODE_IGNORE);
# L827
        var atlas_candidate := resource as AtlasTexture;
# L828
        if atlas_candidate and atlas_candidate.atlas == source_tex:
# L829
            scan_result.append(EditingAtlasTextureInfo.create(atlas_candidate, file_path));

# L831
func _find_texture_in_dir_recursive(source_tex : Texture2D, directory : EditorFileSystemDirectory, scan_result : Array[EditingAtlasTextureInfo]):
# L832
    _find_texture_in_dir(source_tex, directory, scan_result);
# L833
    var sub_dir_count := directory.get_subdir_count();
# L834
    for i in range(sub_dir_count):
# L835
        var sub_dir := directory.get_subdir(i);
# L836
        _find_texture_in_dir_recursive(source_tex, sub_dir, scan_result);

Headers are the same:

Godot Engine v4.4.dev.custom_build.8004c7524 (2024-10-30 00:26:02 UTC) - https://godotengine.org
WARNING: GENERAL - Message Id Number: 0 | Message Id Name: Loader Message
        windows_read_data_files_in_registry: Registry lookup failed to get layer manifest files.
        Objects - 1
                Object[0] - VK_OBJECT_TYPE_INSTANCE, Handle 1937273426288
     at: RenderingContextDriverVulkan::_debug_messenger_callback (drivers\vulkan\rendering_context_driver_vulkan.cpp:639)
Vulkan 1.3.280 - Forward+ - Using Device #0: NVIDIA - NVIDIA GeForce RTX 4060 Ti

Tempt 1

``` SCRIPT ERROR: Bad address index. at: _update_inspecting_metrics (res://addons/AtlasTextureManager/atlastexture_manager.gd:826) SCRIPT ERROR: Internal script error! Opcode: 332 (please report). at: (res://addons/AtlasTextureManager/atlastexture_manager.gd:832) ================================================================ CrashHandlerException: Program crashed Engine version: Godot Engine v4.4.dev.custom_build (8004c7524fb9f43425c4d6f614410a76678e0f7c) Dumping the backtrace. Please include this when reporting the bug to the project developer. [0] Variant::clear (D:\godot\core\variant\variant.h:325) [1] Variant::clear (D:\godot\core\variant\variant.h:325) [2] Variant::~Variant (D:\godot\core\variant\variant.h:820) [3] Variant::`scalar deleting destructor' [4] GDScriptFunction::call (D:\godot\modules\gdscript\gdscript_vm.cpp:3889) [5] GDScriptInstance::callp (D:\godot\modules\gdscript\gdscript.cpp:2073) [6] Object::callp (D:\godot\core\object\object.cpp:791) [7] Variant::callp (D:\godot\core\variant\variant_call.cpp:1227) [8] GDScriptFunction::call (D:\godot\modules\gdscript\gdscript_vm.cpp:1924) [9] GDScriptInstance::callp (D:\godot\modules\gdscript\gdscript.cpp:2073) [10] Object::callp (D:\godot\core\object\object.cpp:791) [11] Variant::callp (D:\godot\core\variant\variant_call.cpp:1227) [12] GDScriptFunction::call (D:\godot\modules\gdscript\gdscript_vm.cpp:1924) [13] GDScriptInstance::callp (D:\godot\modules\gdscript\gdscript.cpp:2073) [14] Object::callp (D:\godot\core\object\object.cpp:791) [15] Variant::callp (D:\godot\core\variant\variant_call.cpp:1227) [16] GDScriptFunction::call (D:\godot\modules\gdscript\gdscript_vm.cpp:1924) [17] GDScriptLambdaSelfCallable::call (D:\godot\modules\gdscript\gdscript_lambda_callable.cpp:279) [18] Callable::callp (D:\godot\core\variant\callable.cpp:57) [19] _VariantCall::func_Callable_call (D:\godot\core\variant\variant_call.cpp:1039) [20] `_register_variant_builtin_methods_misc'::`2'::Method_Callable_call::call (D:\godot\core\variant\variant_call.cpp:2123) [21] Variant::callp (D:\godot\core\variant\variant_call.cpp:1239) [22] GDScriptFunction::call (D:\godot\modules\gdscript\gdscript_vm.cpp:1924) [23] GDScriptLambdaCallable::call (D:\godot\modules\gdscript\gdscript_lambda_callable.cpp:118) [24] Callable::callp (D:\godot\core\variant\callable.cpp:57) [25] Object::emit_signalp (D:\godot\core\object\object.cpp:1201) [26] Node::emit_signalp (D:\godot\scene\main\node.cpp:3975) [27] Object::emit_signal<> (D:\godot\core\object\object.h:920) [28] BaseButton::_pressed (D:\godot\scene\gui\base_button.cpp:138) [29] BaseButton::on_action_event (D:\godot\scene\gui\base_button.cpp:174) [30] BaseButton::gui_input (D:\godot\scene\gui\base_button.cpp:69) [31] Control::_call_gui_input (D:\godot\scene\gui\control.cpp:1823) [32] Viewport::_gui_call_input (D:\godot\scene\main\viewport.cpp:1573) [33] Viewport::_gui_input_event (D:\godot\scene\main\viewport.cpp:1837) [34] Viewport::push_input (D:\godot\scene\main\viewport.cpp:3176) [35] Window::_window_input (D:\godot\scene\main\window.cpp:1680) [36] call_with_variant_args_helper const &,0> (D:\godot\core\variant\binder_common.h:304) [37] call_with_variant_args const &> (D:\godot\core\variant\binder_common.h:418) [38] CallableCustomMethodPointer const &>::call (D:\godot\core\object\callable_method_pointer.h:107) [39] Callable::callp (D:\godot\core\variant\callable.cpp:57) [40] Callable::call > (D:\godot\core\variant\variant.h:906) [41] DisplayServerWindows::_dispatch_input_event (D:\godot\platform\windows\display_server_windows.cpp:3784) [42] DisplayServerWindows::_dispatch_input_events (D:\godot\platform\windows\display_server_windows.cpp:3754) [43] Input::_parse_input_event_impl (D:\godot\core\input\input.cpp:805) [44] Input::flush_buffered_events (D:\godot\core\input\input.cpp:1086) [45] DisplayServerWindows::process_events (D:\godot\platform\windows\display_server_windows.cpp:3234) [46] OS_Windows::run (D:\godot\platform\windows\os_windows.cpp:1771) [47] widechar_main (D:\godot\platform\windows\godot_windows.cpp:180) [48] _main (D:\godot\platform\windows\godot_windows.cpp:206) [49] main (D:\godot\platform\windows\godot_windows.cpp:220) [50] WinMain (D:\godot\platform\windows\godot_windows.cpp:234) [51] __scrt_common_main_seh (D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:288) [52] -- END OF BACKTRACE -- ================================================================ ```

Tempt 2

``` SCRIPT ERROR: Invalid assignment of property or key 'text' with value of type 'CompressedTexture2D' on a base object of type 'EditorFileSystemDirectory'. at: _label (res://addons/AtlasTextureManager/atlastexture_manager.gd:749) ================================================================ CrashHandlerException: Program crashed Engine version: Godot Engine v4.4.dev.custom_build (8004c7524fb9f43425c4d6f614410a76678e0f7c) Dumping the backtrace. Please include this when reporting the bug to the project developer. [0] Variant::clear (D:\godot\core\variant\variant.h:325) [1] Variant::~Variant (D:\godot\core\variant\variant.h:820) [2] Variant::`scalar deleting destructor' [3] GDScriptFunction::call (D:\godot\modules\gdscript\gdscript_vm.cpp:3889) [4] GDScriptLambdaSelfCallable::call (D:\godot\modules\gdscript\gdscript_lambda_callable.cpp:279) [5] Callable::callp (D:\godot\core\variant\callable.cpp:57) [6] _VariantCall::func_Callable_call (D:\godot\core\variant\variant_call.cpp:1039) [7] `_register_variant_builtin_methods_misc'::`2'::Method_Callable_call::call (D:\godot\core\variant\variant_call.cpp:2123) [8] Variant::callp (D:\godot\core\variant\variant_call.cpp:1239) [9] GDScriptFunction::call (D:\godot\modules\gdscript\gdscript_vm.cpp:1924) [10] GDScriptLambdaCallable::call (D:\godot\modules\gdscript\gdscript_lambda_callable.cpp:118) [11] Callable::callp (D:\godot\core\variant\callable.cpp:57) [12] Object::emit_signalp (D:\godot\core\object\object.cpp:1201) [13] Node::emit_signalp (D:\godot\scene\main\node.cpp:3975) [14] Object::emit_signal<> (D:\godot\core\object\object.h:920) [15] BaseButton::_pressed (D:\godot\scene\gui\base_button.cpp:138) [16] BaseButton::on_action_event (D:\godot\scene\gui\base_button.cpp:174) [17] BaseButton::gui_input (D:\godot\scene\gui\base_button.cpp:69) [18] Control::_call_gui_input (D:\godot\scene\gui\control.cpp:1823) [19] Viewport::_gui_call_input (D:\godot\scene\main\viewport.cpp:1573) [20] Viewport::_gui_input_event (D:\godot\scene\main\viewport.cpp:1837) [21] Viewport::push_input (D:\godot\scene\main\viewport.cpp:3176) [22] Window::_window_input (D:\godot\scene\main\window.cpp:1680) [23] call_with_variant_args_helper const &,0> (D:\godot\core\variant\binder_common.h:304) [24] call_with_variant_args const &> (D:\godot\core\variant\binder_common.h:418) [25] CallableCustomMethodPointer const &>::call (D:\godot\core\object\callable_method_pointer.h:107) [26] Callable::callp (D:\godot\core\variant\callable.cpp:57) [27] Callable::call > (D:\godot\core\variant\variant.h:906) [28] DisplayServerWindows::_dispatch_input_event (D:\godot\platform\windows\display_server_windows.cpp:3784) [29] DisplayServerWindows::_dispatch_input_events (D:\godot\platform\windows\display_server_windows.cpp:3754) [30] Input::_parse_input_event_impl (D:\godot\core\input\input.cpp:805) [31] Input::flush_buffered_events (D:\godot\core\input\input.cpp:1086) [32] DisplayServerWindows::process_events (D:\godot\platform\windows\display_server_windows.cpp:3234) [33] OS_Windows::run (D:\godot\platform\windows\os_windows.cpp:1771) [34] widechar_main (D:\godot\platform\windows\godot_windows.cpp:180) [35] _main (D:\godot\platform\windows\godot_windows.cpp:206) [36] main (D:\godot\platform\windows\godot_windows.cpp:220) [37] WinMain (D:\godot\platform\windows\godot_windows.cpp:234) [38] __scrt_common_main_seh (D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:288) [39] -- END OF BACKTRACE -- ================================================================ ```

Tempt 3

``` SCRIPT ERROR: Invalid access to property or key 'margin' on a base object of type 'Nil'. at: (res://addons/AtlasTextureManager/atlastexture_manager.gd:510) SCRIPT ERROR: Bad address index. at: _zoom_button (res://addons/AtlasTextureManager/atlastexture_manager.gd:74) ================================================================ CrashHandlerException: Program crashed Engine version: Godot Engine v4.4.dev.custom_build (8004c7524fb9f43425c4d6f614410a76678e0f7c) Dumping the backtrace. Please include this when reporting the bug to the project developer. [0] Variant::clear (D:\godot\core\variant\variant.h:325) [1] Variant::clear (D:\godot\core\variant\variant.h:325) [2] Variant::~Variant (D:\godot\core\variant\variant.h:820) [3] Variant::`scalar deleting destructor' [4] GDScriptFunction::call (D:\godot\modules\gdscript\gdscript_vm.cpp:3889) [5] GDScriptLambdaCallable::call (D:\godot\modules\gdscript\gdscript_lambda_callable.cpp:118) [6] Callable::callp (D:\godot\core\variant\callable.cpp:57) [7] Object::emit_signalp (D:\godot\core\object\object.cpp:1201) [8] Node::emit_signalp (D:\godot\scene\main\node.cpp:3975) [9] Object::emit_signal<> (D:\godot\core\object\object.h:920) [10] BaseButton::_pressed (D:\godot\scene\gui\base_button.cpp:138) [11] BaseButton::on_action_event (D:\godot\scene\gui\base_button.cpp:174) [12] BaseButton::gui_input (D:\godot\scene\gui\base_button.cpp:69) [13] Control::_call_gui_input (D:\godot\scene\gui\control.cpp:1823) [14] Viewport::_gui_call_input (D:\godot\scene\main\viewport.cpp:1573) [15] Viewport::_gui_input_event (D:\godot\scene\main\viewport.cpp:1837) [16] Viewport::push_input (D:\godot\scene\main\viewport.cpp:3176) [17] Window::_window_input (D:\godot\scene\main\window.cpp:1680) [18] call_with_variant_args_helper const &,0> (D:\godot\core\variant\binder_common.h:304) [19] call_with_variant_args const &> (D:\godot\core\variant\binder_common.h:418) [20] CallableCustomMethodPointer const &>::call (D:\godot\core\object\callable_method_pointer.h:107) [21] Callable::callp (D:\godot\core\variant\callable.cpp:57) [22] Callable::call > (D:\godot\core\variant\variant.h:906) [23] DisplayServerWindows::_dispatch_input_event (D:\godot\platform\windows\display_server_windows.cpp:3784) [24] DisplayServerWindows::_dispatch_input_events (D:\godot\platform\windows\display_server_windows.cpp:3754) [25] Input::_parse_input_event_impl (D:\godot\core\input\input.cpp:805) [26] Input::flush_buffered_events (D:\godot\core\input\input.cpp:1086) [27] DisplayServerWindows::process_events (D:\godot\platform\windows\display_server_windows.cpp:3234) [28] OS_Windows::run (D:\godot\platform\windows\os_windows.cpp:1771) [29] widechar_main (D:\godot\platform\windows\godot_windows.cpp:180) [30] _main (D:\godot\platform\windows\godot_windows.cpp:206) [31] main (D:\godot\platform\windows\godot_windows.cpp:220) [32] WinMain (D:\godot\platform\windows\godot_windows.cpp:234) [33] __scrt_common_main_seh (D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:288) [34] -- END OF BACKTRACE -- ================================================================ ```

Tempt 4

``` ERROR: Condition ' !nc ' is true. Breaking..: at: GDScriptFunction::call (modules\gdscript\gdscript_vm.cpp:1623) SCRIPT ERROR: Internal script error! Opcode: 31 (please report). at: (res://addons/AtlasTextureManager/atlastexture_manager.gd:827) ================================================================ CrashHandlerException: Program crashed Engine version: Godot Engine v4.4.dev.custom_build (8004c7524fb9f43425c4d6f614410a76678e0f7c) Dumping the backtrace. Please include this when reporting the bug to the project developer. [0] GDScriptFunction::call (D:\godot\modules\gdscript\gdscript_vm.cpp:2250) [1] GDScriptInstance::callp (D:\godot\modules\gdscript\gdscript.cpp:2073) [2] Object::callp (D:\godot\core\object\object.cpp:791) [3] Variant::callp (D:\godot\core\variant\variant_call.cpp:1227) [4] GDScriptFunction::call (D:\godot\modules\gdscript\gdscript_vm.cpp:1924) [5] GDScriptInstance::callp (D:\godot\modules\gdscript\gdscript.cpp:2073) [6] Object::callp (D:\godot\core\object\object.cpp:791) [7] Variant::callp (D:\godot\core\variant\variant_call.cpp:1227) [8] GDScriptFunction::call (D:\godot\modules\gdscript\gdscript_vm.cpp:1924) [9] GDScriptInstance::callp (D:\godot\modules\gdscript\gdscript.cpp:2073) [10] Object::callp (D:\godot\core\object\object.cpp:791) [11] Variant::callp (D:\godot\core\variant\variant_call.cpp:1227) [12] GDScriptFunction::call (D:\godot\modules\gdscript\gdscript_vm.cpp:1924) [13] GDScriptLambdaSelfCallable::call (D:\godot\modules\gdscript\gdscript_lambda_callable.cpp:279) [14] Callable::callp (D:\godot\core\variant\callable.cpp:57) [15] _VariantCall::func_Callable_call (D:\godot\core\variant\variant_call.cpp:1039) [16] `_register_variant_builtin_methods_misc'::`2'::Method_Callable_call::call (D:\godot\core\variant\variant_call.cpp:2123) [17] Variant::callp (D:\godot\core\variant\variant_call.cpp:1239) [18] GDScriptFunction::call (D:\godot\modules\gdscript\gdscript_vm.cpp:1924) [19] GDScriptLambdaCallable::call (D:\godot\modules\gdscript\gdscript_lambda_callable.cpp:118) [20] Callable::callp (D:\godot\core\variant\callable.cpp:57) [21] Object::emit_signalp (D:\godot\core\object\object.cpp:1201) [22] Node::emit_signalp (D:\godot\scene\main\node.cpp:3975) [23] Object::emit_signal<> (D:\godot\core\object\object.h:920) [24] BaseButton::_pressed (D:\godot\scene\gui\base_button.cpp:138) [25] BaseButton::on_action_event (D:\godot\scene\gui\base_button.cpp:174) [26] BaseButton::gui_input (D:\godot\scene\gui\base_button.cpp:69) [27] Control::_call_gui_input (D:\godot\scene\gui\control.cpp:1823) [28] Viewport::_gui_call_input (D:\godot\scene\main\viewport.cpp:1573) [29] Viewport::_gui_input_event (D:\godot\scene\main\viewport.cpp:1837) [30] Viewport::push_input (D:\godot\scene\main\viewport.cpp:3176) [31] Window::_window_input (D:\godot\scene\main\window.cpp:1680) [32] call_with_variant_args_helper const &,0> (D:\godot\core\variant\binder_common.h:304) [33] call_with_variant_args const &> (D:\godot\core\variant\binder_common.h:418) [34] CallableCustomMethodPointer const &>::call (D:\godot\core\object\callable_method_pointer.h:107) [35] Callable::callp (D:\godot\core\variant\callable.cpp:57) [36] Callable::call > (D:\godot\core\variant\variant.h:906) [37] DisplayServerWindows::_dispatch_input_event (D:\godot\platform\windows\display_server_windows.cpp:3784) [38] DisplayServerWindows::_dispatch_input_events (D:\godot\platform\windows\display_server_windows.cpp:3754) [39] Input::_parse_input_event_impl (D:\godot\core\input\input.cpp:805) [40] Input::flush_buffered_events (D:\godot\core\input\input.cpp:1086) [41] DisplayServerWindows::process_events (D:\godot\platform\windows\display_server_windows.cpp:3234) [42] OS_Windows::run (D:\godot\platform\windows\os_windows.cpp:1771) [43] widechar_main (D:\godot\platform\windows\godot_windows.cpp:180) [44] _main (D:\godot\platform\windows\godot_windows.cpp:206) [45] main (D:\godot\platform\windows\godot_windows.cpp:220) [46] WinMain (D:\godot\platform\windows\godot_windows.cpp:234) [47] __scrt_common_main_seh (D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:288) [48] -- END OF BACKTRACE -- ================================================================ ```

Steps to reproduce

  1. Download the MRP and open it with one of the tested versions.
  2. switch to the AtlasTextue Manager window at the top left dock.
  3. Double-click the icon.svg image asset in the FileSystem window.
  4. Click the Scan in Project button in the AtlasTextue Manager window.

https://github.com/user-attachments/assets/ab24c711-5d91-48d2-88bd-8ea74ba2734a

Minimal reproduction project (MRP)

MRP-GDScript-Crash.zip

timothyqiu commented 3 weeks ago

When the button is pressed, ResourceLoader.load(file_path, "", ResourceLoader.CACHE_MODE_IGNORE) is called for every file in the project. This results in force reloading of the script of your addon itself. This makes later logic heap-reuse-after-free.

You can use ResourceLoader.get_recognized_extensions_for_type("AtlasTexture") to get a list of extensions to filter out the correct resource files.

Delsin-Yu commented 3 weeks ago

I see. Should precautions be taken to prevent such use cases from crashing the engine?

timothyqiu commented 3 weeks ago

Made a MRP that crashes the game instead of the editor: test-4.zip

Delsin-Yu commented 3 weeks ago

In short:

res://demo.gd:

extends Control
func _on_button_pressed() -> void:
    var res := ResourceLoader.load("res://demo.gd", "", ResourceLoader.CACHE_MODE_IGNORE)
    print(self)
    print(res)
aekobear commented 2 weeks ago

I stumbled across this problem today and when trying to find a work-around, noticed that this also causes an editor crash:

func hot_reload():
  get_script().reload(true)

Could the root cause be the same?

Delsin-Yu commented 2 weeks ago

@aekobear I guess so, since conceptually, they are doing the same thing in the end, but we might need someone familiar with the ResourceLoader::load and GDScript::reload to confirm.