godotengine / godot

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

Data races when running Godot #32081

Open qarmin opened 5 years ago

qarmin commented 5 years ago

Godot version: 3.2.alpha.custom_build. 24e1039eb

OS/device including version: Ubuntu 19.04

Issue description: When I run Godot project manager, then thread sanitizer shows some data races(reading data in one thread, when saving in another thread)

SUMMARY: ThreadSanitizer: data race (/home/rafal/Pulpit/mojgodot/bin/godot.x11.tools.64.llvms+0x1703076) in __tsan_atomic64_fetch_add


**Steps to reproduce:**
1. Compile Godot with thread sanitizer support e.g.(newer versions of GCC compiler are a little buggy for now, so llvm is the only option)

scons p=x11 -j6 use_tsan=yes use_llvm=yes

2. Run project manager

bin/godot.x11.tools.64.llvms

pwaller commented 4 years ago

There are lots of these errors, many of them surround the refcount primitive.

I recommend reading this excellent article for some background on data races, and to understand why even "benign-looking" code often isn't benign: https://software.intel.com/en-us/blogs/2013/01/06/benign-data-races-what-could-possibly-go-wrong.

pwaller commented 4 years ago

Here is also another great reference from the thread sanitizer docs: https://github.com/google/sanitizers/wiki/ThreadSanitizerPopularDataRaces

qarmin commented 4 years ago

When running my game with Godot 3.2.2, there is a lot of more errors - Thread Sanitizer Log.txt

Strange that this happens a lot with SafeRefCount::unref() / ::ref() which as name suggest, should be safe because operate on atomic_increment and decrement

pwaller commented 4 years ago

Strange that this happens a lot with SafeRefCount::unref() / ::ref()

One issue there is that both the read and the write must be atomic or otherwise synchronized. See the language in the error messages, e.g. ("Atomic write" vs "previous read").

One of the warnings indicates for example that atomic_conditional_increment is actually doing a non-atomic read of the memory it just incremented (return tmp + 1 does a non-atomic read of tmp which is a reference to the atomically-incremented variable):

https://github.com/godotengine/godot/blob/b96b0d90d7f433c576067305c889ebb2f1dc11be/core/safe_refcount.h#L101-L109

I refer also again to https://software.intel.com/content/www/us/en/develop/blogs/benign-data-races-what-could-possibly-go-wrong.html -- I think this is actually one of the examples given in that blog post of a "what could possibly go wrong", at the end.

RandomShaper commented 4 years ago

I have plans to address much of these issues very soon. I'll fix all the wrong approaches to atomicity in 4.0 and then port them to 3.2.

My expectation is that we'll get rid of a number of hard to debug issues that stem from that.

Please stay tuned. 😄

qarmin commented 3 years ago

When running https://github.com/qarmin/RegressionTestProject/tree/3.2, then there is still huge amount of data races - 7_Use Godot.txt in 3.2.4.beta.custom_build. ebe9d61ec

qarmin commented 3 years ago

Thread sanitizer still shows with 4.0 2fa4b59f9900bd7c1d306328db71df168f61b4c5 e.g. lock-order-inversion when opening and closing editor - log.txt

akien-mga commented 1 year ago

Is this still reproducible in latest 4.x builds?

rcorre commented 1 year ago

After patching around https://github.com/godotengine/godot/issues/76581, I see a lot of lock-order-inversion warnings in 4.0.2: tsan.txt

==================
WARNING: ThreadSanitizer: lock-order-inversion (potential deadlock) (pid=80028)
  Cycle in lock order graph: M0 (0x7b5000044a10) => M1 (0x7b8800022448) => M0

  Mutex M1 acquired here while holding mutex M0 in main thread:
    #0 pthread_mutex_lock <null> (godot.linuxbsd.editor.x86_64.llvm.san+0x2e12851) (BuildId: fca740c9f8cae87822f94c6eab6045df1899fefb)
    #1 __gthread_mutex_lock(pthread_mutex_t*) /usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/12.2.1/../../../../include/c++/12.2.1/x86_64-pc-linux-gnu/bits/gthr-default.h:749:12 (godot.linuxbsd.editor.x86_64.llvm.san+0x45c5969) (BuildId: fca740c9f8cae87822f94c6eab6045df1899fefb)
    #2 __gthread_recursive_mutex_lock(pthread_mutex_t*) /usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/12.2.1/../../../../include/c++/12.2.1/x86_64-pc-linux-gnu/bits/gthr-default.h:811:10 (godot.linuxbsd.editor.x86_64.llvm.san+0x45c5969)
    #3 std::recursive_mutex::lock() /usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/12.2.1/../../../../include/c++/12.2.1/mutex:108:17 (godot.linuxbsd.editor.x86_64.llvm.san+0x45c5969)
    #4 std::unique_lock<std::recursive_mutex>::lock() /usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/12.2.1/../../../../include/c++/12.2.1/bits/unique_lock.h:139:17 (godot.linuxbsd.editor.x86_64.llvm.san+0x45c5969)
    #5 std::unique_lock<std::recursive_mutex>::unique_lock(std::recursive_mutex&) /usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/12.2.1/../../../../include/c++/12.2.1/bits/unique_lock.h:69:2 (godot.linuxbsd.editor.x86_64.llvm.san+0x45c5969)
    #6 MutexLock<MutexImpl<std::recursive_mutex>>::MutexLock(MutexImpl<std::recursive_mutex> const&) /home/rcorre/src/godot/godot/./core/os/mutex.h:122:4 (godot.linuxbsd.editor.x86_64.llvm.san+0x45c5969)
    #7 TextServerAdvanced::_shaped_text_shape(RID const&) /home/rcorre/src/godot/godot/modules/text_server_adv/text_server_adv.cpp:5543:2 (godot.linuxbsd.editor.x86_64.llvm.san+0x45c5969)
    #8 TextServerAdvanced::_shaped_text_update_breaks(RID const&) /home/rcorre/src/godot/godot/modules/text_server_adv/text_server_adv.cpp:4655:3 (godot.linuxbsd.editor.x86_64.llvm.san+0x45af220) (BuildId: fca740c9f8cae87822f94c6eab6045df1899fefb)
    #9 TextServerAdvanced::shaped_text_update_breaks(RID const&) /home/rcorre/src/godot/godot/modules/text_server_adv/text_server_adv.h:890:2 (godot.linuxbsd.editor.x86_64.llvm.san+0x45e14ba) (BuildId: fca740c9f8cae87822f94c6eab6045df1899fefb)
    #10 TextServer::shaped_text_get_line_breaks(RID const&, double, long, BitField<TextServer::LineBreakFlag>) const /home/rcorre/src/godot/godot/servers/text_server.cpp:809:34 (godot.linuxbsd.editor.x86_64.llvm.san+0x8432754) (BuildId: fca740c9f8cae87822f94c6eab6045df1899fefb)
    #11 TextServerExtension::shaped_text_get_line_breaks(RID const&, double, long, BitField<TextServer::LineBreakFlag>) const /home/rcorre/src/godot/godot/servers/text/text_server_extension.cpp:1157:21 (godot.linuxbsd.editor.x86_64.llvm.san+0x8f5da82) (BuildId: fca740c9f8cae87822f94c6eab6045df1899fefb)
    #12 Label::_shape() /home/rcorre/src/godot/godot/scene/gui/label.cpp:148:38 (godot.linuxbsd.editor.x86_64.llvm.san+0x6c8c7a5) (BuildId: fca740c9f8cae87822f94c6eab6045df1899fefb)
    #13 Label::get_minimum_size() const /home/rcorre/src/godot/godot/scene/gui/label.cpp:619:30 (godot.linuxbsd.editor.x86_64.llvm.san+0x6c9366b) (BuildId: fca740c9f8cae87822f94c6eab6045df1899fefb)
    #14 Control::_update_minimum_size_cache() /home/rcorre/src/godot/godot/scene/gui/control.cpp:1608:18 (godot.linuxbsd.editor.x86_64.llvm.san+0x6b69405) (BuildId: fca740c9f8cae87822f94c6eab6045df1899fefb)
    #15 Control::get_combined_minimum_size() const /home/rcorre/src/godot/godot/scene/gui/control.cpp:1627:32 (godot.linuxbsd.editor.x86_64.llvm.san+0x6b69405)
    #16 AcceptDialog::_get_contents_minimum_size() const /home/rcorre/src/godot/godot/scene/gui/dialogs.cpp:260:28 (godot.linuxbsd.editor.x86_64.llvm.san+0x6bb809a) (BuildId: fca740c9f8cae87822f94c6eab6045df1899fefb)
    #17 Window::get_contents_minimum_size() const /home/rcorre/src/godot/godot/scene/main/window.cpp:1566:9 (godot.linuxbsd.editor.x86_64.llvm.san+0x6a3bf9c) (BuildId: fca740c9f8cae87822f94c6eab6045df1899fefb)
    #18 Window::get_clamped_minimum_size() const /home/rcorre/src/godot/godot/scene/main/window.cpp:1574:22 (godot.linuxbsd.editor.x86_64.llvm.san+0x6a3bf9c)
    #19 Window::_update_window_size() /home/rcorre/src/godot/godot/scene/main/window.cpp:883:22 (godot.linuxbsd.editor.x86_64.llvm.san+0x6a3bf9c)
    #20 Window::set_min_size(Vector2i const&) /home/rcorre/src/godot/godot/scene/main/window.cpp:391:2 (godot.linuxbsd.editor.x86_64.llvm.san+0x6a3cac4) (BuildId: fca740c9f8cae87822f94c6eab6045df1899fefb)
    #21 ConfirmationDialog::ConfirmationDialog() /home/rcorre/src/godot/godot/scene/gui/dialogs.cpp:447:2 (godot.linuxbsd.editor.x86_64.llvm.san+0x6bbcff1) (BuildId: fca740c9f8cae87822f94c6eab6045df1899fefb)
    #22 EditorFileDialog::EditorFileDialog() /home/rcorre/src/godot/godot/editor/editor_file_dialog.cpp:1704:19 (godot.linuxbsd.editor.x86_64.llvm.san+0x5263f09) (BuildId: fca740c9f8cae87822f94c6eab6045df1899fefb)
    #23 EditorAssetLibrary::EditorAssetLibrary(bool) /home/rcorre/src/godot/godot/editor/plugins/asset_library_editor_plugin.cpp:1622:15 (godot.linuxbsd.editor.x86_64.llvm.san+0x5e7a7b9) (BuildId: fca740c9f8cae87822f94c6eab6045df1899fefb)
    #24 ProjectManager::ProjectManager() /home/rcorre/src/godot/godot/editor/project_manager.cpp:2924:19 (godot.linuxbsd.editor.x86_64.llvm.san+0x58d8e94) (BuildId: fca740c9f8cae87822f94c6eab6045df1899fefb)
    #25 Main::start() /home/rcorre/src/godot/godot/main/main.cpp:3002:31 (godot.linuxbsd.editor.x86_64.llvm.san+0x2f2b926) (BuildId: fca740c9f8cae87822f94c6eab6045df1899fefb)
    #26 main /home/rcorre/src/godot/godot/platform/linuxbsd/godot_linuxbsd.cpp:71:6 (godot.linuxbsd.editor.x86_64.llvm.san+0x2e67e41) (BuildId: fca740c9f8cae87822f94c6eab6045df1899fefb)

  Mutex M0 previously acquired by the same thread here:
    #0 pthread_mutex_lock <null> (godot.linuxbsd.editor.x86_64.llvm.san+0x2e12851) (BuildId: fca740c9f8cae87822f94c6eab6045df1899fefb)
    #1 __gthread_mutex_lock(pthread_mutex_t*) /usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/12.2.1/../../../../include/c++/12.2.1/x86_64-pc-linux-gnu/bits/gthr-default.h:749:12 (godot.linuxbsd.editor.x86_64.llvm.san+0x45af1e6) (BuildId: fca740c9f8cae87822f94c6eab6045df1899fefb)
    #2 __gthread_recursive_mutex_lock(pthread_mutex_t*) /usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/12.2.1/../../../../include/c++/12.2.1/x86_64-pc-linux-gnu/bits/gthr-default.h:811:10 (godot.linuxbsd.editor.x86_64.llvm.san+0x45af1e6)
    #3 std::recursive_mutex::lock() /usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/12.2.1/../../../../include/c++/12.2.1/mutex:108:17 (godot.linuxbsd.editor.x86_64.llvm.san+0x45af1e6)
    #4 std::unique_lock<std::recursive_mutex>::lock() /usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/12.2.1/../../../../include/c++/12.2.1/bits/unique_lock.h:139:17 (godot.linuxbsd.editor.x86_64.llvm.san+0x45af1e6)
    #5 std::unique_lock<std::recursive_mutex>::unique_lock(std::recursive_mutex&) /usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/12.2.1/../../../../include/c++/12.2.1/bits/unique_lock.h:69:2 (godot.linuxbsd.editor.x86_64.llvm.san+0x45af1e6)
    #6 MutexLock<MutexImpl<std::recursive_mutex>>::MutexLock(MutexImpl<std::recursive_mutex> const&) /home/rcorre/src/godot/godot/./core/os/mutex.h:122:4 (godot.linuxbsd.editor.x86_64.llvm.san+0x45af1e6)
    #7 TextServerAdvanced::_shaped_text_update_breaks(RID const&) /home/rcorre/src/godot/godot/modules/text_server_adv/text_server_adv.cpp:4653:12 (godot.linuxbsd.editor.x86_64.llvm.san+0x45af1e6)
    #8 TextServerAdvanced::shaped_text_update_breaks(RID const&) /home/rcorre/src/godot/godot/modules/text_server_adv/text_server_adv.h:890:2 (godot.linuxbsd.editor.x86_64.llvm.san+0x45e14ba) (BuildId: fca740c9f8cae87822f94c6eab6045df1899fefb)
    #9 TextServer::shaped_text_get_line_breaks(RID const&, double, long, BitField<TextServer::LineBreakFlag>) const /home/rcorre/src/godot/godot/servers/text_server.cpp:809:34 (godot.linuxbsd.editor.x86_64.llvm.san+0x8432754) (BuildId: fca740c9f8cae87822f94c6eab6045df1899fefb)
    #10 TextServerExtension::shaped_text_get_line_breaks(RID const&, double, long, BitField<TextServer::LineBreakFlag>) const /home/rcorre/src/godot/godot/servers/text/text_server_extension.cpp:1157:21 (godot.linuxbsd.editor.x86_64.llvm.san+0x8f5da82) (BuildId: fca740c9f8cae87822f94c6eab6045df1899fefb)
    #11 Label::_shape() /home/rcorre/src/godot/godot/scene/gui/label.cpp:148:38 (godot.linuxbsd.editor.x86_64.llvm.san+0x6c8c7a5) (BuildId: fca740c9f8cae87822f94c6eab6045df1899fefb)
    #12 Label::get_minimum_size() const /home/rcorre/src/godot/godot/scene/gui/label.cpp:619:30 (godot.linuxbsd.editor.x86_64.llvm.san+0x6c9366b) (BuildId: fca740c9f8cae87822f94c6eab6045df1899fefb)
    #13 Control::_update_minimum_size_cache() /home/rcorre/src/godot/godot/scene/gui/control.cpp:1608:18 (godot.linuxbsd.editor.x86_64.llvm.san+0x6b69405) (BuildId: fca740c9f8cae87822f94c6eab6045df1899fefb)
    #14 Control::get_combined_minimum_size() const /home/rcorre/src/godot/godot/scene/gui/control.cpp:1627:32 (godot.linuxbsd.editor.x86_64.llvm.san+0x6b69405)
    #15 AcceptDialog::_get_contents_minimum_size() const /home/rcorre/src/godot/godot/scene/gui/dialogs.cpp:260:28 (godot.linuxbsd.editor.x86_64.llvm.san+0x6bb809a) (BuildId: fca740c9f8cae87822f94c6eab6045df1899fefb)
    #16 Window::get_contents_minimum_size() const /home/rcorre/src/godot/godot/scene/main/window.cpp:1566:9 (godot.linuxbsd.editor.x86_64.llvm.san+0x6a3bf9c) (BuildId: fca740c9f8cae87822f94c6eab6045df1899fefb)
    #17 Window::get_clamped_minimum_size() const /home/rcorre/src/godot/godot/scene/main/window.cpp:1574:22 (godot.linuxbsd.editor.x86_64.llvm.san+0x6a3bf9c)
    #18 Window::_update_window_size() /home/rcorre/src/godot/godot/scene/main/window.cpp:883:22 (godot.linuxbsd.editor.x86_64.llvm.san+0x6a3bf9c)
    #19 Window::set_min_size(Vector2i const&) /home/rcorre/src/godot/godot/scene/main/window.cpp:391:2 (godot.linuxbsd.editor.x86_64.llvm.san+0x6a3cac4) (BuildId: fca740c9f8cae87822f94c6eab6045df1899fefb)
    #20 ConfirmationDialog::ConfirmationDialog() /home/rcorre/src/godot/godot/scene/gui/dialogs.cpp:447:2 (godot.linuxbsd.editor.x86_64.llvm.san+0x6bbcff1) (BuildId: fca740c9f8cae87822f94c6eab6045df1899fefb)
    #21 EditorFileDialog::EditorFileDialog() /home/rcorre/src/godot/godot/editor/editor_file_dialog.cpp:1704:19 (godot.linuxbsd.editor.x86_64.llvm.san+0x5263f09) (BuildId: fca740c9f8cae87822f94c6eab6045df1899fefb)
    #22 EditorAssetLibrary::EditorAssetLibrary(bool) /home/rcorre/src/godot/godot/editor/plugins/asset_library_editor_plugin.cpp:1622:15 (godot.linuxbsd.editor.x86_64.llvm.san+0x5e7a7b9) (BuildId: fca740c9f8cae87822f94c6eab6045df1899fefb)
    #23 ProjectManager::ProjectManager() /home/rcorre/src/godot/godot/editor/project_manager.cpp:2924:19 (godot.linuxbsd.editor.x86_64.llvm.san+0x58d8e94) (BuildId: fca740c9f8cae87822f94c6eab6045df1899fefb)
    #24 Main::start() /home/rcorre/src/godot/godot/main/main.cpp:3002:31 (godot.linuxbsd.editor.x86_64.llvm.san+0x2f2b926) (BuildId: fca740c9f8cae87822f94c6eab6045df1899fefb)
    #25 main /home/rcorre/src/godot/godot/platform/linuxbsd/godot_linuxbsd.cpp:71:6 (godot.linuxbsd.editor.x86_64.llvm.san+0x2e67e41) (BuildId: fca740c9f8cae87822f94c6eab6045df1899fefb)

  Mutex M0 acquired here while holding mutex M1 in main thread:
    #0 pthread_mutex_lock <null> (godot.linuxbsd.editor.x86_64.llvm.san+0x2e12851) (BuildId: fca740c9f8cae87822f94c6eab6045df1899fefb)
    #1 __gthread_mutex_lock(pthread_mutex_t*) /usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/12.2.1/../../../../include/c++/12.2.1/x86_64-pc-linux-gnu/bits/gthr-default.h:749:12 (godot.linuxbsd.editor.x86_64.llvm.san+0x45a98ce) (BuildId: fca740c9f8cae87822f94c6eab6045df1899fefb)
    #2 __gthread_recursive_mutex_lock(pthread_mutex_t*) /usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/12.2.1/../../../../include/c++/12.2.1/x86_64-pc-linux-gnu/bits/gthr-default.h:811:10 (godot.linuxbsd.editor.x86_64.llvm.san+0x45a98ce)
    #3 std::recursive_mutex::lock() /usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/12.2.1/../../../../include/c++/12.2.1/mutex:108:17 (godot.linuxbsd.editor.x86_64.llvm.san+0x45a98ce)
    #4 std::unique_lock<std::recursive_mutex>::lock() /usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/12.2.1/../../../../include/c++/12.2.1/bits/unique_lock.h:139:17 (godot.linuxbsd.editor.x86_64.llvm.san+0x45a98ce)
    #5 std::unique_lock<std::recursive_mutex>::unique_lock(std::recursive_mutex&) /usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/12.2.1/../../../../include/c++/12.2.1/bits/unique_lock.h:69:2 (godot.linuxbsd.editor.x86_64.llvm.san+0x45a98ce)
    #6 MutexLock<MutexImpl<std::recursive_mutex>>::MutexLock(MutexImpl<std::recursive_mutex> const&) /home/rcorre/src/godot/godot/./core/os/mutex.h:122:4 (godot.linuxbsd.editor.x86_64.llvm.san+0x45a98ce)
    #7 TextServerAdvanced::_shaped_text_substr(RID const&, long, long) const /home/rcorre/src/godot/godot/modules/text_server_adv/text_server_adv.cpp:4089:12 (godot.linuxbsd.editor.x86_64.llvm.san+0x45a98ce)
    #8 TextServerAdvanced::shaped_text_substr(RID const&, long, long) const /home/rcorre/src/godot/godot/modules/text_server_adv/text_server_adv.h:883:2 (godot.linuxbsd.editor.x86_64.llvm.san+0x45e12da) (BuildId: fca740c9f8cae87822f94c6eab6045df1899fefb)
    #9 Label::_shape() /home/rcorre/src/godot/godot/scene/gui/label.cpp:150:19 (godot.linuxbsd.editor.x86_64.llvm.san+0x6c8c905) (BuildId: fca740c9f8cae87822f94c6eab6045df1899fefb)
    #10 Label::get_minimum_size() const /home/rcorre/src/godot/godot/scene/gui/label.cpp:619:30 (godot.linuxbsd.editor.x86_64.llvm.san+0x6c9366b) (BuildId: fca740c9f8cae87822f94c6eab6045df1899fefb)
    #11 Control::_update_minimum_size_cache() /home/rcorre/src/godot/godot/scene/gui/control.cpp:1608:18 (godot.linuxbsd.editor.x86_64.llvm.san+0x6b69405) (BuildId: fca740c9f8cae87822f94c6eab6045df1899fefb)
    #12 Control::get_combined_minimum_size() const /home/rcorre/src/godot/godot/scene/gui/control.cpp:1627:32 (godot.linuxbsd.editor.x86_64.llvm.san+0x6b69405)
    #13 AcceptDialog::_get_contents_minimum_size() const /home/rcorre/src/godot/godot/scene/gui/dialogs.cpp:260:28 (godot.linuxbsd.editor.x86_64.llvm.san+0x6bb809a) (BuildId: fca740c9f8cae87822f94c6eab6045df1899fefb)
    #14 Window::get_contents_minimum_size() const /home/rcorre/src/godot/godot/scene/main/window.cpp:1566:9 (godot.linuxbsd.editor.x86_64.llvm.san+0x6a3bf9c) (BuildId: fca740c9f8cae87822f94c6eab6045df1899fefb)
    #15 Window::get_clamped_minimum_size() const /home/rcorre/src/godot/godot/scene/main/window.cpp:1574:22 (godot.linuxbsd.editor.x86_64.llvm.san+0x6a3bf9c)
    #16 Window::_update_window_size() /home/rcorre/src/godot/godot/scene/main/window.cpp:883:22 (godot.linuxbsd.editor.x86_64.llvm.san+0x6a3bf9c)
    #17 Window::set_min_size(Vector2i const&) /home/rcorre/src/godot/godot/scene/main/window.cpp:391:2 (godot.linuxbsd.editor.x86_64.llvm.san+0x6a3cac4) (BuildId: fca740c9f8cae87822f94c6eab6045df1899fefb)
    #18 ConfirmationDialog::ConfirmationDialog() /home/rcorre/src/godot/godot/scene/gui/dialogs.cpp:447:2 (godot.linuxbsd.editor.x86_64.llvm.san+0x6bbcff1) (BuildId: fca740c9f8cae87822f94c6eab6045df1899fefb)
    #19 EditorFileDialog::EditorFileDialog() /home/rcorre/src/godot/godot/editor/editor_file_dialog.cpp:1704:19 (godot.linuxbsd.editor.x86_64.llvm.san+0x5263f09) (BuildId: fca740c9f8cae87822f94c6eab6045df1899fefb)
    #20 EditorAssetLibrary::EditorAssetLibrary(bool) /home/rcorre/src/godot/godot/editor/plugins/asset_library_editor_plugin.cpp:1622:15 (godot.linuxbsd.editor.x86_64.llvm.san+0x5e7a7b9) (BuildId: fca740c9f8cae87822f94c6eab6045df1899fefb)
    #21 ProjectManager::ProjectManager() /home/rcorre/src/godot/godot/editor/project_manager.cpp:2924:19 (godot.linuxbsd.editor.x86_64.llvm.san+0x58d8e94) (BuildId: fca740c9f8cae87822f94c6eab6045df1899fefb)
    #22 Main::start() /home/rcorre/src/godot/godot/main/main.cpp:3002:31 (godot.linuxbsd.editor.x86_64.llvm.san+0x2f2b926) (BuildId: fca740c9f8cae87822f94c6eab6045df1899fefb)
    #23 main /home/rcorre/src/godot/godot/platform/linuxbsd/godot_linuxbsd.cpp:71:6 (godot.linuxbsd.editor.x86_64.llvm.san+0x2e67e41) (BuildId: fca740c9f8cae87822f94c6eab6045df1899fefb)

  Mutex M1 previously acquired by the same thread here:
    #0 pthread_mutex_lock <null> (godot.linuxbsd.editor.x86_64.llvm.san+0x2e12851) (BuildId: fca740c9f8cae87822f94c6eab6045df1899fefb)
    #1 __gthread_mutex_lock(pthread_mutex_t*) /usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/12.2.1/../../../../include/c++/12.2.1/x86_64-pc-linux-gnu/bits/gthr-default.h:749:12 (godot.linuxbsd.editor.x86_64.llvm.san+0x45a97e7) (BuildId: fca740c9f8cae87822f94c6eab6045df1899fefb)
    #2 __gthread_recursive_mutex_lock(pthread_mutex_t*) /usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/12.2.1/../../../../include/c++/12.2.1/x86_64-pc-linux-gnu/bits/gthr-default.h:811:10 (godot.linuxbsd.editor.x86_64.llvm.san+0x45a97e7)
    #3 std::recursive_mutex::lock() /usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/12.2.1/../../../../include/c++/12.2.1/mutex:108:17 (godot.linuxbsd.editor.x86_64.llvm.san+0x45a97e7)
    #4 std::unique_lock<std::recursive_mutex>::lock() /usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/12.2.1/../../../../include/c++/12.2.1/bits/unique_lock.h:139:17 (godot.linuxbsd.editor.x86_64.llvm.san+0x45a97e7)
    #5 std::unique_lock<std::recursive_mutex>::unique_lock(std::recursive_mutex&) /usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/12.2.1/../../../../include/c++/12.2.1/bits/unique_lock.h:69:2 (godot.linuxbsd.editor.x86_64.llvm.san+0x45a97e7)
    #6 MutexLock<MutexImpl<std::recursive_mutex>>::MutexLock(MutexImpl<std::recursive_mutex> const&) /home/rcorre/src/godot/godot/./core/os/mutex.h:122:4 (godot.linuxbsd.editor.x86_64.llvm.san+0x45a97e7)
    #7 TextServerAdvanced::_shaped_text_substr(RID const&, long, long) const /home/rcorre/src/godot/godot/modules/text_server_adv/text_server_adv.cpp:4085:2 (godot.linuxbsd.editor.x86_64.llvm.san+0x45a97e7)
    #8 TextServerAdvanced::shaped_text_substr(RID const&, long, long) const /home/rcorre/src/godot/godot/modules/text_server_adv/text_server_adv.h:883:2 (godot.linuxbsd.editor.x86_64.llvm.san+0x45e12da) (BuildId: fca740c9f8cae87822f94c6eab6045df1899fefb)
    #9 Label::_shape() /home/rcorre/src/godot/godot/scene/gui/label.cpp:150:19 (godot.linuxbsd.editor.x86_64.llvm.san+0x6c8c905) (BuildId: fca740c9f8cae87822f94c6eab6045df1899fefb)
    #10 Label::get_minimum_size() const /home/rcorre/src/godot/godot/scene/gui/label.cpp:619:30 (godot.linuxbsd.editor.x86_64.llvm.san+0x6c9366b) (BuildId: fca740c9f8cae87822f94c6eab6045df1899fefb)
    #11 Control::_update_minimum_size_cache() /home/rcorre/src/godot/godot/scene/gui/control.cpp:1608:18 (godot.linuxbsd.editor.x86_64.llvm.san+0x6b69405) (BuildId: fca740c9f8cae87822f94c6eab6045df1899fefb)
    #12 Control::get_combined_minimum_size() const /home/rcorre/src/godot/godot/scene/gui/control.cpp:1627:32 (godot.linuxbsd.editor.x86_64.llvm.san+0x6b69405)
    #13 AcceptDialog::_get_contents_minimum_size() const /home/rcorre/src/godot/godot/scene/gui/dialogs.cpp:260:28 (godot.linuxbsd.editor.x86_64.llvm.san+0x6bb809a) (BuildId: fca740c9f8cae87822f94c6eab6045df1899fefb)
    #14 Window::get_contents_minimum_size() const /home/rcorre/src/godot/godot/scene/main/window.cpp:1566:9 (godot.linuxbsd.editor.x86_64.llvm.san+0x6a3bf9c) (BuildId: fca740c9f8cae87822f94c6eab6045df1899fefb)
    #15 Window::get_clamped_minimum_size() const /home/rcorre/src/godot/godot/scene/main/window.cpp:1574:22 (godot.linuxbsd.editor.x86_64.llvm.san+0x6a3bf9c)
    #16 Window::_update_window_size() /home/rcorre/src/godot/godot/scene/main/window.cpp:883:22 (godot.linuxbsd.editor.x86_64.llvm.san+0x6a3bf9c)
    #17 Window::set_min_size(Vector2i const&) /home/rcorre/src/godot/godot/scene/main/window.cpp:391:2 (godot.linuxbsd.editor.x86_64.llvm.san+0x6a3cac4) (BuildId: fca740c9f8cae87822f94c6eab6045df1899fefb)
    #18 ConfirmationDialog::ConfirmationDialog() /home/rcorre/src/godot/godot/scene/gui/dialogs.cpp:447:2 (godot.linuxbsd.editor.x86_64.llvm.san+0x6bbcff1) (BuildId: fca740c9f8cae87822f94c6eab6045df1899fefb)
    #19 EditorFileDialog::EditorFileDialog() /home/rcorre/src/godot/godot/editor/editor_file_dialog.cpp:1704:19 (godot.linuxbsd.editor.x86_64.llvm.san+0x5263f09) (BuildId: fca740c9f8cae87822f94c6eab6045df1899fefb)
    #20 EditorAssetLibrary::EditorAssetLibrary(bool) /home/rcorre/src/godot/godot/editor/plugins/asset_library_editor_plugin.cpp:1622:15 (godot.linuxbsd.editor.x86_64.llvm.san+0x5e7a7b9) (BuildId: fca740c9f8cae87822f94c6eab6045df1899fefb)
    #21 ProjectManager::ProjectManager() /home/rcorre/src/godot/godot/editor/project_manager.cpp:2924:19 (godot.linuxbsd.editor.x86_64.llvm.san+0x58d8e94) (BuildId: fca740c9f8cae87822f94c6eab6045df1899fefb)
    #22 Main::start() /home/rcorre/src/godot/godot/main/main.cpp:3002:31 (godot.linuxbsd.editor.x86_64.llvm.san+0x2f2b926) (BuildId: fca740c9f8cae87822f94c6eab6045df1899fefb)
    #23 main /home/rcorre/src/godot/godot/platform/linuxbsd/godot_linuxbsd.cpp:71:6 (godot.linuxbsd.editor.x86_64.llvm.san+0x2e67e41) (BuildId: fca740c9f8cae87822f94c6eab6045df1899fefb)

SUMMARY: ThreadSanitizer: lock-order-inversion (potential deadlock) (/home/rcorre/src/godot/godot/bin/godot.linuxbsd.editor.x86_64.llvm.san+0x2e12851) (BuildId: fca740c9f8cae87822f94c6eab6045df1899fefb) in pthread_mutex_lock
rcorre commented 1 year ago

The main pattern I'm seeing is in TextServerAdvanced.

  1. _free_rid takes the THREAD_SAFE_METHOD lock first, then locks FontAdvanced::mutex second
  2. Many functions lock FontAdvanced::mutex first, then call _shaped_text_shape which takes the THREAD_SAFE_METHOD lock second