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 race in pthread_barrier_wait detected by ThreadSanitizer upon closing the Editor #87993

Open
Rubonnek opened this issue Feb 5, 2024 · 1 comment

Comments

@Rubonnek
Copy link
Member

Rubonnek commented Feb 5, 2024

Tested versions

63d6bda - reproducible

System information

Godot v4.3.dev (63d6bda) - Arch Linux #1 SMP PREEMPT_DYNAMIC Fri, 02 Feb 2024 17:03:55 +0000 - Tty - Vulkan (Forward+) - dedicated AMD Radeon RX 6900 XT (RADV NAVI21) () - AMD Ryzen 9 5950X 16-Core Processor (32 Threads)

Issue description

Closing the Editor against an empty project with ThreadSanitizer enabled will generate a data race warning in pthread_barrier_wait.

Steps to reproduce

  1. Compile Godot with ThreadSanitizer enabled -- the following is the command I used:
scons -Q -s platform=linuxbsd dev_mode=yes dev_build=yes udev=yes target=editor debug_symbols=yes precision=single bits=64 optimize=debug compiledb=yes use_llvm=yes linker=lld tests=yes use_asan=no use_tsan=yes werror=no -j$(nproc)

If you are on Arch Linux, it seems that linking to libatomic.a is unnecessary -- you may need to apply the following patch and try to compile again if it previously failed:

diff --git a/platform/linuxbsd/detect.py b/platform/linuxbsd/detect.py
index 7946ef6228..14471c2393 100644
--- a/platform/linuxbsd/detect.py
+++ b/platform/linuxbsd/detect.py
@@ -520,8 +520,6 @@ def configure(env: "Environment"):
     # Link those statically for portability
     if env["use_static_cpp"]:
         env.Append(LINKFLAGS=["-static-libgcc", "-static-libstdc++"])
-        if env["use_llvm"] and platform.system() != "FreeBSD":
-            env["LINKCOM"] = env["LINKCOM"] + " -l:libatomic.a"
     else:
         if env["use_llvm"] and platform.system() != "FreeBSD":
             env.Append(LIBS=["atomic"])
  1. Decompress the MRP below and open a terminal at the MRP project path and run:
TSAN_OPTIONS=second_deadlock_stack=1 /opt/godot/bin/godot.linuxbsd.editor.dev.x86_64.llvm.san -e

If the FATAL: ThreadSanitizer: unexpected memory mapping error appears, you may need to temporarily lower the ASLR entropy:

sudo sysctl vm.mmap_rnd_bits=28
# reverse it with: sudo sysctl vm.mmap_rnd_bits=32

OR disable ASLR entirely temporarily :

sudo sysctl kernel.randomize_va_space=0
# reverse it with: sudo sysctl kernel.randomize_va_space=2
  1. The following ThreadSanitizer warning should appear after closing the Editor:
==================
WARNING: ThreadSanitizer: data race (pid=41490)
  Read of size 1 at 0x7ffef9873f40 by thread T36:
    #0 pthread_barrier_wait <null> (godot.linuxbsd.editor.dev.x86_64.llvm.san+0x3b42151) (BuildId: 77398a27c54674f8)
    #1 <null> <null> (libvulkan_radeon.so+0x23102d) (BuildId: 0162f9f3c2516d03ae83012d794ea26051a87d33)

  Previous write of size 1 at 0x7ffef9873f40 by thread T40:
    #0 pthread_barrier_destroy <null> (godot.linuxbsd.editor.dev.x86_64.llvm.san+0x3b2499f) (BuildId: 77398a27c54674f8)
    #1 <null> <null> (libvulkan_radeon.so+0x237dac) (BuildId: 0162f9f3c2516d03ae83012d794ea26051a87d33)

  Location is stack of main thread.

  Location is global '??' at 0x7ffef9855000 ([stack]+0x1ef40)

  Thread T36 'godot.l:disk$0' (tid=41530, running) created by main thread at:
    #0 pthread_create <null> (godot.linuxbsd.editor.dev.x86_64.llvm.san+0x3b0da76) (BuildId: 77398a27c54674f8)
    #1 <null> <null> (libvulkan_radeon.so+0x44897d) (BuildId: 0162f9f3c2516d03ae83012d794ea26051a87d33)
    #2 VulkanContext::_window_create(int, DisplayServer::VSyncMode, VkSurfaceKHR_T*, int, int) /opt/godot/drivers/vulkan/vulkan_context.cpp:1853:15 (godot.linuxbsd.editor.dev.x86_64.llvm.san+0x567ec18) (BuildId: 77398a27c54674f8)
    #3 VulkanContextX11::window_create(int, DisplayServer::VSyncMode, int, int, void const*) /opt/godot/platform/linuxbsd/x11/vulkan_context_x11.cpp:56:9 (godot.linuxbsd.editor.dev.x86_64.llvm.san+0x3c4262d) (BuildId: 77398a27c54674f8)
    #4 DisplayServerX11::_create_window(DisplayServer::WindowMode, DisplayServer::VSyncMode, unsigned int, Rect2i const&) /opt/godot/platform/linuxbsd/x11/display_server_x11.cpp:5674:28 (godot.linuxbsd.editor.dev.x86_64.llvm.san+0x3bc9c91) (BuildId: 77398a27c54674f8)
    #5 DisplayServerX11::DisplayServerX11(String const&, DisplayServer::WindowMode, DisplayServer::VSyncMode, unsigned int, Vector2i const*, Vector2i const&, int, Error&) /opt/godot/platform/linuxbsd/x11/display_server_x11.cpp:6183:25 (godot.linuxbsd.editor.dev.x86_64.llvm.san+0x3be8705) (BuildId: 77398a27c54674f8)
    #6 DisplayServerX11::create_func(String const&, DisplayServer::WindowMode, DisplayServer::VSyncMode, unsigned int, Vector2i const*, Vector2i const&, int, Error&) /opt/godot/platform/linuxbsd/x11/display_server_x11.cpp:5348:22 (godot.linuxbsd.editor.dev.x86_64.llvm.san+0x3be5804) (BuildId: 77398a27c54674f8)
    #7 DisplayServer::create(int, String const&, DisplayServer::WindowMode, DisplayServer::VSyncMode, unsigned int, Vector2i const*, Vector2i const&, int, Error&) /opt/godot/servers/display_server.cpp:978:9 (godot.linuxbsd.editor.dev.x86_64.llvm.san+0x87e6993) (BuildId: 77398a27c54674f8)
    #8 Main::setup2() /opt/godot/main/main.cpp:2600:20 (godot.linuxbsd.editor.dev.x86_64.llvm.san+0x3cc0d4b) (BuildId: 77398a27c54674f8)
    #9 Main::setup(char const*, int, char**, bool) /opt/godot/main/main.cpp:2338:10 (godot.linuxbsd.editor.dev.x86_64.llvm.san+0x3cbcc0d) (BuildId: 77398a27c54674f8)
    #10 main /opt/godot/platform/linuxbsd/godot_linuxbsd.cpp:62:14 (godot.linuxbsd.editor.dev.x86_64.llvm.san+0x3b91df7) (BuildId: 77398a27c54674f8)

  Thread T40 'godot.l:disk$2' (tid=41534, running) created by main thread at:
    #0 pthread_create <null> (godot.linuxbsd.editor.dev.x86_64.llvm.san+0x3b0da76) (BuildId: 77398a27c54674f8)
    #1 <null> <null> (libvulkan_radeon.so+0x44897d) (BuildId: 0162f9f3c2516d03ae83012d794ea26051a87d33)
    #2 RenderingDevice::initialize(ApiContextRD*, bool) /opt/godot/servers/rendering/rendering_device.cpp:4915:36 (godot.linuxbsd.editor.dev.x86_64.llvm.san+0x8e1bcbf) (BuildId: 77398a27c54674f8)
    #3 DisplayServerX11::DisplayServerX11(String const&, DisplayServer::WindowMode, DisplayServer::VSyncMode, unsigned int, Vector2i const*, Vector2i const&, int, Error&) /opt/godot/platform/linuxbsd/x11/display_server_x11.cpp:6198:21 (godot.linuxbsd.editor.dev.x86_64.llvm.san+0x3be87be) (BuildId: 77398a27c54674f8)
    #4 DisplayServerX11::create_func(String const&, DisplayServer::WindowMode, DisplayServer::VSyncMode, unsigned int, Vector2i const*, Vector2i const&, int, Error&) /opt/godot/platform/linuxbsd/x11/display_server_x11.cpp:5348:22 (godot.linuxbsd.editor.dev.x86_64.llvm.san+0x3be5804) (BuildId: 77398a27c54674f8)
    #5 DisplayServer::create(int, String const&, DisplayServer::WindowMode, DisplayServer::VSyncMode, unsigned int, Vector2i const*, Vector2i const&, int, Error&) /opt/godot/servers/display_server.cpp:978:9 (godot.linuxbsd.editor.dev.x86_64.llvm.san+0x87e6993) (BuildId: 77398a27c54674f8)
    #6 Main::setup2() /opt/godot/main/main.cpp:2600:20 (godot.linuxbsd.editor.dev.x86_64.llvm.san+0x3cc0d4b) (BuildId: 77398a27c54674f8)
    #7 Main::setup(char const*, int, char**, bool) /opt/godot/main/main.cpp:2338:10 (godot.linuxbsd.editor.dev.x86_64.llvm.san+0x3cbcc0d) (BuildId: 77398a27c54674f8)
    #8 main /opt/godot/platform/linuxbsd/godot_linuxbsd.cpp:62:14 (godot.linuxbsd.editor.dev.x86_64.llvm.san+0x3b91df7) (BuildId: 77398a27c54674f8)

SUMMARY: ThreadSanitizer: data race (/opt/godot/bin/godot.linuxbsd.editor.dev.x86_64.llvm.san+0x3b42151) (BuildId: 77398a27c54674f8) in pthread_barrier_wait
==================

Minimal reproduction project (MRP)

EmptyProject.zip

@Rubonnek
Copy link
Member Author

Rubonnek commented Feb 7, 2024

Related: #77390

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