godotengine / godot

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

Area2D can crash with multi-threaded physics #50470

Open Avantir-Chaosfire opened 3 years ago

Avantir-Chaosfire commented 3 years ago

Godot version

3.2.1 (Looks to be present in 4.0.0 too, but haven't tested)

System information

Windows 10

Issue description

I have some Area2Ds in my game whose polygonal hitboxes are animated as part of enemy attacks. This all works fine until I set the physics/2d/thread_model to Multi-Threaded, which I did to allow my game to instance a loading scene as part of the background loading thread during the loading screen (Turns out it also works with Single-Unsafe, but anyways). Having set that to Multi-Threaded, I now get irregular crashes when the hitboxes are animated. Usually this results in a silent crash - no error message at all. But one time, I got this: No message crash (Relevant line number is 46 in 4.0.0) It looks like this is due to this bit of code in area_2d_sw.cpp:

if (!moved_list.in_list() && get_space()) {
    get_space()->area_add_to_moved_list(&moved_list);
}

which happens in a number of places, and is not thread safe. The List throws the above error when a single SelfList is added to it multiple times.

Steps to reproduce

  1. Set physics/2d/thread_model to Multi-Threaded.
  2. Create an Area2D with a polygonal hitbox
  3. Use an AnimationPlayer to continually move the vertices of the Area2D's polygon
  4. Wait - the game should eventually freeze and then crash with no error

The more Area2Ds you use the faster the issue should occur (I found it happened quite reliably with 6 Area2Ds being animated over ~1 second (90% of the time) - but very inconsistently with 1 Area2D being animated over 3 seconds (5% of the time))

Minimal reproduction project

Built on Godot 3.2.1 with mono

BackgroundSceneInstanceBug.zip

Calinou commented 3 years ago

@Avantir-Chaosfire Please upload a minimal reproduction project to make this easier to troubleshoot.

Avantir-Chaosfire commented 3 years ago

Minimal reproduction project added. It launches one scene with a loading screen and a button to reload the scene. You may have to reload the scene many times before the crash occurs.

Also note that when I tried this on a Mac (instead of Windows), it just froze indefinitely instead of crashing - not sure of this is just a different manifestation of the problem or if the behaviour is different between the two OSes.