godotengine / godot

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

VisualScript crashes when reconnecting _physics and _process_physics nodes delta to Construct Vector3 #60041

Open trupljan opened 2 years ago

trupljan commented 2 years ago

Godot version

Godot_v3.4.4-stable_x11.64

System information

Linux, Ubuntu 20.04 LTS, NVIDIA GTX 1650 Super, GLES3

Issue description

I have tried VisualScript for first time to check if it is any useful, and I found several ways to crash it during my fooling around. This is one of the bugs I found. When I create a visual script for 3D box and override both _physics and _process_physics methods, then connect delta from _processPhysics to Construct Vector3's x (or other coordinate) and then try to connect _physics delta to the same box, it crashes the editor.

ERROR: A function node has already been set here.
   at: add_node (modules/visual_script/visual_script.cpp:307)
ERROR: Condition "!func.nodes.has(p_id)" is true. Returned: Ref<VisualScriptNode>()
   at: get_node (modules/visual_script/visual_script.cpp:381)

handle_crash: Program crashed with signal 11
Engine version: Godot Engine v3.4.4.stable.official (419e713a29f20bd3351a54d1e6c4c5af7ef4b253)
Dumping the backtrace. Please include this when reporting the bug on https://github.com/godotengine/godot/issues
[1] /lib/x86_64-linux-gnu/libc.so.6(+0x430c0) [0x7fb4492140c0] (??:0)
[2] /home/tester/godot/Godot_v3.4.4-stable_x11.64() [0xbe31e7] (??:0)
[3] /home/tester/godot/Godot_v3.4.4-stable_x11.64() [0xc00238] (??:0)
[4] /home/tester/godot/Godot_v3.4.4-stable_x11.64() [0xa03931] (??:0)
[5] /home/tester/godot/Godot_v3.4.4-stable_x11.64() [0x2b77c39] (??:0)
[6] /home/tester/godot/Godot_v3.4.4-stable_x11.64() [0x2ba7988] (??:0)
[7] /home/tester/godot/Godot_v3.4.4-stable_x11.64() [0x2babd9f] (??:0)
[8] /home/tester/godot/Godot_v3.4.4-stable_x11.64() [0x2bac010] (??:0)
[9] /home/tester/godot/Godot_v3.4.4-stable_x11.64() [0xc3ebbb] (??:0)
[10] /home/tester/godot/Godot_v3.4.4-stable_x11.64() [0xc12fbb] (??:0)
[11] /home/tester/godot/Godot_v3.4.4-stable_x11.64() [0x2b77c39] (??:0)
[12] /home/tester/godot/Godot_v3.4.4-stable_x11.64() [0x2b7802d] (??:0)
[13] /home/tester/godot/Godot_v3.4.4-stable_x11.64() [0x2b78d0c] (??:0)
[14] /home/tester/godot/Godot_v3.4.4-stable_x11.64() [0x1e56680] (??:0)
[15] /home/tester/godot/Godot_v3.4.4-stable_x11.64() [0xc62695] (??:0)
[16] /home/tester/godot/Godot_v3.4.4-stable_x11.64() [0x2b77c39] (??:0)
[17] /home/tester/godot/Godot_v3.4.4-stable_x11.64() [0x2b7802d] (??:0)
[18] /home/tester/godot/Godot_v3.4.4-stable_x11.64() [0x1dabbf3] (??:0)
[19] /home/tester/godot/Godot_v3.4.4-stable_x11.64() [0x1dbe081] (??:0)
[20] /home/tester/godot/Godot_v3.4.4-stable_x11.64() [0x1dc0225] (??:0)
[21] /home/tester/godot/Godot_v3.4.4-stable_x11.64() [0x1dc038b] (??:0)
[22] /home/tester/godot/Godot_v3.4.4-stable_x11.64() [0xc62695] (??:0)
[23] /home/tester/godot/Godot_v3.4.4-stable_x11.64() [0x2b77c39] (??:0)
[24] /home/tester/godot/Godot_v3.4.4-stable_x11.64() [0x2b6ab94] (??:0)
[25] /home/tester/godot/Godot_v3.4.4-stable_x11.64() [0x1d967ed] (??:0)
[26] /home/tester/godot/Godot_v3.4.4-stable_x11.64() [0x1da81d9] (??:0)
[27] /home/tester/godot/Godot_v3.4.4-stable_x11.64() [0x98029b] (??:0)
[28] /home/tester/godot/Godot_v3.4.4-stable_x11.64() [0x9814a9] (??:0)
[29] /home/tester/godot/Godot_v3.4.4-stable_x11.64() [0x98a922] (??:0)
[30] /home/tester/godot/Godot_v3.4.4-stable_x11.64() [0x94719c] (??:0)
[31] /lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xf3) [0x7fb4491f50b3] (??:0)
[32] /home/tester/godot/Godot_v3.4.4-stable_x11.64() [0x95ae1e] (??:0)
-- END OF BACKTRACE --

Steps to reproduce

  1. Create new project (OpenGL ES 3.0)
  2. Click 3D Scene to create Spatial node
  3. Add CSGBox as a child to Spatial node
  4. Attach new VisualScript CSGBox.vs to the box
  5. In visual editor click on Functions: override an existing built-in function
  6. Choose Physics Process(float)
  7. Click again on on Functions: override an existing built-in function
  8. Choose Process(float)
  9. Right click on the plane and search for: Construct Vector 3XYZ and add it
  10. Move with nodes around a bit (probably not important, but I did it during reproduction)
  11. Connect _physics_process delta with x of Construct Vector3
  12. Connect _process delta with x of Construct Vector3 (it should replace existing connection, might connect to y,z too...)
  13. Crash!

Minimal reproduction project

No response

Calinou commented 2 years ago

@trupljan Can you try to get a full backtrace by running a debug build from a terminal? This will tell you where the issue comes from. (Backtraces produced by official builds are not useful since they don't contain debug symbols.)

trupljan commented 2 years ago

There it is:

Godot Engine v3.4.4.stable.custom_build.419e713a2 - https://godotengine.org
OpenGL ES 3.0 Renderer: NVIDIA GeForce GTX 1650 SUPER/PCIe/SSE2
OpenGL ES Batching: ON
/lib/x86_64-linux-gnu/libasound.so.2: undefined symbol: snd_dlpath

ERROR: A function node has already been set here.
   at: add_node (modules/visual_script/visual_script.cpp:307)
ERROR: Condition "!func.nodes.has(p_id)" is true. Returned: Ref<VisualScriptNode>()
   at: get_node (modules/visual_script/visual_script.cpp:381)

================================================================
handle_crash: Program crashed with signal 11
Engine version: Godot Engine v3.4.4.stable.custom_build (419e713a29f20bd3351a54d1e6c4c5af7ef4b253)
Dumping the backtrace. Please include this when reporting the bug on https://github.com/godotengine/godot/issues
[1] /lib/x86_64-linux-gnu/libc.so.6(+0x430c0) [0x7f1ccc4990c0] (??:0)
[2] VisualScriptEditor::_update_graph_connections() (/opt/godot-3.4.4-stable/modules/visual_script/visual_script_editor.cpp:561)
[3] VisualScriptEditor::_update_graph(int) (/opt/godot-3.4.4-stable/modules/visual_script/visual_script_editor.cpp:961)
[4] MethodBind1<int>::call(Object*, Variant const**, int, Variant::CallError&) (/opt/godot-3.4.4-stable/./core/method_bind.gen.inc:775 (discriminator 12))
[5] Object::call(StringName const&, Variant const**, int, Variant::CallError&) (/opt/godot-3.4.4-stable/core/object.cpp:918 (discriminator 1))
[6] UndoRedo::_process_operation_list(List<UndoRedo::Operation, DefaultAllocator>::Element*) (/opt/godot-3.4.4-stable/core/undo_redo.cpp:283 (discriminator 4))
[7] UndoRedo::redo() (/opt/godot-3.4.4-stable/core/undo_redo.cpp:328)
[8] UndoRedo::commit_action() (/opt/godot-3.4.4-stable/core/undo_redo.cpp:252)
[9] VisualScriptEditor::_graph_connected(String const&, int, String const&, int) (/opt/godot-3.4.4-stable/modules/visual_script/visual_script_editor.cpp:3053 (discriminator 2))
[10] MethodBind4<String const&, int, String const&, int>::call(Object*, Variant const**, int, Variant::CallError&) (/opt/godot-3.4.4-stable/./core/method_bind.gen.inc:3115 (discriminator 33))
[11] Object::call(StringName const&, Variant const**, int, Variant::CallError&) (/opt/godot-3.4.4-stable/core/object.cpp:918 (discriminator 1))
[12] Object::emit_signal(StringName const&, Variant const**, int) (/opt/godot-3.4.4-stable/core/object.cpp:1224 (discriminator 1))
[13] Object::emit_signal(StringName const&, Variant const&, Variant const&, Variant const&, Variant const&, Variant const&) (/opt/godot-3.4.4-stable/core/object.cpp:1280)
[14] GraphEdit::_top_layer_input(Ref<InputEvent> const&) (/opt/godot-3.4.4-stable/scene/gui/graph_edit.cpp:710 (discriminator 10))
[15] MethodBind1<Ref<InputEvent> const&>::call(Object*, Variant const**, int, Variant::CallError&) (/opt/godot-3.4.4-stable/./core/method_bind.gen.inc:775 (discriminator 12))
[16] Object::call(StringName const&, Variant const**, int, Variant::CallError&) (/opt/godot-3.4.4-stable/core/object.cpp:918 (discriminator 1))
[17] Object::emit_signal(StringName const&, Variant const**, int) (/opt/godot-3.4.4-stable/core/object.cpp:1224 (discriminator 1))
[18] Object::emit_signal(StringName const&, Variant const&, Variant const&, Variant const&, Variant const&, Variant const&) (/opt/godot-3.4.4-stable/core/object.cpp:1280)
[19] Viewport::_gui_call_input(Control*, Ref<InputEvent> const&) (/opt/godot-3.4.4-stable/scene/main/viewport.cpp:1634 (discriminator 2))
[20] Viewport::_gui_input_event(Ref<InputEvent>) (/opt/godot-3.4.4-stable/scene/main/viewport.cpp:2030 (discriminator 3))
[21] Viewport::input(Ref<InputEvent> const&) (/opt/godot-3.4.4-stable/scene/main/viewport.cpp:2830 (discriminator 2))
[22] Viewport::_vp_input(Ref<InputEvent> const&) (/opt/godot-3.4.4-stable/scene/main/viewport.cpp:1409)
[23] MethodBind1<Ref<InputEvent> const&>::call(Object*, Variant const**, int, Variant::CallError&) (/opt/godot-3.4.4-stable/./core/method_bind.gen.inc:775 (discriminator 12))
[24] Object::call(StringName const&, Variant const**, int, Variant::CallError&) (/opt/godot-3.4.4-stable/core/object.cpp:918 (discriminator 1))
[25] Object::call(StringName const&, Variant const&, Variant const&, Variant const&, Variant const&, Variant const&) (/opt/godot-3.4.4-stable/core/object.cpp:848)
[26] SceneTree::call_group_flags(unsigned int, StringName const&, StringName const&, Variant const&, Variant const&, Variant const&, Variant const&, Variant const&) (/opt/godot-3.4.4-stable/scene/main/scene_tree.cpp:280)
[27] SceneTree::input_event(Ref<InputEvent> const&) (/opt/godot-3.4.4-stable/scene/main/scene_tree.cpp:439 (discriminator 6))
[28] InputDefault::_parse_input_event_impl(Ref<InputEvent> const&, bool) (/opt/godot-3.4.4-stable/main/input_default.cpp:462)
[29] InputDefault::flush_buffered_events() (/opt/godot-3.4.4-stable/main/input_default.cpp:711)
[30] OS_X11::process_xevents() (/opt/godot-3.4.4-stable/platform/x11/os_x11.cpp:2356)
[31] OS_X11::run() (/opt/godot-3.4.4-stable/platform/x11/os_x11.cpp:3641)
[32] ../build/godot-3.4.4-stable/bin/godot.x11.tools.64(main+0x125) [0x179e50b] (/opt/godot-3.4.4-stable/platform/x11/godot_x11.cpp:57)
[33] /lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xf3) [0x7f1ccc47a0b3] (??:0)
[34] ../build/godot-3.4.4-stable/bin/godot.x11.tools.64(_start+0x2e) [0x179e32e] (??:?)
-- END OF BACKTRACE --
================================================================
trupljan commented 2 years ago

How to recompile only changed modules? When I change one line in visual_script_editor.cpp and run "scons platform=x11 -j$(nproc) debug_symbols=yes progress=no" the damn think recompile whole engine, but the object files are already there and I want only to recompile the changes in one file and link the executable again.

EDIT: scons platform=x11 -j$(nproc) debug_symbols=yes progress=yes fast_unsafe=yes

Calinou commented 2 years ago

EDIT: scons platform=x11 -j$(nproc) debug_symbols=yes progress=yes fast_unsafe=yes

Quoting #57806, this is already the default for target=debug builds (which are the default):

These options are enabled automatically for debug builds, unless fast_unsafe=no is passed. They are disabled by default for release and release_debug builds, unless fast_unsafe=yes is passed.

trupljan commented 2 years ago

OK, but I feel it was faster with it being explicitly set. Maybe it was because of progress=yes. Have no experience with scons. Anyway, I now understand the problem what happened as I replicated it with functions created by clicking + in functions. Functions cannot share bodies. I basically could not decide wheter I want to update box position in _process or _process_physics when checking this visual script, so I put both nodes to screen. But it is actually defining functions and by connecting two function "headers" to same operation, it would share function "body". What I would expect is to either share the body, as it is just a signal passing through a graph, or disconnect the other function. Or maybe it should not allow the connection at all. What technically happens is that variable to_node is nullptr in VisualScriptEditor::_update_graph_connections and therefore it crashes, but adding a check and preventing from_port and connect_node update leads to weird behaviour in editor like function nodes disappearing. There is some deeper logical problem related to undo and redo functionality, as some node does not exists when they should(?). I checked the code but it is too difficult for me to fix it. And it is not that important also, I was just curious if I could fix it ;)