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 EditorExportPlatformWeb::~EditorExportPlatformWeb() detected by ThreadSanitizer #87995

Closed
Rubonnek opened this issue Feb 5, 2024 · 0 comments · Fixed by #88043
Closed

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 with ThreadSanitizer enabled against an empty project will generate a data race warning by ThreadSanitizer.

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 somewhere in the log:
==================
WARNING: ThreadSanitizer: data race (pid=41490)
  Write of size 1 at 0x7b500000cbc0 by main thread:
    #0 EditorExportPlatformWeb::~EditorExportPlatformWeb() /opt/godot/platform/web/export/export_plugin.cpp:717:14 (godot.linuxbsd.editor.dev.x86_64.llvm.san+0x61abdfd) (BuildId: 77398a27c54674f8)
    #1 void memdelete<EditorExportPlatform>(EditorExportPlatform*) /opt/godot/./core/os/memory.h:109:13 (godot.linuxbsd.editor.dev.x86_64.llvm.san+0x628f507) (BuildId: 77398a27c54674f8)
    #2 Ref<EditorExportPlatform>::unref() /opt/godot/./core/object/ref_counted.h:210:4 (godot.linuxbsd.editor.dev.x86_64.llvm.san+0x628f507)
    #3 Ref<EditorExportPlatform>::~Ref() /opt/godot/./core/object/ref_counted.h:222:3 (godot.linuxbsd.editor.dev.x86_64.llvm.san+0x628f507)
    #4 CowData<Ref<EditorExportPlatform>>::_unref(void*) /opt/godot/./core/templates/cowdata.h:242:13 (godot.linuxbsd.editor.dev.x86_64.llvm.san+0x628f507)
    #5 CowData<Ref<EditorExportPlatform>>::~CowData() /opt/godot/./core/templates/cowdata.h:445:2 (godot.linuxbsd.editor.dev.x86_64.llvm.san+0x628dc11) (BuildId: 77398a27c54674f8)
    #6 Vector<Ref<EditorExportPlatform>>::~Vector() /opt/godot/./core/templates/vector.h:291:28 (godot.linuxbsd.editor.dev.x86_64.llvm.san+0x628dc11)
    #7 EditorExport::~EditorExport() /opt/godot/editor/export/editor_export.cpp:397:1 (godot.linuxbsd.editor.dev.x86_64.llvm.san+0x628dc11)
    #8 void memdelete<Node>(Node*) /opt/godot/./core/os/memory.h:109:13 (godot.linuxbsd.editor.dev.x86_64.llvm.san+0x708d0b9) (BuildId: 77398a27c54674f8)
    #9 Node::_notification(int) /opt/godot/scene/main/node.cpp:217:5 (godot.linuxbsd.editor.dev.x86_64.llvm.san+0x708d0b9)
    #10 Node::_notificationv(int, bool) /opt/godot/./scene/main/node.h:49:2 (godot.linuxbsd.editor.dev.x86_64.llvm.san+0x5a74b8c) (BuildId: 77398a27c54674f8)
    #11 EditorNode::_notificationv(int, bool) /opt/godot/editor/editor_node.h:123:2 (godot.linuxbsd.editor.dev.x86_64.llvm.san+0x5a74b8c)
    #12 Object::notification(int, bool) /opt/godot/core/object/object.cpp:851:3 (godot.linuxbsd.editor.dev.x86_64.llvm.san+0xa16b995) (BuildId: 77398a27c54674f8)
    #13 Object::_predelete() /opt/godot/core/object/object.cpp:198:2 (godot.linuxbsd.editor.dev.x86_64.llvm.san+0xa16b995)
    #14 predelete_handler(Object*) /opt/godot/core/object/object.cpp:2048:19 (godot.linuxbsd.editor.dev.x86_64.llvm.san+0xa183df5) (BuildId: 77398a27c54674f8)
    #15 void memdelete<Node>(Node*) /opt/godot/./core/os/memory.h:105:7 (godot.linuxbsd.editor.dev.x86_64.llvm.san+0x708d0a1) (BuildId: 77398a27c54674f8)
    #16 Node::_notification(int) /opt/godot/scene/main/node.cpp:217:5 (godot.linuxbsd.editor.dev.x86_64.llvm.san+0x708d0a1)
    #17 Node::_notificationv(int, bool) /opt/godot/./scene/main/node.h:49:2 (godot.linuxbsd.editor.dev.x86_64.llvm.san+0x71dfd46) (BuildId: 77398a27c54674f8)
    #18 Viewport::_notificationv(int, bool) /opt/godot/./scene/main/viewport.h:95:2 (godot.linuxbsd.editor.dev.x86_64.llvm.san+0x71dfd46)
    #19 Window::_notificationv(int, bool) /opt/godot/scene/main/window.h:45:2 (godot.linuxbsd.editor.dev.x86_64.llvm.san+0x71dfd46)
    #20 Object::notification(int, bool) /opt/godot/core/object/object.cpp:851:3 (godot.linuxbsd.editor.dev.x86_64.llvm.san+0xa16b995) (BuildId: 77398a27c54674f8)
    #21 Object::_predelete() /opt/godot/core/object/object.cpp:198:2 (godot.linuxbsd.editor.dev.x86_64.llvm.san+0xa16b995)
    #22 predelete_handler(Object*) /opt/godot/core/object/object.cpp:2048:19 (godot.linuxbsd.editor.dev.x86_64.llvm.san+0xa183df5) (BuildId: 77398a27c54674f8)
    #23 void memdelete<Window>(Window*) /opt/godot/./core/os/memory.h:105:7 (godot.linuxbsd.editor.dev.x86_64.llvm.san+0x70f3acd) (BuildId: 77398a27c54674f8)
    #24 SceneTree::finalize() /opt/godot/scene/main/scene_tree.cpp:628:3 (godot.linuxbsd.editor.dev.x86_64.llvm.san+0x70f3acd)
    #25 OS_LinuxBSD::run() /opt/godot/platform/linuxbsd/os_linuxbsd.cpp:950:13 (godot.linuxbsd.editor.dev.x86_64.llvm.san+0x3ba24c7) (BuildId: 77398a27c54674f8)
    #26 main /opt/godot/platform/linuxbsd/godot_linuxbsd.cpp:74:6 (godot.linuxbsd.editor.dev.x86_64.llvm.san+0x3b91e34) (BuildId: 77398a27c54674f8)

  Previous read of size 1 at 0x7b500000cbc0 by thread T48:
    #0 EditorExportPlatformWeb::_server_thread_poll(void*) /opt/godot/platform/web/export/export_plugin.cpp:679:14 (godot.linuxbsd.editor.dev.x86_64.llvm.san+0x61ab2ed) (BuildId: 77398a27c54674f8)
    #1 Thread::callback(unsigned long, Thread::Settings const&, void (*)(void*), void*) /opt/godot/core/os/thread.cpp:64:3 (godot.linuxbsd.editor.dev.x86_64.llvm.san+0x98e20a8) (BuildId: 77398a27c54674f8)
    #2 void std::__invoke_impl<void, void (*)(unsigned long, Thread::Settings const&, void (*)(void*), void*), unsigned long, Thread::Settings, void (*)(void*), void*>(std::__invoke_other, void (*&&)(unsigned long, Thread::Settings const&, void (*)(void*), void*), unsigned long&&, Thread::Settings&&, void (*&&)(void*
), void*&&) /usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/13.2.1/../../../../include/c++/13.2.1/bits/invoke.h:61:14 (godot.linuxbsd.editor.dev.x86_64.llvm.san+0x98e25b3) (BuildId: 77398a27c54674f8)
    #3 std::__invoke_result<void (*)(unsigned long, Thread::Settings const&, void (*)(void*), void*), unsigned long, Thread::Settings, void (*)(void*), void*>::type std::__invoke<void (*)(unsigned long, Thread::Settings const&, void (*)(void*), void*), unsigned long, Thread::Settings, void (*)(void*), void*>(void (*&
&)(unsigned long, Thread::Settings const&, void (*)(void*), void*), unsigned long&&, Thread::Settings&&, void (*&&)(void*), void*&&) /usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/13.2.1/../../../../include/c++/13.2.1/bits/invoke.h:96:14 (godot.linuxbsd.editor.dev.x86_64.llvm.san+0x98e25b3)
    #4 void std::thread::_Invoker<std::tuple<void (*)(unsigned long, Thread::Settings const&, void (*)(void*), void*), unsigned long, Thread::Settings, void (*)(void*), void*>>::_M_invoke<0ul, 1ul, 2ul, 3ul, 4ul>(std::_Index_tuple<0ul, 1ul, 2ul, 3ul, 4ul>) /usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/13.2.1/../../../../
include/c++/13.2.1/bits/std_thread.h:292:13 (godot.linuxbsd.editor.dev.x86_64.llvm.san+0x98e25b3)
    #5 std::thread::_Invoker<std::tuple<void (*)(unsigned long, Thread::Settings const&, void (*)(void*), void*), unsigned long, Thread::Settings, void (*)(void*), void*>>::operator()() /usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/13.2.1/../../../../include/c++/13.2.1/bits/std_thread.h:299:11 (godot.linuxbsd.editor.dev.
x86_64.llvm.san+0x98e25b3)
    #6 std::thread::_State_impl<std::thread::_Invoker<std::tuple<void (*)(unsigned long, Thread::Settings const&, void (*)(void*), void*), unsigned long, Thread::Settings, void (*)(void*), void*>>>::_M_run() /usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/13.2.1/../../../../include/c++/13.2.1/bits/std_thread.h:244:13 (godo
t.linuxbsd.editor.dev.x86_64.llvm.san+0x98e25b3)
    #7 execute_native_thread_routine msdf-error-correction.cpp (godot.linuxbsd.editor.dev.x86_64.llvm.san+0xa693862) (BuildId: 77398a27c54674f8)

  Location is heap block of size 512 at 0x7b500000ca00 allocated by main thread:
    #0 malloc <null> (godot.linuxbsd.editor.dev.x86_64.llvm.san+0x3b22ba3) (BuildId: 77398a27c54674f8)
    #1 Memory::alloc_static(unsigned long, bool) /opt/godot/core/os/memory.cpp:75:14 (godot.linuxbsd.editor.dev.x86_64.llvm.san+0x98d942d) (BuildId: 77398a27c54674f8)
    #2 operator new(unsigned long, char const*) /opt/godot/core/os/memory.cpp:40:9 (godot.linuxbsd.editor.dev.x86_64.llvm.san+0x98d942d)
    #3 Ref<EditorExportPlatformWeb>::instantiate() /opt/godot/./core/object/ref_counted.h:216:7 (godot.linuxbsd.editor.dev.x86_64.llvm.san+0x6196962) (BuildId: 77398a27c54674f8)
    #4 register_web_exporter() /opt/godot/platform/web/export/export.cpp:55:11 (godot.linuxbsd.editor.dev.x86_64.llvm.san+0x61964cd) (BuildId: 77398a27c54674f8)
    #5 register_exporters() /opt/godot/editor/register_exporters.gen.cpp:14:2 (godot.linuxbsd.editor.dev.x86_64.llvm.san+0x606f903) (BuildId: 77398a27c54674f8)
    #6 EditorNode::EditorNode() /opt/godot/editor/editor_node.cpp:6465:2 (godot.linuxbsd.editor.dev.x86_64.llvm.san+0x5a49d25) (BuildId: 77398a27c54674f8)
    #7 Main::start() /opt/godot/main/main.cpp:3578:18 (godot.linuxbsd.editor.dev.x86_64.llvm.san+0x3ccea06) (BuildId: 77398a27c54674f8)
    #8 main /opt/godot/platform/linuxbsd/godot_linuxbsd.cpp:72:6 (godot.linuxbsd.editor.dev.x86_64.llvm.san+0x3b91e19) (BuildId: 77398a27c54674f8)

  Thread T48 (tid=41542, running) created by main thread at:
    #0 pthread_create <null> (godot.linuxbsd.editor.dev.x86_64.llvm.san+0x3b0da76) (BuildId: 77398a27c54674f8)
    #1 std::thread::_M_start_thread(std::unique_ptr<std::thread::_State, std::default_delete<std::thread::_State>>, void (*)()) <null> (godot.linuxbsd.editor.dev.x86_64.llvm.san+0xa693949) (BuildId: 77398a27c54674f8)
    #2 EditorExportPlatformWeb::EditorExportPlatformWeb() /opt/godot/platform/web/export/export_plugin.cpp:691:17 (godot.linuxbsd.editor.dev.x86_64.llvm.san+0x61ab421) (BuildId: 77398a27c54674f8)
    #3 Ref<EditorExportPlatformWeb>::instantiate() /opt/godot/./core/object/ref_counted.h:216:7 (godot.linuxbsd.editor.dev.x86_64.llvm.san+0x619696d) (BuildId: 77398a27c54674f8)
    #4 register_web_exporter() /opt/godot/platform/web/export/export.cpp:55:11 (godot.linuxbsd.editor.dev.x86_64.llvm.san+0x61964cd) (BuildId: 77398a27c54674f8)
    #5 register_exporters() /opt/godot/editor/register_exporters.gen.cpp:14:2 (godot.linuxbsd.editor.dev.x86_64.llvm.san+0x606f903) (BuildId: 77398a27c54674f8)
    #6 EditorNode::EditorNode() /opt/godot/editor/editor_node.cpp:6465:2 (godot.linuxbsd.editor.dev.x86_64.llvm.san+0x5a49d25) (BuildId: 77398a27c54674f8)
    #7 Main::start() /opt/godot/main/main.cpp:3578:18 (godot.linuxbsd.editor.dev.x86_64.llvm.san+0x3ccea06) (BuildId: 77398a27c54674f8)
    #8 main /opt/godot/platform/linuxbsd/godot_linuxbsd.cpp:72:6 (godot.linuxbsd.editor.dev.x86_64.llvm.san+0x3b91e19) (BuildId: 77398a27c54674f8)

SUMMARY: ThreadSanitizer: data race /opt/godot/platform/web/export/export_plugin.cpp:717:14 in EditorExportPlatformWeb::~EditorExportPlatformWeb()
==================

Minimal reproduction project (MRP)

EmptyProject.zip

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants