-
-
Notifications
You must be signed in to change notification settings - Fork 22k
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
Prevent crashes when removing Viewport from scene tree in event handler #77763
Conversation
CC @Sauermann |
A few lines above, the Line 2956 in 621d68e
So it looks more like a problem that an event is not set as handled. |
In fact, all three of these checks are performed before that line. Unless they can mutate in the process, this doesn't seem correct. |
That is exactly the problem here, as the event handlers can have arbitrary effects, including those that violate preconditions of further handling of events. This PR tries to prevent the further handling by re-checking the preconditions, while #77765 tries to be more specific and stops further processing in just this case by marking the event as handled after hiding the dialog. |
If an event leads to the mutation of these states, then the event was processed and should be set to as handled.
If that should be the way, then it would be prudent to perform the inside_tree-check (and the other checks) between all input event processing steps. Currently it is only checked at the beginning of event processing.
|
131cd88
to
c4db212
Compare
This PR now tries to prevent crashes like #77752 in general by rechecking if the viewport is still in the tree every time when attempting to access the tree after executing arbitrary event handlers. This should stop things from crashing if any other (user) code makes an error like this as well. #77765 then fixes AcceptDialog specifically and prevents it from triggering these errors. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems ok, but I wonder if those should be DEV_ASSERT
s instead of ERR_FAIL_COND
. I wonder what impact it would have on performance when used at runtime, for something which is aimed at catching and prevent engine bugs IIUC.
If these trigger it will crash anyways, so there is no point in making these |
ERR_FAIL makes sense, because the crash can be triggered by user code, e.g. func _input(event: InputEvent) -> void:
get_viewport().get_parent().remove_child(get_viewport())
|
Godot doesn't catch all possible crashes, that can be caused by user code. In this case the crash can be prevented by the user simply by accepting the event with the following change: func _input(event: InputEvent) -> void:
get_viewport().get_parent().remove_child(get_viewport())
get_viewport().set_input_as_handled() |
Well, we try to when presented with a repro case. If you end up with this code from KoBeWi and experience the crash, there is no way to know that you can fix it as you describe. So that shouldn't happen. |
Thanks! |
Fixes #77752
These checks were removed by #77452, only theis_inside_tree
is strictly necessary to fix the crash, I re-added the other two just to be on the safe side, I don't think any other the checks inpush_unhandled_input
can have changed sincepush_input
has checked them.If during the processing of an event, some event handler removes the viewport associated with the event from the scene tree without marking the event as handled, when the event processing continues it will try to access the tree and crash. This makes this an error instead of an crash.