godotengine / godot

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

Crash when inserting array properties (not elements) in Inspector #60842

Closed Rindbee closed 2 years ago

Rindbee commented 2 years ago

Godot version

v4.0.alpha.custom_build [bb73dafe3]

System information

Linux Mint 20.3, Vulkan, NVIDIA GeForce GTX 1050 Ti

Issue description

It is unsafe to perform consecutive insert operations with "Insert New Before/After" on array properties (not array elements) in the Inspector.

Relevant properties (properties added with ADD_ARRAY/ADD_ARRAY_COUNT):

  1. TileMap::layers
  2. ItemList::Items
  3. MenuButton::Items
  4. OptionButton::Items
  5. TabBar::Tabs
  6. BoneMap::bonemap
  7. Curve::Points/Curve2D::Points/Curve3D::Points
  8. TileSet::occlusion_layers/physics_layers/terrain_sets/navigation_layers/custom_data_layers
  9. AudioStreamRandomizer::streams
================================================================
handle_crash: Program crashed with signal 11
Engine version: Godot Engine v4.0.alpha.custom_build (bb73dafe377471abcd6661a54e8bf0a2091ac4f2)
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) [0x7f7d3de8b0c0] (??:0)
[2] /lib/x86_64-linux-gnu/libpthread.so.0(pthread_mutex_lock+0x4) [0x7f7d3e19bfc4] (??:0)
[3] /home/bee/code/godot/godot/bin/godot.linuxbsd.opt.tools.64.llvm() [0x44a33e4] (/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/mutex:109)
[4] /home/bee/code/godot/godot/bin/godot.linuxbsd.opt.tools.64.llvm() [0x44c316c] (/home/bee/code/godot/godot/scene/main/viewport.cpp:1152)
[5] /home/bee/code/godot/godot/bin/godot.linuxbsd.opt.tools.64.llvm() [0x44c8bb3] (/home/bee/code/godot/godot/scene/main/viewport.cpp:1674)
[6] /home/bee/code/godot/godot/bin/godot.linuxbsd.opt.tools.64.llvm() [0x44ce520] (/home/bee/code/godot/godot/./core/object/ref_counted.h:220)
[7] /home/bee/code/godot/godot/bin/godot.linuxbsd.opt.tools.64.llvm() [0x44fcf83] (/home/bee/code/godot/godot/scene/main/window.cpp:974)
[8] /home/bee/code/godot/godot/bin/godot.linuxbsd.opt.tools.64.llvm() [0x45107c9] (/home/bee/code/godot/godot/./core/object/ref_counted.h:220)
[9] /home/bee/code/godot/godot/bin/godot.linuxbsd.opt.tools.64.llvm() [0x246b658] (/home/bee/code/godot/godot/platform/linuxbsd/display_server_x11.cpp:?)
[10] /home/bee/code/godot/godot/bin/godot.linuxbsd.opt.tools.64.llvm() [0x5e17f1f] (/home/bee/code/godot/godot/./core/object/ref_counted.h:220)
[11] /home/bee/code/godot/godot/bin/godot.linuxbsd.opt.tools.64.llvm() [0x5e15cea] (/home/bee/code/godot/godot/./core/templates/list.h:351)
[12] /home/bee/code/godot/godot/bin/godot.linuxbsd.opt.tools.64.llvm() [0x246eeec] (/home/bee/code/godot/godot/./core/templates/local_vector.h:259)
[13] /home/bee/code/godot/godot/bin/godot.linuxbsd.opt.tools.64.llvm() [0x2457066] (/home/bee/code/godot/godot/platform/linuxbsd/os_linuxbsd.cpp:439)
[14] /home/bee/code/godot/godot/bin/godot.linuxbsd.opt.tools.64.llvm() [0x2451ee0] (/home/bee/code/godot/godot/platform/linuxbsd/godot_linuxbsd.cpp:70)
[15] /lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xf3) [0x7f7d3de6c0b3] (??:0)
[16] /home/bee/code/godot/godot/bin/godot.linuxbsd.opt.tools.64.llvm() [0x2451d6e] (??:?)
-- END OF BACKTRACE --
================================================================

Steps to reproduce

  1. Use "Add element" to add some elements;
  2. Edit them to make them different;
  3. Right click on an item to open the popup menu;
  4. Insert a new element with "Insert New Before/After";
  5. Try a few more times.

Minimal reproduction project

No response

Rindbee commented 2 years ago

I'm guessing there are several reasons for this problem:

  1. Since #52277, each element of the array has become a property of the object, adding, removing, or even moving an array element will cause the property_list_changed signal to be emitted.
  2. The property_list_changed signal will eventually cause EditorInspector::update_tree() to be called.
  3. EditorInspector::update_tree() does not seem to be cheap.
salamandars commented 2 years ago

What Node/array does it happen on? I couldn't replicate it when testing with an ItemList. (master build, Win 10 x64)

Rindbee commented 2 years ago

What Node/array does it happen on? I couldn't replicate it when testing with an ItemList. (master build, Win 10 x64)

Make the item different first. Peek 2022-06-07 18-57

Rindbee commented 2 years ago

Tooltips appear very frequently now, and when you reproduce, you may get a log similar to:

Crash log

==94938==ERROR: AddressSanitizer: heap-use-after-free on address 0x61e002e862b0 at pc 0x559566f2829a bp 0x7ffcef0accf0 sp 0x7ffcef0acce8
READ of size 1 at 0x61e002e862b0 thread T0
    #0 0x559566f28299 in Node::is_inside_tree() const /opt/godot/godot/./scene/main/node.h:328:59
    #1 0x559566f28299 in Node::queue_delete() /opt/godot/godot/scene/main/node.cpp:2585:6
    #2 0x55956707d36c in Viewport::_gui_cancel_tooltip() /opt/godot/godot/scene/main/viewport.cpp:1135:22
    #3 0x5595670a1d90 in Viewport::_gui_input_event(Ref) /opt/godot/godot/scene/main/viewport.cpp:1677:4
    #4 0x5595670c36a0 in Viewport::push_input(Ref const&, bool) /opt/godot/godot/scene/main/viewport.cpp:2750:3
    #5 0x5595671b29c0 in Window::_window_input(Ref const&) /opt/godot/godot/scene/main/window.cpp:1093:2
    #6 0x559567206fdd in void call_with_variant_args_helper const&, 0ul>(Window*, void (Window::*)(Ref const&), Variant const**, Callable::CallError&, IndexSequence<0ul>) /opt/godot/godot/./core/variant/binder_common.h:262:2
    #7 0x559567206776 in CallableCustomMethodPointer const&>::call(Variant const**, int, Variant&, Callable::CallError&) const /opt/godot/godot/./core/object/callable_method_pointer.h:104:3
    #8 0x55956fff8d62 in Callable::callp(Variant const**, int, Variant&, Callable::CallError&) const /opt/godot/godot/core/variant/callable.cpp:50:11
    #9 0x55955ceb68a8 in DisplayServerX11::_dispatch_input_event(Ref const&) /opt/godot/godot/platform/linuxbsd/display_server_x11.cpp:3214:14
    #10 0x55956fe4b8cb in Input::_parse_input_event_impl(Ref const&, bool) /opt/godot/godot/core/input/input.cpp:662:3
    #11 0x55956fe42d1d in Input::flush_buffered_events() /opt/godot/godot/core/input/input.cpp:884:3
    #12 0x55955cecc952 in DisplayServerX11::process_events() /opt/godot/godot/platform/linuxbsd/display_server_x11.cpp:4209:26
    #13 0x55955ce500c5 in OS_LinuxBSD::run() /opt/godot/godot/platform/linuxbsd/os_linuxbsd.cpp:534:35
    #14 0x55955ce3e1fc in main /opt/godot/godot/platform/linuxbsd/godot_linuxbsd.cpp:72:6
    #15 0x7f632fbd8d8f in __libc_start_call_main csu/../sysdeps/nptl/libc_start_call_main.h:58:16
    #16 0x7f632fbd8e3f in __libc_start_main csu/../csu/libc-start.c:392:3
    #17 0x55955cd7dca4 in _start (/opt/godot/godot/bin/godot.linuxbsd.opt.tools.x86_64.llvm.san+0xd25dca4) (BuildId: 45e7c8ea93072dde)

0x61e002e862b0 is located 560 bytes inside of 2920-byte region [0x61e002e86080,0x61e002e86be8)
freed by thread T0 here:
    #0 0x55955ce00842 in free (/opt/godot/godot/bin/godot.linuxbsd.opt.tools.x86_64.llvm.san+0xd2e0842) (BuildId: 45e7c8ea93072dde)
    #1 0x559566ec0483 in Node::_notification(int) /opt/godot/godot/scene/main/node.cpp:169:5
    #2 0x55955d552818 in Node::_notificationv(int, bool) /opt/godot/godot/./scene/main/node.h:45:2

previously allocated by thread T0 here:
    #0 0x55955ce00aee in malloc (/opt/godot/godot/bin/godot.linuxbsd.opt.tools.x86_64.llvm.san+0xd2e0aee) (BuildId: 45e7c8ea93072dde)
    #1 0x55956f64a13b in Memory::alloc_static(unsigned long, bool) /opt/godot/godot/core/os/memory.cpp:75:14
    #2 0x55956714d593 in void call_with_variant_args(Viewport*, void (Viewport::*)(), Variant const**, int, Callable::CallError&) /opt/godot/godot/./core/variant/binder_common.h:376:2
    #3 0x55956714d593 in CallableCustomMethodPointer::call(Variant const**, int, Variant&, Callable::CallError&) const /opt/godot/godot/./core/object/callable_method_pointer.h:104:3
    #4 0x55956fff8d62 in Callable::callp(Variant const**, int, Variant&, Callable::CallError&) const /opt/godot/godot/core/variant/callable.cpp:50:11
    #5 0x559570cd16fc in Object::emit_signalp(StringName const&, Variant const**, int) /opt/godot/godot/core/object/object.cpp:1045:15
    #6 0x55955dfe7cb3 in Error Object::emit_signal<>(StringName const&) /opt/godot/godot/./core/object/object.h:873:10
    #7 0x559566fcea2b in SceneTree::process_timers(float, bool) /opt/godot/godot/scene/main/scene_tree.cpp:535:14

SUMMARY: AddressSanitizer: heap-use-after-free /opt/godot/godot/./scene/main/node.h:328:59 in Node::is_inside_tree() const

This is a duplicate of #59798.

This issue is similar but it shouldn't be the same problem. It's been a long time and I can't be sure. Is there an option to disable tooltip?

Rindbee commented 2 years ago

Cannot be fully fixed by #66859. Here is a different crash log.

Crash log

==48459==ERROR: AddressSanitizer: heap-use-after-free on address 0x61e0026235d0 at pc 0x558f163c89a3 bp 0x7ffd8e4e7450 sp 0x7ffd8e4e7448
READ of size 8 at 0x61e0026235d0 thread T0
    #0 0x558f163c89a2 in CowData::_ref(CowData const&) (/opt/godot/godot/bin/godot.linuxbsd.editor.x86_64.llvm.san+0xd05f9a2) (BuildId: 1f9fc4fc4acf6406)
    #1 0x558f20b02447 in Label::get_text() const (/opt/godot/godot/bin/godot.linuxbsd.editor.x86_64.llvm.san+0x17799447) (BuildId: 1f9fc4fc4acf6406)
    #2 0x558f203a73ff in Viewport::_gui_input_event(Ref) (/opt/godot/godot/bin/godot.linuxbsd.editor.x86_64.llvm.san+0x1703e3ff) (BuildId: 1f9fc4fc4acf6406)
    #3 0x558f203c8530 in Viewport::push_input(Ref const&, bool) (/opt/godot/godot/bin/godot.linuxbsd.editor.x86_64.llvm.san+0x1705f530) (BuildId: 1f9fc4fc4acf6406)
    #4 0x558f204b8330 in Window::_window_input(Ref const&) (/opt/godot/godot/bin/godot.linuxbsd.editor.x86_64.llvm.san+0x1714f330) (BuildId: 1f9fc4fc4acf6406)
    #5 0x558f2050bb4d in void call_with_variant_args_helper const&, 0ul>(Window*, void (Window::*)(Ref const&), Variant const**, Callable::CallError&, IndexSequence<0ul>) (/opt/godot/godot/bin/godot.linuxbsd.editor.x86_64.llvm.san+0x171a2b4d) (BuildId: 1f9fc4fc4acf6406)
    #6 0x558f2050b2e6 in CallableCustomMethodPointer const&>::call(Variant const**, int, Variant&, Callable::CallError&) const (/opt/godot/godot/bin/godot.linuxbsd.editor.x86_64.llvm.san+0x171a22e6) (BuildId: 1f9fc4fc4acf6406)
    #7 0x558f2924be12 in Callable::callp(Variant const**, int, Variant&, Callable::CallError&) const (/opt/godot/godot/bin/godot.linuxbsd.editor.x86_64.llvm.san+0x1fee2e12) (BuildId: 1f9fc4fc4acf6406)
    #8 0x558f1643b328 in DisplayServerX11::_dispatch_input_event(Ref const&) (/opt/godot/godot/bin/godot.linuxbsd.editor.x86_64.llvm.san+0xd0d2328) (BuildId: 1f9fc4fc4acf6406)
    #9 0x558f290aa89b in Input::_parse_input_event_impl(Ref const&, bool) (/opt/godot/godot/bin/godot.linuxbsd.editor.x86_64.llvm.san+0x1fd4189b) (BuildId: 1f9fc4fc4acf6406)
    #10 0x558f290a1cfd in Input::flush_buffered_events() (/opt/godot/godot/bin/godot.linuxbsd.editor.x86_64.llvm.san+0x1fd38cfd) (BuildId: 1f9fc4fc4acf6406)
    #11 0x558f1645136c in DisplayServerX11::process_events() (/opt/godot/godot/bin/godot.linuxbsd.editor.x86_64.llvm.san+0xd0e836c) (BuildId: 1f9fc4fc4acf6406)
    #12 0x558f163d5775 in OS_LinuxBSD::run() (/opt/godot/godot/bin/godot.linuxbsd.editor.x86_64.llvm.san+0xd06c775) (BuildId: 1f9fc4fc4acf6406)
    #13 0x558f163c1f74 in main (/opt/godot/godot/bin/godot.linuxbsd.editor.x86_64.llvm.san+0xd058f74) (BuildId: 1f9fc4fc4acf6406)
    #14 0x7ff3324aed8f in __libc_start_call_main csu/../sysdeps/nptl/libc_start_call_main.h:58:16
    #15 0x7ff3324aee3f in __libc_start_main csu/../csu/libc-start.c:392:3
    #16 0x558f16301a24 in _start (/opt/godot/godot/bin/godot.linuxbsd.editor.x86_64.llvm.san+0xcf98a24) (BuildId: 1f9fc4fc4acf6406)

0x61e0026235d0 is located 2384 bytes inside of 2592-byte region [0x61e002622c80,0x61e0026236a0)
freed by thread T0 here:
    #0 0x558f163845c2 in free (/opt/godot/godot/bin/godot.linuxbsd.editor.x86_64.llvm.san+0xd01b5c2) (BuildId: 1f9fc4fc4acf6406)
    #1 0x558f201c6fb3 in Node::_notification(int) (/opt/godot/godot/bin/godot.linuxbsd.editor.x86_64.llvm.san+0x16e5dfb3) (BuildId: 1f9fc4fc4acf6406)
    #2 0x558f16af7ba8 in Node::_notificationv(int, bool) (/opt/godot/godot/bin/godot.linuxbsd.editor.x86_64.llvm.san+0xd78eba8) (BuildId: 1f9fc4fc4acf6406)

previously allocated by thread T0 here:
    #0 0x558f1638486e in malloc (/opt/godot/godot/bin/godot.linuxbsd.editor.x86_64.llvm.san+0xd01b86e) (BuildId: 1f9fc4fc4acf6406)
    #1 0x558f2885ccfb in Memory::alloc_static(unsigned long, bool) (/opt/godot/godot/bin/godot.linuxbsd.editor.x86_64.llvm.san+0x1f4f3cfb) (BuildId: 1f9fc4fc4acf6406)
    #2 0x558f20452c13 in CallableCustomMethodPointer::call(Variant const**, int, Variant&, Callable::CallError&) const (/opt/godot/godot/bin/godot.linuxbsd.editor.x86_64.llvm.san+0x170e9c13) (BuildId: 1f9fc4fc4acf6406)
    #3 0x558f2924be12 in Callable::callp(Variant const**, int, Variant&, Callable::CallError&) const (/opt/godot/godot/bin/godot.linuxbsd.editor.x86_64.llvm.san+0x1fee2e12) (BuildId: 1f9fc4fc4acf6406)
    #4 0x558f29f179ec in Object::emit_signalp(StringName const&, Variant const**, int) (/opt/godot/godot/bin/godot.linuxbsd.editor.x86_64.llvm.san+0x20bae9ec) (BuildId: 1f9fc4fc4acf6406)
    #5 0x558f1758d7e3 in Error Object::emit_signal<>(StringName const&) (/opt/godot/godot/bin/godot.linuxbsd.editor.x86_64.llvm.san+0xe2247e3) (BuildId: 1f9fc4fc4acf6406)
    #6 0x558f202d1cbc in SceneTree::process_timers(double, bool) (/opt/godot/godot/bin/godot.linuxbsd.editor.x86_64.llvm.san+0x16f68cbc) (BuildId: 1f9fc4fc4acf6406)

SUMMARY: AddressSanitizer: heap-use-after-free (/opt/godot/godot/bin/godot.linuxbsd.editor.x86_64.llvm.san+0xd05f9a2) (BuildId: 1f9fc4fc4acf6406) in CowData::_ref(CowData const&)

Edit:

Forgot to reset gui.tooltip_label, now it should not crash.