godotengine / godotengine/godot

Data race in `pthread_barrier_wait` detected by ThreadSanitizer upon closing the Editor

Open
#87,993 1 comment 1 reaction 0 assignees View on GitHub
bug topic:rendering
Dominant language
C++
Stars
117k
Forks
26.8k
PR merge metrics
PR metrics pending

Description

### Tested versions

https://github.com/godotengine/godot/commit/63d6bda8e95ac992da74e84b2f3be62f3d85190b - 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:
```bash
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
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"])
```
2. 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:
```bash
sudo sysctl vm.mmap_rnd_bits=28
# reverse it with: sudo sysctl vm.mmap_rnd_bits=32
```
OR disable ASLR entirely temporarily :
```bash
sudo sysctl kernel.randomize_va_space=0
# reverse it with: sudo sysctl kernel.randomize_va_space=2
```

3. 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 (godot.linuxbsd.editor.dev.x86_64.llvm.san+0x3b42151) (BuildId: 77398a27c54674f8)
#1 (libvulkan_radeon.so+0x23102d) (BuildId: 0162f9f3c2516d03ae83012d794ea26051a87d33)

Previous write of size 1 at 0x7ffef9873f40 by thread T40:
#0 pthread_barrier_destroy (godot.linuxbsd.editor.dev.x86_64.llvm.san+0x3b2499f) (BuildId: 77398a27c54674f8)
#1 (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 (godot.linuxbsd.editor.dev.x86_64.llvm.san+0x3b0da76) (BuildId: 77398a27c54674f8)
#1 (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 (godot.linuxbsd.editor.dev.x86_64.llvm.san+0x3b0da76) (BuildId: 77398a27c54674f8)
#1 (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](https://github.com/godotengine/godot/files/14171510/EmptyProject.zip)

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.