godotengine / godot

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

Popup menu crash the project. #16013

Closed Malkverbena closed 5 years ago

Malkverbena commented 6 years ago

The project crash when I use the node. When I call the popup menu the project chash.
On older builds everything works fine.

I'm using rc3 Windows 10 Core-I7 - GPU: NVIDEA Quadro K600

Steps to reproduce:
Usually I instance the menu by code but when I try to insert it on node tree the project does not start. Running the project above, drag the item to inventory and click with the right button of the mouse on the item to open the popup menu.

Minimal reproduction project: https://github.com/Malkverbena/Inventory
Sorry for the mess and the mix of languages. Hope the code are clear.

menu popup bug

akien-mga commented 6 years ago

I could reproduce the crash on X11 (fb56315e) with the provided project and steps to reproduce. It looks like it enters an infinite loop.

When dragging the item to one of the inventories, right-clicking the item to show the PopupMenu, and then clicking anywhere (either on an option or outside the popup), this error is displayed:

ERROR: remove_child: Condition ' idx == -1 ' is true.
   At: scene/main/node.cpp:1407.
Item usado
Item usado
Thread 1 "godot-git" received signal SIGSEGV, Segmentation fault.
0x0000000000000000 in ?? ()
(gdb) bt
#0  0x0000000000000000 in ?? ()
#1  0x0000000001d0e4c5 in Viewport::_gui_input_event (this=0x4f7caa0, p_event=...) at scene/main/viewport.cpp:1546
#2  0x0000000001d126c5 in Viewport::input (this=0x4f7caa0, p_event=...) at scene/main/viewport.cpp:2325
#3  0x0000000001d0ca63 in Viewport::_vp_input (this=0x4f7caa0, p_ev=...) at scene/main/viewport.cpp:1205
#4  0x0000000001147e42 in MethodBind1<Ref<InputEvent> const&>::call (this=0x4a89470, p_object=0x4f7caa0, p_args=0x7fffffffcc50, p_arg_count=1, r_error=...) at core/method_bind.gen.inc:729
#5  0x0000000002807367 in Object::call (this=0x4f7caa0, p_method=..., p_args=0x7fffffffcc50, p_argcount=1, r_error=...) at core/object.cpp:914
#6  0x0000000002806ea6 in Object::call (this=0x4f7caa0, p_name=..., p_arg1=..., p_arg2=..., p_arg3=..., p_arg4=..., p_arg5=...) at core/object.cpp:838
#7  0x0000000001d34ffe in SceneTree::call_group_flags (this=0x4f7bc70, p_call_flags=2, p_group=..., p_function=..., p_arg1=..., p_arg2=..., p_arg3=..., p_arg4=..., p_arg5=...)
    at scene/main/scene_tree.cpp:250
#8  0x0000000001d35ce3 in SceneTree::input_event (this=0x4f7bc70, p_event=...) at scene/main/scene_tree.cpp:406
#9  0x0000000000eb349b in InputDefault::parse_input_event (this=0x49aab30, p_event=...) at main/input_default.cpp:346
#10 0x0000000000ea3cd2 in OS_X11::process_xevents (this=0x7fffffffd510) at platform/x11/os_x11.cpp:1762
#11 0x0000000000ea6c67 in OS_X11::run (this=0x7fffffffd510) at platform/x11/os_x11.cpp:2388
#12 0x0000000000e9bfcb in main (argc=1, argv=0x7fffffffda28) at platform/x11/godot_x11.cpp:55

In some cases I had no crash/backtrace but an infinite loop instead:

ERROR: _modal_stack_remove: Condition ' !is_inside_tree() ' is true.
   At: scene/gui/control.cpp:2113.
ERROR: affine_invert: Condition ' det == 0 ' is true.
   At: core/math/math_2d.cpp:326.
ERROR: _modal_stack_remove: Condition ' !is_inside_tree() ' is true.
   At: scene/gui/control.cpp:2113.
ERROR: affine_invert: Condition ' det == 0 ' is true.
   At: core/math/math_2d.cpp:326.

(not sure which of the two is the first message, it loops too fast :))

groud commented 6 years ago

Note, I can't reproduce with current master on linux.

Sorry, I was mislead by the fact the editor does not crashes.

groud commented 6 years ago

Also, I'm quite surprised of this error:

ERROR: _modal_stack_remove: Condition ' !is_inside_tree() ' is true.
   At: scene/gui/control.cpp:2113.

THe only place where _modal_stack_remove is called in control.cpp is surrounded by if (is_inside_tree())

vnen commented 6 years ago

The only place where _modal_stack_remove is called in control.cpp is surrounded by if (is_inside_tree())

The error is thrown on control.cpp, but the caller can be anywhere. This function is also called from scene/main/viewport.cpp.

groud commented 6 years ago

I though it was a private function due to the underscore. But I might have found the problem. Compiling ^^

vnen commented 6 years ago

Well, it is a private function, but Viewport is a friend class.

groud commented 6 years ago

I can't tell what's happening. For now the only thing I figured out is that the top variable around line 1546 in viewport.cpp seems wrong (not null, but the function pointer given by top->get_global_tranform_with_canvas is 0).

johnnygossdev commented 6 years ago

Hi everyone, I'm not sure if it's related but I got a similar error.

I can't confirm what caused it because I was tabbed in my browser at the time. When I tabbed back, I got this error message:

CrashHandlerException: Program crashed
Dumping the backtrace. Please include this when reporting the bug on https://github.com/godotengine/godot/issues
[0] RegisterProcTableCallback
[1] DrvGetLayerPaletteEntries
[2] RegisterProcTableCallback
[3] RegisterProcTableCallback
[4] RegisterProcTableCallback
[5] <couldn't map PC to fn name>
[6] <couldn't map PC to fn name>
[7] <couldn't map PC to fn name>
[8] <couldn't map PC to fn name>
[9] <couldn't map PC to fn name>
[10] <couldn't map PC to fn name>
[11] <couldn't map PC to fn name>
[12] <couldn't map PC to fn name>
[13] <couldn't map PC to fn name>
[14] <couldn't map PC to fn name>
[15] <couldn't map PC to fn name>
[16] <couldn't map PC to fn name>
[17] <couldn't map PC to fn name>
[18] BaseThreadInitThunk
-- END OF BACKTRACE --

Using RC3

binbitten commented 6 years ago

Hold my beer.

1 - In the provided project - object_stack.gd:

func _gui_input(event):
    if event is InputEventMouseButton and event.button_index == BUTTON_RIGHT:
        show_menu(get_global_transform().get_origin() + event.position)
        accept_event()

_showmenu() will be called for both press and release. Easy workaround of the crash is to only handle press or release.

2 - Cause of the crash: Viewport::_gui_show_modal() (called by menu.popup() at some point) calls guiinput() to release the mouse focus. Because of this and 1, gui_showmodal() is essentially called within itself and causes the modal_stack to be in the wrong order (which causes the crash later on).

3 - Realized that, because of how the mouse focus is released in 2, a control will handle release-input before press-input which will e.g. cause a button to stay pressed down. Am not too familiar with the code, but the solution might be to delay releasing the focus, e.g. (in _gui_show_modal()):

MessageQueue::get_singleton()->push_notification(this, SceneTree::NOTIFICATION_WM_FOCUS_OUT);

This will fix both 2 and 3, though I'm not quite sure of the implications.

akien-mga commented 6 years ago

Nice job! Since the bug is triggered by a user script error, I guess it's not too critical to fix right before 3.0, so moving to the next milestone.

Malkverbena commented 6 years ago

@binbitten Nice job. I have changed my script and everything works fine now.

if event is InputEventMouseButton and event.button_index == BUTTON_RIGHT:
    if menu == null:
        show_menu(get_global_transform().get_origin() + event.position)
        accept_event()
reduz commented 5 years ago

This was fixed months ago, also tested and can't reproduce crash. Closing.