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

Crash if inspector tooltip is dismissed when saving scene #91652

Closed
timothyqiu opened this issue May 7, 2024 · 5 comments · Fixed by #91716
Closed

Crash if inspector tooltip is dismissed when saving scene #91652

timothyqiu opened this issue May 7, 2024 · 5 comments · Fixed by #91716
Assignees
Milestone

Comments

@timothyqiu
Copy link
Member

Tested versions

master[7cdad33]

System information

Godot v4.3.dev (7cdad33) - Arch Linux #⁠1 SMP PREEMPT_DYNAMIC Thu, 02 May 2024 17:49:46 +0000 - X11 - GLES3 (Compatibility) - NVIDIA GeForce RTX 3060 Ti (nvidia; 550.78) - 13th Gen Intel(R) Core(TM) i5-13400F (16 Threads)

Issue description

Saving scene won't dismiss inspector's tooltip. But if you move the mouse cursor out of the tooltip area when saving scene, the tooltip is dismissed and the editor crashes.

Peek.2024-05-07.16-49.mp4
ASan Output

Godot Engine v4.3.dev.custom_build.7cdad3331 (2024-05-06 20:33:45 UTC) - https://godotengine.org
OpenGL API 3.3.0 NVIDIA 550.78 - Compatibility - Using Device: NVIDIA - NVIDIA GeForce RTX 3060 Ti

=================================================================
==21556==ERROR: AddressSanitizer: heap-use-after-free on address 0x5200002d4380 at pc 0x63e4ad49bcbb bp 0x7ffe13c5d1a0 sp 0x7ffe13c5d190
READ of size 4 at 0x5200002d4380 thread T0
    #0 0x63e4ad49bcba in Node::is_inside_tree() const scene/main/node.h:449
    #1 0x63e4b31b84b5 in Window::_window_input(Ref<InputEvent> const&) scene/main/window.cpp:1624
    #2 0x63e4b32659c7 in void call_with_variant_args_helper<Window, Ref<InputEvent> const&, 0ul>(Window*, void (Window::*)(Ref<InputEvent> const&), Variant const**, Callable::CallError&, IndexSequence<0ul>) core/variant/binder_common.h:304
    #3 0x63e4b3252122 in void call_with_variant_args<Window, Ref<InputEvent> const&>(Window*, void (Window::*)(Ref<InputEvent> const&), Variant const**, int, Callable::CallError&) core/variant/binder_common.h:418
    #4 0x63e4b323cfbb in CallableCustomMethodPointer<Window, Ref<InputEvent> const&>::call(Variant const**, int, Variant&, Callable::CallError&) const core/object/callable_method_pointer.h:103
    #5 0x63e4b87cb7be in Callable::callp(Variant const**, int, Variant&, Callable::CallError&) const core/variant/callable.cpp:57
    #6 0x63e4ace15816 in Variant Callable::call<Ref<InputEvent> >(Ref<InputEvent>) const core/variant/variant.h:872
    #7 0x63e4acde1da5 in DisplayServerX11::_dispatch_input_event(Ref<InputEvent> const&) platform/linuxbsd/x11/display_server_x11.cpp:3999
    #8 0x63e4acde1ad6 in DisplayServerX11::_dispatch_input_events(Ref<InputEvent> const&) platform/linuxbsd/x11/display_server_x11.cpp:3988
    #9 0x63e4b86b7d41 in Input::_parse_input_event_impl(Ref<InputEvent> const&, bool) core/input/input.cpp:773
    #10 0x63e4b86bb638 in Input::flush_buffered_events() core/input/input.cpp:1044
    #11 0x63e4acdeffa0 in DisplayServerX11::process_events() platform/linuxbsd/x11/display_server_x11.cpp:5108
    #12 0x63e4acd82872 in OS_LinuxBSD::run() platform/linuxbsd/os_linuxbsd.cpp:958
    #13 0x63e4acd70ac2 in main platform/linuxbsd/godot_linuxbsd.cpp:85
    #14 0x7f22cb156d49  (/usr/lib/libc.so.6+0x25d49) (BuildId: 915eeec6439cfded1125deefc44a8d73e57873d9)
    #15 0x7f22cb156e0b in __libc_start_main (/usr/lib/libc.so.6+0x25e0b) (BuildId: 915eeec6439cfded1125deefc44a8d73e57873d9)
    #16 0x63e4acd706a4 in _start (/home/timothy/repos/godot-master/bin/godot.linuxbsd.editor.dev.x86_64.san+0x85476a4) (BuildId: e3db6d9e987e35b649a188f23fd4902a02006547)

0x5200002d4380 is located 768 bytes inside of 3472-byte region [0x5200002d4080,0x5200002d4e10)
freed by thread T0 here:
    #0 0x7f22cb4dddb2 in __interceptor_free /usr/src/debug/gcc/gcc/libsanitizer/asan/asan_malloc_linux.cpp:52
    #1 0x63e4b816410e in Memory::free_static(void*, bool) core/os/memory.cpp:168
    #2 0x63e4acf843c0 in void memdelete<Object>(Object*) core/os/memory.h:119
    #3 0x63e4b3031a96 in SceneTree::_flush_delete_queue() scene/main/scene_tree.cpp:1367
    #4 0x63e4b30295ef in SceneTree::process(double) scene/main/scene_tree.cpp:533
    #5 0x63e4acf6e37d in Main::iteration() main/main.cpp:4041
    #6 0x63e4b1332dc5 in ProgressDialog::task_step(String const&, String const&, int, bool) editor/progress_dialog.cpp:209
    #7 0x63e4b0dff1d6 in EditorNode::progress_task_step(String const&, String const&, int, bool) editor/editor_node.cpp:4669
    #8 0x63e4b05119f4 in EditorProgress::step(String const&, int, bool) editor/editor_node.h:911
    #9 0x63e4b0dc8ba1 in EditorNode::_save_scene_with_preview(String, int) editor/editor_node.cpp:1634
    #10 0x63e4b0ddaf91 in EditorNode::_menu_option_confirm(int, bool) editor/editor_node.cpp:2676
    #11 0x63e4b0dc3b4e in EditorNode::_menu_option(int) editor/editor_node.cpp:1415
    #12 0x63e4b0ea7780 in void call_with_variant_args_helper<EditorNode, int, 0ul>(EditorNode*, void (EditorNode::*)(int), Variant const**, Callable::CallError&, IndexSequence<0ul>) core/variant/binder_common.h:304
    #13 0x63e4b0ea4f83 in void call_with_variant_args<EditorNode, int>(EditorNode*, void (EditorNode::*)(int), Variant const**, int, Callable::CallError&) core/variant/binder_common.h:418
    #14 0x63e4b0e9e2f1 in CallableCustomMethodPointer<EditorNode, int>::call(Variant const**, int, Variant&, Callable::CallError&) const core/object/callable_method_pointer.h:103
    #15 0x63e4b87cb7be in Callable::callp(Variant const**, int, Variant&, Callable::CallError&) const core/variant/callable.cpp:57
    #16 0x63e4b9062f6f in Object::emit_signalp(StringName const&, Variant const**, int) core/object/object.cpp:1220
    #17 0x63e4b2f9bd3e in Node::emit_signalp(StringName const&, Variant const**, int) scene/main/node.cpp:3902
    #18 0x63e4ad6207a7 in Error Object::emit_signal<int>(StringName const&, int) core/object/object.h:936
    #19 0x63e4b3812007 in PopupMenu::activate_item(int) scene/gui/popup_menu.cpp:2428
    #20 0x63e4b3810ded in PopupMenu::activate_item_by_event(Ref<InputEvent> const&, bool) scene/gui/popup_menu.cpp:2350
    #21 0x63e4b37816ac in MenuBar::shortcut_input(Ref<InputEvent> const&) scene/gui/menu_bar.cpp:166
    #22 0x63e4b2f7f266 in Node::_call_shortcut_input(Ref<InputEvent> const&) scene/main/node.cpp:3368
    #23 0x63e4b302ff6e in SceneTree::_call_input_pause(StringName const&, SceneTree::CallInputType, Ref<InputEvent> const&, Viewport*) scene/main/scene_tree.cpp:1243
    #24 0x63e4b30d0231 in Viewport::_push_unhandled_input_internal(Ref<InputEvent> const&) scene/main/viewport.cpp:3294
    #25 0x63e4b30cfa2c in Viewport::push_input(Ref<InputEvent> const&, bool) scene/main/viewport.cpp:3256
    #26 0x63e4b0bcbf4f in EditorHelpBitTooltip::_input_from_window(Ref<InputEvent> const&) editor/editor_help.cpp:3781
    #27 0x63e4b31b8448 in Window::_window_input(Ref<InputEvent> const&) scene/main/window.cpp:1622
    #28 0x63e4b32659c7 in void call_with_variant_args_helper<Window, Ref<InputEvent> const&, 0ul>(Window*, void (Window::*)(Ref<InputEvent> const&), Variant const**, Callable::CallError&, IndexSequence<0ul>) core/variant/binder_common.h:304
    #29 0x63e4b3252122 in void call_with_variant_args<Window, Ref<InputEvent> const&>(Window*, void (Window::*)(Ref<InputEvent> const&), Variant const**, int, Callable::CallError&) core/variant/binder_common.h:418

previously allocated by thread T0 here:
    #0 0x7f22cb4df359 in __interceptor_malloc /usr/src/debug/gcc/gcc/libsanitizer/asan/asan_malloc_linux.cpp:69
    #1 0x63e4b8163538 in Memory::alloc_static(unsigned long, bool) core/os/memory.cpp:75
    #2 0x63e4b8163456 in operator new(unsigned long, char const*) core/os/memory.cpp:40
    #3 0x63e4b0bcc0d6 in EditorHelpBitTooltip::show_tooltip(EditorHelpBit*, Control*) editor/editor_help.cpp:3788
    #4 0x63e4b0c586bd in EditorProperty::make_custom_tooltip(String const&) const editor/editor_inspector.cpp:987
    #5 0x63e4b30b7237 in Viewport::_gui_show_tooltip() scene/main/viewport.cpp:1460
    #6 0x63e4b3195a8e in void call_with_variant_args_helper<Viewport>(Viewport*, void (Viewport::*)(), Variant const**, Callable::CallError&, IndexSequence<>) core/variant/binder_common.h:304
    #7 0x63e4b317e878 in void call_with_variant_args<Viewport>(Viewport*, void (Viewport::*)(), Variant const**, int, Callable::CallError&) core/variant/binder_common.h:418
    #8 0x63e4b3167d87 in CallableCustomMethodPointer<Viewport>::call(Variant const**, int, Variant&, Callable::CallError&) const core/object/callable_method_pointer.h:103
    #9 0x63e4b87cb7be in Callable::callp(Variant const**, int, Variant&, Callable::CallError&) const core/variant/callable.cpp:57
    #10 0x63e4b9062f6f in Object::emit_signalp(StringName const&, Variant const**, int) core/object/object.cpp:1220
    #11 0x63e4ae4e472b in Error Object::emit_signal<>(StringName const&) core/object/object.h:936
    #12 0x63e4b302a20e in SceneTree::process_timers(double, bool) scene/main/scene_tree.cpp:600
    #13 0x63e4b3029664 in SceneTree::process(double) scene/main/scene_tree.cpp:539
    #14 0x63e4acf6e37d in Main::iteration() main/main.cpp:4041
    #15 0x63e4acd828b1 in OS_LinuxBSD::run() platform/linuxbsd/os_linuxbsd.cpp:962
    #16 0x63e4acd70ac2 in main platform/linuxbsd/godot_linuxbsd.cpp:85
    #17 0x7f22cb156d49  (/usr/lib/libc.so.6+0x25d49) (BuildId: 915eeec6439cfded1125deefc44a8d73e57873d9)
    #18 0x7f22cb156e0b in __libc_start_main (/usr/lib/libc.so.6+0x25e0b) (BuildId: 915eeec6439cfded1125deefc44a8d73e57873d9)
    #19 0x63e4acd706a4 in _start (/home/timothy/repos/godot-master/bin/godot.linuxbsd.editor.dev.x86_64.san+0x85476a4) (BuildId: e3db6d9e987e35b649a188f23fd4902a02006547)

SUMMARY: AddressSanitizer: heap-use-after-free scene/main/node.h:449 in Node::is_inside_tree() const
Shadow bytes around the buggy address:
  0x5200002d4100: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x5200002d4180: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x5200002d4200: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x5200002d4280: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x5200002d4300: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
=>0x5200002d4380:[fd]fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x5200002d4400: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x5200002d4480: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x5200002d4500: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x5200002d4580: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x5200002d4600: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
==21556==ABORTING

Steps to reproduce

  1. Make sure your scene is already saved.
  2. Hover the mouse cursor on any property so a tooltip appears.
  3. Move the mouse cursor to that tooltip.
  4. Press Ctrl+S and move your cursor out of the tooltip at the same time.

Minimal reproduction project (MRP)

N/A

@dalexeev
Copy link
Member

dalexeev commented May 7, 2024

I haven't been able to reproduce this on my system, so debugging is difficult for me. What build options did you use? Or other tips on how I can reproduce the problem?

=21556==ERROR: AddressSanitizer: heap-use-after-free on address 0x5200002d4380 at pc 0x63e4ad49bcbb bp 0x7ffe13c5d1a0 sp 0x7ffe13c5d190
READ of size 4 at 0x5200002d4380 thread T0
    #0 0x63e4ad49bcba in Node::is_inside_tree() const scene/main/node.h:449
    #1 0x63e4b31b84b5 in Window::_window_input(Ref<InputEvent> const&) scene/main/window.cpp:1624
    #2 0x63e4b32659c7 in void call_with_variant_args_helper<Window, Ref<InputEvent> const&, 0ul>(Window*, void (Window::*)(Ref<InputEvent> const&), Variant const**, Callable::CallError&, IndexSequence<0ul>) core/variant/binder_common.h:304
    #3 0x63e4b3252122 in void call_with_variant_args<Window, Ref<InputEvent> const&>(Window*, void (Window::*)(Ref<InputEvent> const&), Variant const**, int, Callable::CallError&) core/variant/binder_common.h:418
    #4 0x63e4b323cfbb in CallableCustomMethodPointer<Window, Ref<InputEvent> const&>::call(Variant const**, int, Variant&, Callable::CallError&) const core/object/callable_method_pointer.h:103
    #5 0x63e4b87cb7be in Callable::callp(Variant const**, int, Variant&, Callable::CallError&) const core/variant/callable.cpp:57

I would guess this is due to

1. input forwarding:

godot/editor/editor_help.cpp

Lines 3774 to 3784 in e001bc7

// Forwards non-mouse input to the parent viewport.
void EditorHelpBitTooltip::_input_from_window(const Ref<InputEvent> &p_event) {
if (p_event->is_action_pressed(SNAME("ui_cancel"), false, true)) {
hide(); // Will be deleted on its timer.
} else {
const Ref<InputEventMouse> mouse_event = p_event;
if (mouse_event.is_null()) {
get_parent_viewport()->push_input(p_event);
}
}
}

2. connected signals, since there is CallableCustomMethodPointer:

godot/editor/editor_help.cpp

Lines 3842 to 3847 in e001bc7

timer->connect("timeout", callable_mp(static_cast<Node *>(this), &Node::queue_free));
add_child(timer);
ERR_FAIL_NULL(p_target);
p_target->connect("mouse_entered", callable_mp(timer, &Timer::stop));
p_target->connect("mouse_exited", callable_mp(timer, &Timer::start).bind(-1));

3. using const_cast:

EditorHelpBitTooltip::show_tooltip(help_bit, const_cast<EditorProperty *>(this));
return memnew(Control); // Make the standard tooltip invisible.

@KoBeWi
Copy link
Member

KoBeWi commented May 7, 2024

Also can't reproduce. I'm on Windows.

@timothyqiu
Copy link
Member Author

What build options did you use?

Mainly an ASan enabled build:

target=editor tests=no module_text_server_fb_enabled=yes linker=mold dev_build=yes use_asan=yes use_lsan=yes

@dalexeev
Copy link
Member

dalexeev commented May 7, 2024

Thanks, I reproduced the bug with these options, I'll take a look.

@dalexeev
Copy link
Member

dalexeev commented May 7, 2024

I found the root of the problem, but I'm not sure how to solve it.

Full stack trace

Details
#0  EditorHelpBitTooltip::_notification (this=0x62000039a090, p_what=1) at editor/editor_help.cpp:3772
#1  0x000055556197bb3c in EditorHelpBitTooltip::_notificationv (this=0x62000039a090, p_notification=1, p_reversed=true) at editor/editor_help.h:325
#2  0x0000555569ed9a31 in Object::notification (this=0x62000039a090, p_notification=1, p_reversed=true) at core/object/object.cpp:918
#3  0x0000555569ed248a in Object::_predelete (this=0x62000039a090) at core/object/object.cpp:199
#4  0x0000555569ef1c9f in predelete_handler (p_object=0x62000039a090) at core/object/object.cpp:2153
#5  0x000055555dcb7043 in memdelete<Object> (p_class=0x62000039a090) at ./core/os/memory.h:112
#6  0x0000555563e03d5f in SceneTree::_flush_delete_queue (this=0x61a000031290) at scene/main/scene_tree.cpp:1367
#7  0x0000555563dfb7f8 in SceneTree::process (this=0x61a000031290, p_time=0.049498333333333332) at scene/main/scene_tree.cpp:533
#8  0x000055555dca0638 in Main::iteration () at main/main.cpp:4044
#9  0x00005555620d2306 in ProgressDialog::task_step (this=0x62000006d090, p_task=..., p_state=..., p_step=1, p_force_redraw=true) at editor/progress_dialog.cpp:209
#10 0x0000555561b94dd9 in EditorNode::progress_task_step (p_task=..., p_state=..., p_step=1, p_force_refresh=true) at editor/editor_node.cpp:4669
#11 0x000055556129954f in EditorProgress::step (this=0x7ffff59e7840, p_state=..., p_step=1, p_force_refresh=true) at ./editor/editor_node.h:911
#12 0x0000555561b5e57d in EditorNode::_save_scene_with_preview (this=0x61f000071c90, p_file=..., p_idx=-1) at editor/editor_node.cpp:1641
#13 0x0000555561b708e5 in EditorNode::_menu_option_confirm (this=0x61f000071c90, p_option=3, p_confirmed=false) at editor/editor_node.cpp:2676
#14 0x0000555561b592e9 in EditorNode::_menu_option (this=0x61f000071c90, p_option=3) at editor/editor_node.cpp:1415
#15 0x0000555561c3eaf1 in call_with_variant_args_helper<EditorNode, int, 0ul> (p_instance=0x61f000071c90, p_method=<error reading variable: Cannot access memory at address 0xffffffffffffffc0>, p_args=0x7ffff56a8d30, r_error=...) at ./core/variant/binder_common.h:304
#16 0x0000555561c3c2b4 in call_with_variant_args<EditorNode, int> (p_instance=0x61f000071c90, p_method=(void (EditorNode::*)(EditorNode * const, int)) 0x555561b592c0 <EditorNode::_menu_option(int)>, p_args=0x7ffff56a8d30, p_argcount=1, r_error=...) at ./core/variant/binder_common.h:418
#17 0x0000555561c3559e in CallableCustomMethodPointer<EditorNode, int>::call (this=0x608002055630, p_arguments=0x7ffff56a8d30, p_argcount=1, r_return_value=..., r_call_error=...) at ./core/object/callable_method_pointer.h:103
#18 0x0000555569634c3d in Callable::callp (this=0x7fffffff8720, p_arguments=0x7ffff56a8d30, p_argcount=1, r_return_value=..., r_call_error=...) at core/variant/callable.cpp:57
#19 0x0000555569ede5e6 in Object::emit_signalp (this=0x6210003a4910, p_name=..., p_args=0x7ffff56a8d30, p_argcount=1) at core/object/object.cpp:1220
#20 0x0000555563d6c6fd in Node::emit_signalp (this=0x6210003a4910, p_name=..., p_args=0x7ffff56a8d30, p_argcount=1) at scene/main/node.cpp:3902
#21 0x000055555e35dc92 in Object::emit_signal<int> (this=0x6210003a4910, p_name=...) at ./core/object/object.h:936
#22 0x00005555645f761c in PopupMenu::activate_item (this=0x6210003a4910, p_idx=6) at scene/gui/popup_menu.cpp:2428
#23 0x00005555645f63f6 in PopupMenu::activate_item_by_event (this=0x6210003a4910, p_event=..., p_for_global_only=false) at scene/gui/popup_menu.cpp:2350
#24 0x0000555564565ff9 in MenuBar::shortcut_input (this=0x61e000087090, p_event=...) at scene/gui/menu_bar.cpp:166
#25 0x0000555563d4fb9b in Node::_call_shortcut_input (this=0x61e000087090, p_event=...) at scene/main/node.cpp:3368
#26 0x0000555563e02213 in SceneTree::_call_input_pause (this=0x61a000031290, p_group=..., p_call_type=SceneTree::CALL_INPUT_TYPE_SHORTCUT_INPUT, p_input=..., p_viewport=0x61f000070e90) at scene/main/scene_tree.cpp:1243
#27 0x0000555563ea3748 in Viewport::_push_unhandled_input_internal (this=0x61f000070e90, p_event=...) at scene/main/viewport.cpp:3294
#28 0x0000555563ea2f3b in Viewport::push_input (this=0x61f000070e90, p_event=..., p_local_coords=false) at scene/main/viewport.cpp:3256
#29 0x000055556195e3e2 in EditorHelpBitTooltip::_input_from_window (this=0x62000039a090, p_event=...) at editor/editor_help.cpp:3784
#30 0x0000555563f8d1d9 in Window::_window_input (this=0x62000039a090, p_ev=...) at scene/main/window.cpp:1622
#31 0x000055556403b8d0 in call_with_variant_args_helper<Window, Ref<InputEvent> const&, 0ul> (p_instance=0x62000039a090, p_method=(void (Window::*)(Window * const, const Ref<InputEvent> &)) 0x555563f8c63e <Window::_window_input(Ref<InputEvent> const&)>, p_args=0x7ffff5675d50, r_error=...) at ./core/variant/binder_common.h:304
#32 0x0000555564027e43 in call_with_variant_args<Window, Ref<InputEvent> const&> (p_instance=0x62000039a090, p_method=(void (Window::*)(Window * const, const Ref<InputEvent> &)) 0x555563f8c63e <Window::_window_input(Ref<InputEvent> const&)>, p_args=0x7ffff5675d50, p_argcount=1, r_error=...) at ./core/variant/binder_common.h:418
#33 0x0000555564012a58 in CallableCustomMethodPointer<Window, Ref<InputEvent> const&>::call (this=0x608004d79430, p_arguments=0x7ffff5675d50, p_argcount=1, r_return_value=..., r_call_error=...) at ./core/object/callable_method_pointer.h:103
#34 0x0000555569634c3d in Callable::callp (this=0x7ffff5835500, p_arguments=0x7ffff5675d50, p_argcount=1, r_return_value=..., r_call_error=...) at core/variant/callable.cpp:57
#35 0x000055555db46f13 in Callable::call<Ref<InputEvent> > (this=0x7ffff5835500) at ./core/variant/variant.h:872
#36 0x000055555db12dbe in DisplayServerX11::_dispatch_input_event (this=0x61c000001090, p_event=...) at platform/linuxbsd/x11/display_server_x11.cpp:3999
#37 0x000055555db12aeb in DisplayServerX11::_dispatch_input_events (p_event=...) at platform/linuxbsd/x11/display_server_x11.cpp:3988
#38 0x000055556951ef38 in Input::_parse_input_event_impl (this=0x6190000a3790, p_event=..., p_is_emulated=false) at core/input/input.cpp:773
#39 0x000055556952289f in Input::flush_buffered_events (this=0x6190000a3790) at core/input/input.cpp:1044
#40 0x000055555db21000 in DisplayServerX11::process_events (this=0x61c000001090) at platform/linuxbsd/x11/display_server_x11.cpp:5108
#41 0x000055555dab3135 in OS_LinuxBSD::run (this=0x7ffff5900060) at platform/linuxbsd/os_linuxbsd.cpp:958
#42 0x000055555daa11f7 in main (argc=5, argv=0x7fffffffe3a8) at platform/linuxbsd/godot_linuxbsd.cpp:85

Filtered stack trace

#0  EditorHelpBitTooltip::_notification (this=0x62000039a090, p_what=1)
    at editor/editor_help.cpp:3772
#8  0x000055555dca0638 in Main::iteration ()
    at main/main.cpp:4044
#9  0x00005555620d2306 in ProgressDialog::task_step (this=0x62000006d090, p_task=..., p_state=..., p_step=1, p_force_redraw=true)
    at editor/progress_dialog.cpp:209
#29 0x000055556195e3e2 in EditorHelpBitTooltip::_input_from_window (this=0x62000039a090, p_event=...)
    at editor/editor_help.cpp:3784
#30 0x0000555563f8d1d9 in Window::_window_input (this=0x62000039a090, p_ev=...)
    at scene/main/window.cpp:1622

Description

0. Freeing the popup

I added the following debug code so that the subsequent line numbers in editor_help.cpp are different by 3 from 107fd30:

void EditorHelpBitTooltip::_notification(int p_what) {

case NOTIFICATION_PREDELETE:
    print_line("EditorHelpBitTooltip NOTIFICATION_PREDELETE"); // <-- Breakpoint.
    break;

8-9. ProgressDialog::task_step() calls Main::iteration()

This is the "hack" that broke my expectations.

#ifndef ANDROID_ENABLED
Main::iteration(); // this will not work on a lot of platforms, so it's only meant for the editor
#endif

29. EditorHelpBitTooltip::_input_from_window() calls push_input()

Forward the input event to the parent viewport.

godot/editor/editor_help.cpp

Lines 3774 to 3784 in 107fd30

// Forwards non-mouse input to the parent viewport.
void EditorHelpBitTooltip::_input_from_window(const Ref<InputEvent> &p_event) {
if (p_event->is_action_pressed(SNAME("ui_cancel"), false, true)) {
hide(); // Will be deleted on its timer.
} else {
const Ref<InputEventMouse> mouse_event = p_event;
if (mouse_event.is_null()) {
get_parent_viewport()->push_input(p_event);
}
}
}

30. One step before crash

Line 1622: this is freed (EditorHelpBitTooltip < PopupPanel < Popup < Window).
Line 1624: We call its method is_inside_tree().

godot/scene/main/window.cpp

Lines 1619 to 1626 in 107fd30

// If the event needs to be handled in a Window-derived class, then it should overwrite
// `_input_from_window` instead of subscribing to the `window_input` signal, because the signal
// filters out internal events.
_input_from_window(p_ev);
if (p_ev->get_device() != InputEvent::DEVICE_ID_INTERNAL && is_inside_tree()) {
emit_signal(SceneStringNames::get_singleton()->window_input, p_ev);
}

And then the crash from the first post:

==21556==ERROR: AddressSanitizer: heap-use-after-free on address 0x5200002d4380 at pc 0x63e4ad49bcbb bp 0x7ffe13c5d1a0 sp 0x7ffe13c5d190
READ of size 4 at 0x5200002d4380 thread T0
    #0 0x63e4ad49bcba in Node::is_inside_tree() const scene/main/node.h:449
    #1 0x63e4b31b84b5 in Window::_window_input(Ref<InputEvent> const&) scene/main/window.cpp:1624

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

Successfully merging a pull request may close this issue.

4 participants