Data races detected while deleting QThreads

79 views Asked by At

I am working on a multithread project and I am trying to detect thread inconsistency using helgrind (valgrind tool).

After closing the app I get multiples reports like this:

==50932== Possible data race during read of size 8 at 0x3413C718 by thread #26
==50932== Locks held: none
==50932==    at 0xB91ED11: QObjectPrivate::ConnectionData::removeConnection(QObjectPrivate::Connection*) (in /usr/local/qt5/lib/libQt5Core.so.5.15.10)
==50932==    by 0xB92A4E2: QObject::~QObject() (in /usr/local/qt5/lib/libQt5Core.so.5.15.10)\
==50932==    by 0x525E9F: classA::~classA() (classA.cpp:52)
==50932==    by 0x525EC3: classA::~classA() (classA.cpp:52)
==50932==    by 0xB922012: QObject::event(QEvent*) (in /usr/local/qt5/lib/libQt5Core.so.5.15.10)
==50932==    by 0x9CC66D2: QApplicationPrivate::notify_helper(QObject*, QEvent*) (in /usr/local/qt5/lib/libQt5Widgets.so.5.15.10)
==50932==    by 0xB8F4E19: QCoreApplication::notifyInternal2(QObject*, QEvent*) (in /usr/local/qt5/lib/libQt5Core.so.5.15.10)
==50932==    by 0xB8F7F06: QCoreApplicationPrivate::sendPostedEvents(QObject*, int, QThreadData*) (in /usr/local/qt5/lib/libQt5Core.so.5.15.10)
==50932==    by 0xB94EA36: ??? (in /usr/local/qt5/lib/libQt5Core.so.5.15.10)
==50932==    by 0xCCA8D3A: g_main_context_dispatch (in /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.7200.4)
==50932==    by 0xCCFE257: ??? (in /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.7200.4)
==50932==    by 0xCCA63E2: g_main_context_iteration (in /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.7200.4)
==50932==
==50932== This conflicts with a previous write of size 8 by thread #25
==50932== Locks held: none
==50932==    at 0xB91ED20: QObjectPrivate::ConnectionData::removeConnection(QObjectPrivate::Connection*) (in /usr/local/qt5/lib/libQt5Core.so.5.15.10)
==50932==    by 0xB92A4E2: QObject::~QObject() (in /usr/local/qt5/lib/libQt5Core.so.5.15.10)
==50932==    by 0x468CA9: IclassB::~IclassB() (IclassB.h:43)
==50932==    by 0x4646ED: classB::~classB() (classB.cpp:75)
==50932==    by 0x464711: classB::~classB() (classB.cpp:75)
==50932==    by 0xB922012: QObject::event(QEvent*) (in /usr/local/qt5/lib/libQt5Core.so.5.15.10)
==50932==    by 0x9CC66D2: QApplicationPrivate::notify_helper(QObject*, QEvent*) (in /usr/local/qt5/lib/libQt5Widgets.so.5.15.10)
==50932==    by 0xB8F4E19: QCoreApplication::notifyInternal2(QObject*, QEvent*) (in /usr/local/qt5/lib/libQt5Core.so.5.15.10)
==50932==  Address 0x3413c718 is 8 bytes inside a block of size 88 alloc'd
==50932==    at 0x484AFF5: operator new(unsigned long) (vg_replace_malloc.c:483)
==50932==    by 0xB9233E4: QObjectPrivate::connectImpl(QObject const*, int, QObject const*, void**, QtPrivate::QSlotObjectBase*, Qt::ConnectionType, int const*, QMetaObject const*) (in /usr/local/qt5/lib/libQt5Core.so.5.15.10)
==50932==    by 0xB923964: QObject::connectImpl(QObject const*, void**, QObject const*, void**, QtPrivate::QSlotObjectBase*, Qt::ConnectionType, int const*, QMetaObject const*) (in /usr/local/qt5/lib/libQt5Core.so.5.15.10)
==50932==    by 0x3E52AF: std::enable_if<QtPrivate::FunctionPointer<MainWindow::MainWindow(QWidget*)::{lambda()#31}>::ArgumentCount==(-1), QMetaObject::Connection>::type QObject::connect<void> (QObject::*)(QObject*), MainWindow::MainWindow(QWidget*)::{lambda()#31}>(QtPrivate::FunctionPointer<void> (QObject::*)(QObject*)>::Object const*, void (QObject::*)(QObject*), > QObject const*, MainWindow::MainWindow(QWidget*)::{lambda()#31}, > Qt::ConnectionType) (qobject.h:347)
==50932==    by 0x3D2149: MainWindow::MainWindow(QWidget*) (mainwindow.cpp:633)
==50932==    by 0x374017: main (main.cpp:199)
==50932==  Block was alloc'd by thread #1
==50932==

So I have 2 classes running in different threads and when I close the app it seems like they both access to QObjectPrivate::ConnectionData::removeConnection() and since this method is from the Qt framework itself it seems that the data races cannot be tackled.

IclassB Is the interface for classB so it has nothing implemented.

Both threads A and B access to their destructor which are:

classB::~classB()
{
    if (d != nullptr)
    {
        delete d->member;
        delete d;
    }
}

and

classA::~classA()
{
    if (d != nullptr)
    {
        if (d->mm->isActive())
            d->mm->stop();
        delete d;
    }

}

I cannot see anything weird with the destructors. I just wanna make sure that this dataraces is a false positive because I have a lot of this type.

0

There are 0 answers