Qt 6.4 built with TSAN - but how to add my own Glib build?
-
so im now able to build a Qt 6.4 with TSAN using these steps
mkdir qt6_dev cd qt6_dev git clone git://code.qt.io/qt/qt5.git qt6 cd qt6 git checkout v6.4.0 perl init-repository mkdir qt6-build cd qt6-build ../qt6/qtbase/configure -developer-build -debug -opensource -nomake examples -nomake tests -sanitize thread cmake --build . --parallel 2
but the problem is that i also need (according to some Qt devs) Glib (from the Gtk projects) with TSAN build
TSAN needs (other then ASAN) some 3rd-parties also build with TSANanyone around who build his own Glib from source under Ubuntu 22.04 with some tips how to build with TSAN?
im currently doing with
git clone https://gitlab.gnome.org/GNOME/glib.git git checkout 2.72.1 mkdir glib-build cd glib-build meson setup ../glib -Dbuildtype=debug -Db_sanitize=thread meson compile
builds
but i have no idea if that is correct for Qt or best practise and i don't know how to tell Qt 6.4 cmake to use this version
trying with
export LD_LIBRARY_PATH=/home/linux/dev/3rdparty-linux-gcc/qt6_dev/glib-build/glib:$LD_LIBRARY_PATH ../qt6/qtbase/configure -developer-build -debug -opensource -nomake examples -nomake tests -sanitize thread
didn't worked - Qt still grabs my systems glib
-- Found GLIB2: /usr/lib/x86_64-linux-gnu/libglib-2.0.so
-
solution was these steps
mkdir ~/qt6_dev
1. build Glib with --prefix
cd ~/qt6_dev
git clone https://gitlab.gnome.org/GNOME/glib.git
cd glib
git checkout 2.72.1
cd ..
mkdir glib-build
cd glib-build
meson setup ../glib -Dbuildtype=debug -Db_sanitize=thread --prefix ~/qt6_dev/glib-install
meson compile
meson install2. build Qt with PKG_CONFIG_PATH set
cd ~/qt6_dev
git clone git://code.qt.io/qt/qt5.git qt6
cd qt6
git checkout v6.4.0
perl init-repository
cd ..
mkdir qt6-build
cd qt6-build
PKG_CONFIG_PATH=~/qt6_dev/glib-install/lib/x86_64-linux-gnu/pkgconfig
../qt6/qtbase/configure -debug -opensource -nomake examples -nomake tests -sanitize thread -prefix ~/qt6_dev/qt6-install
cmake --build . --parallel 2
cmake --install . -
i've got everything (i need) built with TSAN
mkdir ~/qt6_dev
- build Glib with TSAN
cd ~/qt6_dev git clone https://gitlab.gnome.org/GNOME/glib.git cd glib git checkout 2.72.1 cd .. mkdir glib-build cd glib-build meson setup ../glib -Dbuildtype=debug -Db_sanitize=thread --prefix ~/qt6_dev/glib-install meson compile meson install
- build DBus with TSAN (and TSAN-Glib)
git clone https://github.com/freedesktop/dbus.git cd dbus git checkout dbus-1.12.20 cd .. mkdir dbus-build cd dbus-build PKG_CONFIG_PATH=~/qt6_dev/glib-install/lib/x86_64-linux-gnu/pkgconfig cmake ../dbus/cmake -DCMAKE_INSTALL_PREFIX=~/qt6_dev/dbus-install -DCMAKE_CXX_FLAGS="-g -fno-omit-frame-pointer -fsanitize=thread" -DCMAKE_C_FLAGS="-g -fno-omit-frame-pointer -fsanitize=thread" -DCMAKE_EXE_LINKER_FLAGS="-fno-omit-frame-pointer -fsanitize=thread" -DCMAKE_MODULE_LINKER_FLAGS="-fno-omit-frame-pointer -fsanitize=thread" cmake --build . --parallel 6 cmake --install .
- build Qt 6.4(with patch: https://codereview.qt-project.org/c/qt/qtbase/+/442720) with TSAN
cd ~/qt6_dev git clone git://code.qt.io/qt/qt5.git qt6 cd qt6 perl init-repository git checkout v6.4.0 cd .. mkdir qt6-build cd qt6-build PKG_CONFIG_PATH=~/qt6_dev/glib-install/lib/x86_64-linux-gnu/pkgconfig ../qt6/qtbase/configure -debug -opensource -nomake examples -nomake tests -sanitize thread DBus1_ROOT=~/qt6_dev/dbus-install -prefix ~/qt6_dev/qt6-install cmake --build . --parallel 6 cmake --install .
- build simple example qt_tsan_tests with TSAN
int main( int argc, char* argv[] ) { QApplication app( argc, argv ); QWidget window; window.resize( 320, 240 ); window.show(); return app.exec(); }
- start example with
./qt_tsan_tests
TSAN Output: https://pastebin.com/FHjrcQLS
-
Hi,
is it expected that such a minimal Qt application fails with TSAN enabled (referring to your example)? I've followed your instructions and my application fails on startup in QThread coding, for example:
WARNING: ThreadSanitizer: data race (pid=248678) Atomic read of size 8 at 0x7b0c0000a0b8 by thread T4: #0 __tsan_atomic64_load ../../../../src/libsanitizer/tsan/tsan_interface_atomic.cpp:539 (libtsan.so.0+0x801ee) #1 std::__atomic_base<QObjectPrivate::SignalVector*>::load(std::memory_order) const /usr/include/c++/11/bits/atomic_base.h:838 (libQt6Core.so.6+0x23d94f) #2 std::atomic<QObjectPrivate::SignalVector*>::load(std::memory_order) const /usr/include/c++/11/atomic:570 (libQt6Core.so.6+0x23d94f) #3 QObjectPrivate::SignalVector* QAtomicOps<QObjectPrivate::SignalVector*>::loadRelaxed<QObjectPrivate::SignalVector*>(std::atomic<QObjectPrivate::SignalVector*> const&) /home/andre/Projects/GitHub/qt6_dev/qt6/qtbase/src/corelib/thread/qatomic_cxx11.h:201 (libQt6Core.so.6+0x23d94f) #4 QBasicAtomicPointer<QObjectPrivate::SignalVector>::loadRelaxed() const /home/andre/Projects/GitHub/qt6_dev/qt6/qtbase/src/corelib/thread/qbasicatomic.h:190 (libQt6Core.so.6+0x23d94f) #5 QObjectPrivate::maybeSignalConnected(unsigned int) const /home/andre/Projects/GitHub/qt6_dev/qt6/qtbase/src/corelib/kernel/qobject.cpp:468 (libQt6Core.so.6+0x23d94f) #6 void doActivate<false>(QObject*, int, void**) <null> (libQt6Core.so.6+0x258272) #7 QMetaObject::activate(QObject*, QMetaObject const*, int, void**) /home/andre/Projects/GitHub/qt6_dev/qt6/qtbase/src/corelib/kernel/qobject.cpp:4032 (libQt6Core.so.6+0x248f48) #8 QThread::started(QThread::QPrivateSignal) /home/andre/Projects/GitHub/qt6_dev/qt6-build/qtbase/src/corelib/Core_autogen/include/moc_qthread.cpp:211 (libQt6Core.so.6+0x3b795e) #9 operator() /home/andre/Projects/GitHub/qt6_dev/qt6/qtbase/src/corelib/thread/qthread_unix.cpp:316 (libQt6Core.so.6+0x48ebf7) #10 terminate_on_exception<QThreadPrivate::start(void*)::<lambda()> > /home/andre/Projects/GitHub/qt6_dev/qt6/qtbase/src/corelib/thread/qthread_unix.cpp:257 (libQt6Core.so.6+0x48f02c) #11 QThreadPrivate::start(void*) /home/andre/Projects/GitHub/qt6_dev/qt6/qtbase/src/corelib/thread/qthread_unix.cpp:280 (libQt6Core.so.6+0x48f892)
Anything you've done to avoid that? Or are those actual data races in Qt's QThread library? (I doubt that and think it's missing TSAN instructions or similar).
I've written about how I build Qt6 here: https://github.com/Komet/MediaElch/blob/master/docs/contributing/guides/build-qt6-with-tsan.md
Kind regards,
Andre -
sorry for the late reply
i only checked the very simple Qt Application - just open a window+return
Qt is not tested per default with TSAN so i think there are many small problems lurking around
im creating issues for every finding on https://bugreports.qt.io/
-
@LowLevelM Thank you very much! I also noticed that I can't test my Qt application with memory sanitizer either. I think I'll have to start with small parts of my app + Qt with ASAN enabled. Step by step. Thank you for your guide! :)