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

Data races when adding and removing nodes(Area2D, RigidBody2D) with physics multi threading #47489

Open
Tracked by #45334
qarmin opened this issue Mar 30, 2021 · 0 comments

Comments

@qarmin
Copy link
Contributor

qarmin commented Mar 30, 2021

Godot version:
3.3.rc.custom_build. 7696f88

OS/device including version:
Ubuntu 20.04 CI

Issue description:
This errors are shown when adding, moving and removing nodes in project(thread sanitizer output)

2021-03-30T07:54:15.3490375Z WARNING: ThreadSanitizer: data race (pid=12978)
2021-03-30T07:54:15.3491718Z   Read of size 8 at 0x7b5400f924c8 by main thread (mutexes: write M653157477961114776, write M646683553496772888, write M148472844719324248, write M141998920254982360, write M406022448409990488, write M399548523945648600, write M393919024409996760, write M998527274383313368, write M100059148723385496, write M106533073187727384, write M760399444086866712, write M766873368551208600, write M387445099945654872):
2021-03-30T07:54:15.3493214Z     #0 memcpy <null> (godot.x11.tools.64.llvms+0x15adf57)
2021-03-30T07:54:15.3494924Z     #1 Body2DSW::get_linear_velocity() const /home/runner/work/RegressionTestProject/RegressionTestProject/godot/servers/physics_2d/body_2d_sw.h:192:62 (godot.x11.tools.64.llvms+0x66426bb)
2021-03-30T07:54:15.3497789Z     #2 Physics2DDirectBodyStateSW::get_linear_velocity() const /home/runner/work/RegressionTestProject/RegressionTestProject/godot/servers/physics_2d/body_2d_sw.h:361:61 (godot.x11.tools.64.llvms+0x6972b09)
2021-03-30T07:54:15.3500411Z     #3 RigidBody2D::_direct_state_changed(Object*) /home/runner/work/RegressionTestProject/RegressionTestProject/godot/scene/2d/physics_body_2d.cpp:453:27 (godot.x11.tools.64.llvms+0x5ac2d4d)
2021-03-30T07:54:15.3510695Z     #4 MethodBind1<Object*>::call(Object*, Variant const**, int, Variant::CallError&) /home/runner/work/RegressionTestProject/RegressionTestProject/godot/./core/method_bind.gen.inc:775:3 (godot.x11.tools.64.llvms+0x17cb339)
2021-03-30T07:54:15.3513265Z     #5 Object::call(StringName const&, Variant const**, int, Variant::CallError&) /home/runner/work/RegressionTestProject/RegressionTestProject/godot/core/object.cpp:919:17 (godot.x11.tools.64.llvms+0x6caa6cf)
2021-03-30T07:54:15.3515515Z     #6 Body2DSW::call_queries() /home/runner/work/RegressionTestProject/RegressionTestProject/godot/servers/physics_2d/body_2d_sw.cpp:621:10 (godot.x11.tools.64.llvms+0x696fd13)
2021-03-30T07:54:15.3517643Z     #7 Space2DSW::call_queries() /home/runner/work/RegressionTestProject/RegressionTestProject/godot/servers/physics_2d/space_2d_sw.cpp:1296:6 (godot.x11.tools.64.llvms+0x66abf46)
2021-03-30T07:54:15.3519895Z     #8 Physics2DServerSW::flush_queries() /home/runner/work/RegressionTestProject/RegressionTestProject/godot/servers/physics_2d/physics_2d_server_sw.cpp:1360:10 (godot.x11.tools.64.llvms+0x663ef0f)
2021-03-30T07:54:15.3522325Z     #9 Physics2DServerWrapMT::flush_queries() /home/runner/work/RegressionTestProject/RegressionTestProject/godot/servers/physics_2d/physics_2d_server_wrap_mt.cpp:99:21 (godot.x11.tools.64.llvms+0x664d023)
2021-03-30T07:54:15.3524598Z     #10 Main::iteration() /home/runner/work/RegressionTestProject/RegressionTestProject/godot/main/main.cpp:2098:37 (godot.x11.tools.64.llvms+0x16d0117)
2021-03-30T07:54:15.3526670Z     #11 OS_X11::run() /home/runner/work/RegressionTestProject/RegressionTestProject/godot/platform/x11/os_x11.cpp:3641:7 (godot.x11.tools.64.llvms+0x1658906)
2021-03-30T07:54:15.3529740Z     #12 main /home/runner/work/RegressionTestProject/RegressionTestProject/godot/platform/x11/godot_x11.cpp:56:6 (godot.x11.tools.64.llvms+0x163378a)
2021-03-30T07:54:15.3530759Z 
2021-03-30T07:54:15.3531220Z   Previous write of size 8 at 0x7b5400f924c8 by thread T15:
2021-03-30T07:54:15.3532002Z     #0 memcpy <null> (godot.x11.tools.64.llvms+0x15adf57)
2021-03-30T07:54:15.3533716Z     #1 Body2DSW::set_state(Physics2DServer::BodyState, Variant const&) /home/runner/work/RegressionTestProject/RegressionTestProject/godot/servers/physics_2d/body_2d_sw.cpp:328:21 (godot.x11.tools.64.llvms+0x696e311)
2021-03-30T07:54:15.3536685Z     #2 Physics2DServerSW::body_set_state(RID, Physics2DServer::BodyState, Variant const&) /home/runner/work/RegressionTestProject/RegressionTestProject/godot/servers/physics_2d/physics_2d_server_sw.cpp:836:8 (godot.x11.tools.64.llvms+0x663a750)
2021-03-30T07:54:15.3540035Z     #3 CommandQueueMT::Command3<Physics2DServer, void (Physics2DServer::*)(RID, Physics2DServer::BodyState, Variant const&), RID, Physics2DServer::BodyState, Variant>::call() /home/runner/work/RegressionTestProject/RegressionTestProject/godot/./core/command_queue_mt.h:301:2 (godot.x11.tools.64.llvms+0x667e8cf)
2021-03-30T07:54:15.3543072Z     #4 CommandQueueMT::flush_one(bool) /home/runner/work/RegressionTestProject/RegressionTestProject/godot/./core/command_queue_mt.h:440:8 (godot.x11.tools.64.llvms+0x665e040)
2021-03-30T07:54:15.3545511Z     #5 CommandQueueMT::wait_and_flush_one() /home/runner/work/RegressionTestProject/RegressionTestProject/godot/./core/command_queue_mt.h:473:3 (godot.x11.tools.64.llvms+0x664e08c)
2021-03-30T07:54:15.3547849Z     #6 Physics2DServerWrapMT::thread_loop() /home/runner/work/RegressionTestProject/RegressionTestProject/godot/servers/physics_2d/physics_2d_server_wrap_mt.cpp:63:17 (godot.x11.tools.64.llvms+0x664cc4f)
2021-03-30T07:54:15.3551632Z     #7 Physics2DServerWrapMT::_thread_callback(void*) /home/runner/work/RegressionTestProject/RegressionTestProject/godot/servers/physics_2d/physics_2d_server_wrap_mt.cpp:50:8 (godot.x11.tools.64.llvms+0x664cb10)
2021-03-30T07:54:15.3590557Z     #8 Thread::callback(Thread*, Thread::Settings const&, void (*)(void*), void*) /home/runner/work/RegressionTestProject/RegressionTestProject/godot/core/os/thread.cpp:75:2 (godot.x11.tools.64.llvms+0x6ef9db2)
2021-03-30T07:54:15.3599110Z     #9 void std::__invoke_impl<void, void (*)(Thread*, Thread::Settings const&, void (*)(void*), void*), Thread*, Thread::Settings, void (*)(void*), void*>(std::__invoke_other, void (*&&)(Thread*, Thread::Settings const&, void (*)(void*), void*), Thread*&&, Thread::Settings&&, void (*&&)(void*), void*&&) /usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/invoke.h:60:14 (godot.x11.tools.64.llvms+0x6efb9c3)
2021-03-30T07:54:15.3606348Z     #10 std::__invoke_result<void (*)(Thread*, Thread::Settings const&, void (*)(void*), void*), Thread*, Thread::Settings, void (*)(void*), void*>::type std::__invoke<void (*)(Thread*, Thread::Settings const&, void (*)(void*), void*), Thread*, Thread::Settings, void (*)(void*), void*>(void (*&&)(Thread*, Thread::Settings const&, void (*)(void*), void*), Thread*&&, Thread::Settings&&, void (*&&)(void*), void*&&) /usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/invoke.h:95:14 (godot.x11.tools.64.llvms+0x6efb6b7)
2021-03-30T07:54:15.3650458Z     #11 void std::thread::_Invoker<std::tuple<void (*)(Thread*, Thread::Settings const&, void (*)(void*), void*), Thread*, Thread::Settings, void (*)(void*), void*> >::_M_invoke<0ul, 1ul, 2ul, 3ul, 4ul>(std::_Index_tuple<0ul, 1ul, 2ul, 3ul, 4ul>) /usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/thread:264:13 (godot.x11.tools.64.llvms+0x6efb5e3)
2021-03-30T07:54:15.3653468Z     #12 std::thread::_Invoker<std::tuple<void (*)(Thread*, Thread::Settings const&, void (*)(void*), void*), Thread*, Thread::Settings, void (*)(void*), void*> >::operator()() /usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/thread:271:11 (godot.x11.tools.64.llvms+0x6efb518)
2021-03-30T07:54:15.3656226Z     #13 std::thread::_State_impl<std::thread::_Invoker<std::tuple<void (*)(Thread*, Thread::Settings const&, void (*)(void*), void*), Thread*, Thread::Settings, void (*)(void*), void*> > >::_M_run() /usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/thread:215:13 (godot.x11.tools.64.llvms+0x6efaebf)
2021-03-30T07:54:15.3657938Z     #14 execute_native_thread_routine <null> (godot.x11.tools.64.llvms+0x765acc3)
2021-03-30T07:54:15.3658564Z 
2021-03-30T07:54:15.3659083Z   Location is heap block of size 536 at 0x7b5400f92400 allocated by thread T15:
2021-03-30T07:54:15.3659930Z     #0 malloc <null> (godot.x11.tools.64.llvms+0x15a2894)
2021-03-30T07:54:15.3661470Z     #1 Memory::alloc_static(unsigned long, bool) /home/runner/work/RegressionTestProject/RegressionTestProject/godot/core/os/memory.cpp:82:14 (godot.x11.tools.64.llvms+0x6eef0ff)
2021-03-30T07:54:15.3663634Z     #2 operator new(unsigned long, char const*) /home/runner/work/RegressionTestProject/RegressionTestProject/godot/core/os/memory.cpp:42:9 (godot.x11.tools.64.llvms+0x6eef056)
2021-03-30T07:54:15.3665882Z     #3 Physics2DServerSW::body_create() /home/runner/work/RegressionTestProject/RegressionTestProject/godot/servers/physics_2d/physics_2d_server_sw.cpp:582:19 (godot.x11.tools.64.llvms+0x66384f8)
2021-03-30T07:54:15.3668458Z     #4 Physics2DServerWrapMT::bodyallocn() /home/runner/work/RegressionTestProject/RegressionTestProject/godot/servers/physics_2d/physics_2d_server_wrap_mt.h:179:2 (godot.x11.tools.64.llvms+0x66763f5)
2021-03-30T07:54:15.3671192Z     #5 CommandQueueMT::CommandRet0<Physics2DServerWrapMT, int (Physics2DServerWrapMT::*)(), int>::call() /home/runner/work/RegressionTestProject/RegressionTestProject/godot/./core/command_queue_mt.h:304:2 (godot.x11.tools.64.llvms+0x665ef78)
2021-03-30T07:54:15.3673837Z     #6 CommandQueueMT::flush_one(bool) /home/runner/work/RegressionTestProject/RegressionTestProject/godot/./core/command_queue_mt.h:440:8 (godot.x11.tools.64.llvms+0x665e040)
2021-03-30T07:54:15.3676006Z     #7 CommandQueueMT::wait_and_flush_one() /home/runner/work/RegressionTestProject/RegressionTestProject/godot/./core/command_queue_mt.h:473:3 (godot.x11.tools.64.llvms+0x664e08c)
2021-03-30T07:54:15.3678337Z     #8 Physics2DServerWrapMT::thread_loop() /home/runner/work/RegressionTestProject/RegressionTestProject/godot/servers/physics_2d/physics_2d_server_wrap_mt.cpp:63:17 (godot.x11.tools.64.llvms+0x664cc4f)
2021-03-30T07:54:15.3680850Z     #9 Physics2DServerWrapMT::_thread_callback(void*) /home/runner/work/RegressionTestProject/RegressionTestProject/godot/servers/physics_2d/physics_2d_server_wrap_mt.cpp:50:8 (godot.x11.tools.64.llvms+0x664cb10)
2021-03-30T07:54:15.3683303Z     #10 Thread::callback(Thread*, Thread::Settings const&, void (*)(void*), void*) /home/runner/work/RegressionTestProject/RegressionTestProject/godot/core/os/thread.cpp:75:2 (godot.x11.tools.64.llvms+0x6ef9db2)
2021-03-30T07:54:15.3686598Z     #11 void std::__invoke_impl<void, void (*)(Thread*, Thread::Settings const&, void (*)(void*), void*), Thread*, Thread::Settings, void (*)(void*), void*>(std::__invoke_other, void (*&&)(Thread*, Thread::Settings const&, void (*)(void*), void*), Thread*&&, Thread::Settings&&, void (*&&)(void*), void*&&) /usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/invoke.h:60:14 (godot.x11.tools.64.llvms+0x6efb9c3)
2021-03-30T07:54:15.3690932Z     #12 std::__invoke_result<void (*)(Thread*, Thread::Settings const&, void (*)(void*), void*), Thread*, Thread::Settings, void (*)(void*), void*>::type std::__invoke<void (*)(Thread*, Thread::Settings const&, void (*)(void*), void*), Thread*, Thread::Settings, void (*)(void*), void*>(void (*&&)(Thread*, Thread::Settings const&, void (*)(void*), void*), Thread*&&, Thread::Settings&&, void (*&&)(void*), void*&&) /usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/invoke.h:95:14 (godot.x11.tools.64.llvms+0x6efb6b7)
2021-03-30T07:54:15.3694874Z     #13 void std::thread::_Invoker<std::tuple<void (*)(Thread*, Thread::Settings const&, void (*)(void*), void*), Thread*, Thread::Settings, void (*)(void*), void*> >::_M_invoke<0ul, 1ul, 2ul, 3ul, 4ul>(std::_Index_tuple<0ul, 1ul, 2ul, 3ul, 4ul>) /usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/thread:264:13 (godot.x11.tools.64.llvms+0x6efb5e3)
2021-03-30T07:54:15.3697890Z     #14 std::thread::_Invoker<std::tuple<void (*)(Thread*, Thread::Settings const&, void (*)(void*), void*), Thread*, Thread::Settings, void (*)(void*), void*> >::operator()() /usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/thread:271:11 (godot.x11.tools.64.llvms+0x6efb518)
2021-03-30T07:54:15.3700832Z     #15 std::thread::_State_impl<std::thread::_Invoker<std::tuple<void (*)(Thread*, Thread::Settings const&, void (*)(void*), void*), Thread*, Thread::Settings, void (*)(void*), void*> > >::_M_run() /usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/thread:215:13 (godot.x11.tools.64.llvms+0x6efaebf)
2021-03-30T07:54:15.3702650Z     #16 execute_native_thread_routine <null> (godot.x11.tools.64.llvms+0x765acc3)

CI - https://github.com/qarmin/RegressionTestProject/runs/2225466443?check_suite_focus=true
Steps to reproduce:

  1. Enable multithread physics in project settings
  2. Run project

Minimal reproduction project:

extends Node

var TIME_TO_DELETE : float = 1.0
var time_to_delete : float = TIME_TO_DELETE
	
var disabled_classes : Array = []
	
func _populate() -> void:
	for _i in range(2): # Number of created 
		for name_of_class in ClassDB.get_class_list():
			if name_of_class in disabled_classes:
				continue
			if !ClassDB.can_instance(name_of_class):
				continue
			add_child(ClassDB.instance(name_of_class))
				
				
# Populate at start
func _ready() -> void: 
	_populate()

# Move nodes a little and delete and readd them later
func _process(delta: float) -> void:
	for i in get_children():
		if i is Control:
			i._set_size(Vector2(200 * randf() - 100, 200 * randf() - 100))
		if i is Node2D:
			i.set_position(Vector2(1000 * randf() - 500, 1000 * randf() - 500))
		if i is Spatial:
			if i.get_name() != "Camera":
				i.set_scale(Vector3(delta + 1, delta + 1, delta + 1))
				i.set_translation(Vector3(10 * randf(), 10 * randf(), 10 * randf()))
			
	time_to_delete -= delta
	if time_to_delete < 0:
		time_to_delete += TIME_TO_DELETE
		
		for i in get_children():
			i.queue_free()
			
		_populate()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant