Uploaded image for project: 'Qt'
  1. Qt
  2. QTBUG-39024

qfreelist_p.h usage in qmutex is racy

    XMLWordPrintable

Details

    • Bug
    • Resolution: Done
    • P3: Somewhat important
    • 5.3.1
    • 5.3.0 RC1
    • Core: Threads
    • None
    • 8636bade176d692672f191bbfb8ded8bbb6aa88c

    Description

      Running ./tst_qcoreapplication with clang's -fsanitize=thread gives this race:
      (when not using futexes)

      WARNING: ThreadSanitizer: data race
      Read of size 4 at 0x7d700001f078 by thread T2:
      #0 QFreeList<QMutexPrivate, (anonymous namespace)::FreeListConstants>::next() /s/qt/5/kdab/qt5-clang/build/qtbase/src/corelib/../../include/QtCore/5.4.0/QtCore/private/../../../../../../../qtbase/src/corelib/tools/qfreelist_p.h:257 (libQt5Core.so.5+0x0000000fece5)
      #1 QMutexPrivate::allocate() /d/qt/5/kdab/qt5-clang/qtbase/src/corelib/thread/qmutex.cpp:579 (libQt5Core.so.5+0x0000000fe284)
      #2 QBasicMutex::lockInternal(int) /d/qt/5/kdab/qt5-clang/qtbase/src/corelib/thread/qmutex.cpp:436 (libQt5Core.so.5+0x0000000fd8b9)
      #3 QBasicMutex::lockInternal() /d/qt/5/kdab/qt5-clang/qtbase/src/corelib/thread/qmutex.cpp:416 (libQt5Core.so.5+0x0000000fd745)
      #4 QMutex::lock() /d/qt/5/kdab/qt5-clang/qtbase/src/corelib/thread/qmutex.cpp:225 (libQt5Core.so.5+0x0000000fd5d8)
      #5 QCoreApplication::postEvent(QObject*, QEvent*, int) /d/qt/5/kdab/qt5-clang/qtbase/src/corelib/kernel/qcoreapplication.cpp:1297 (libQt5Core.so.5+0x0000007779fb)
      #6 queued_activate(QObject*, int, QObjectPrivate::Connection*, void**) /d/qt/5/kdab/qt5-clang/qtbase/src/corelib/kernel/qobject.cpp:3545 (libQt5Core.so.5+0x00000084a262)
      #7 QMetaObject::activate(QObject*, int, int, void**) /d/qt/5/kdab/qt5-clang/qtbase/src/corelib/kernel/qobject.cpp:3641 (libQt5Core.so.5+0x000000848301)
      #8 QMetaObject::activate(QObject*, QMetaObject const*, int, void**) /d/qt/5/kdab/qt5-clang/qtbase/src/corelib/kernel/qobject.cpp:3554 (libQt5Core.so.5+0x00000084792d)
      #9 DeliverInDefinedOrderThread::progress(int) /s/qt/5/kdab/qt5-clang/build/qtbase/tests/auto/corelib/kernel/qcoreapplication/.moc/tst_qcoreapplication.moc:259 (exe+0x000000052d4b)
      #10 DeliverInDefinedOrderThread::run() /d/qt/5/kdab/qt5-clang/qtbase/tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.cpp:365 (exe+0x000000059076)
      #11 QThreadPrivate::start(void*) /d/qt/5/kdab/qt5-clang/qtbase/src/corelib/thread/qthread_unix.cpp:345 (libQt5Core.so.5+0x0000001247c3)

      Previous write of size 4 at 0x7d700001f078 by main thread:
      #0 QFreeList<QMutexPrivate, (anonymous namespace)::FreeListConstants>::release(int) /s/qt/5/kdab/qt5-clang/build/qtbase/src/corelib/../../include/QtCore/5.4.0/QtCore/private/../../../../../../../qtbase/src/corelib/tools/qfreelist_p.h:276 (libQt5Core.so.5+0x0000000ff12c)
      #1 QMutexPrivate::release() /d/qt/5/kdab/qt5-clang/qtbase/src/corelib/thread/qmutex.cpp:596 (libQt5Core.so.5+0x0000000fefcf)
      #2 QMutexPrivate::deref() /d/qt/5/kdab/qt5-clang/qtbase/src/corelib/thread/qmutex_p.h:113 (libQt5Core.so.5+0x000000100819)
      #3 QBasicMutex::lockInternal(int) /d/qt/5/kdab/qt5-clang/qtbase/src/corelib/thread/qmutex.cpp:439 (libQt5Core.so.5+0x0000000fd92f)
      #4 QBasicMutex::lockInternal() /d/qt/5/kdab/qt5-clang/qtbase/src/corelib/thread/qmutex.cpp:416 (libQt5Core.so.5+0x0000000fd745)
      #5 QMutex::lock() /d/qt/5/kdab/qt5-clang/qtbase/src/corelib/thread/qmutex.cpp:225 (libQt5Core.so.5+0x0000000fd5d8)
      #6 QMutexLocker /s/qt/5/kdab/qt5-clang/build/qtbase/src/corelib/../../include/QtCore/../../../../qtbase/src/corelib/thread/qmutex.h:136 (libQt5Core.so.5+0x0000000b1db6)
      #7 QMutexLocker /s/qt/5/kdab/qt5-clang/build/qtbase/src/corelib/../../include/QtCore/../../../../qtbase/src/corelib/thread/qmutex.h:139 (libQt5Core.so.5+0x0000000a2e90)
      #8 QCoreApplicationPrivate::sendPostedEvents(QObject*, int, QThreadData*) /d/qt/5/kdab/qt5-clang/qtbase/src/corelib/kernel/qcoreapplication.cpp:1421 (libQt5Core.so.5+0x0000007785b5)
      #9 QCoreApplication::sendPostedEvents(QObject*, int) /d/qt/5/kdab/qt5-clang/qtbase/src/corelib/kernel/qcoreapplication.cpp:1402 (libQt5Core.so.5+0x0000007775f4)
      #10 postEventSourceDispatch(_GSource*, int (void*), void*) /d/qt/5/kdab/qt5-clang/qtbase/src/corelib/kernel/qeventdispatcher_glib.cpp:279 (libQt5Core.so.5+0x0000008ef9e8)
      #11 g_main_dispatch /usr/src/debug/glib-2.38.2/glib/gmain.c:3066 (libglib-2.0.so.0+0x00000004b315)
      #12 QEventLoop::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) /d/qt/5/kdab/qt5-clang/qtbase/src/corelib/kernel/qeventloop.cpp:136 (libQt5Core.so.5+0x00000076ca36)
      #13 QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) /d/qt/5/kdab/qt5-clang/qtbase/src/corelib/kernel/qeventloop.cpp:212 (libQt5Core.so.5+0x00000076cecd)
      #14 DeliverInDefinedOrderObject::event(QEvent*) /d/qt/5/kdab/qt5-clang/qtbase/tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.cpp:439 (exe+0x00000005925c)
      #15 QCoreApplicationPrivate::notify_helper(QObject*, QEvent*) /d/qt/5/kdab/qt5-clang/qtbase/src/corelib/kernel/qcoreapplication.cpp:1057 (libQt5Core.so.5+0x000000776582)
      #16 QCoreApplication::notify(QObject*, QEvent*) /d/qt/5/kdab/qt5-clang/qtbase/src/corelib/kernel/qcoreapplication.cpp:1002 (libQt5Core.so.5+0x0000007763cd)
      #17 QCoreApplication::notifyInternal(QObject*, QEvent*) /d/qt/5/kdab/qt5-clang/qtbase/src/corelib/kernel/qcoreapplication.cpp:940 (libQt5Core.so.5+0x00000077611e)
      #18 QCoreApplication::sendEvent(QObject*, QEvent*) /s/qt/5/kdab/qt5-clang/build/qtbase/src/corelib/../../include/QtCore/../../../../qtbase/src/corelib/kernel/qcoreapplication.h:237 (libQt5Core.so.5+0x0000007806fa)
      #19 QCoreApplicationPrivate::sendPostedEvents(QObject*, int, QThreadData*) /d/qt/5/kdab/qt5-clang/qtbase/src/corelib/kernel/qcoreapplication.cpp:1544 (libQt5Core.so.5+0x0000007791f7)
      #20 QCoreApplication::sendPostedEvents(QObject*, int) /d/qt/5/kdab/qt5-clang/qtbase/src/corelib/kernel/qcoreapplication.cpp:1402 (libQt5Core.so.5+0x0000007775f4)
      #21 postEventSourceDispatch(_GSource*, int (void*), void*) /d/qt/5/kdab/qt5-clang/qtbase/src/corelib/kernel/qeventdispatcher_glib.cpp:279 (libQt5Core.so.5+0x0000008ef9e8)
      #22 g_main_dispatch /usr/src/debug/glib-2.38.2/glib/gmain.c:3066 (libglib-2.0.so.0+0x00000004b315)
      #23 QEventLoop::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) /d/qt/5/kdab/qt5-clang/qtbase/src/corelib/kernel/qeventloop.cpp:136 (libQt5Core.so.5+0x00000076ca36)
      #24 QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) /d/qt/5/kdab/qt5-clang/qtbase/src/corelib/kernel/qeventloop.cpp:212 (libQt5Core.so.5+0x00000076cecd)
      #25 DeliverInDefinedOrderObject::event(QEvent*) /d/qt/5/kdab/qt5-clang/qtbase/tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.cpp:439 (exe+0x00000005925c)
      #26 QCoreApplicationPrivate::notify_helper(QObject*, QEvent*) /d/qt/5/kdab/qt5-clang/qtbase/src/corelib/kernel/qcoreapplication.cpp:1057 (libQt5Core.so.5+0x000000776582)
      #27 QCoreApplication::notify(QObject*, QEvent*) /d/qt/5/kdab/qt5-clang/qtbase/src/corelib/kernel/qcoreapplication.cpp:1002 (libQt5Core.so.5+0x0000007763cd)
      #28 QCoreApplication::notifyInternal(QObject*, QEvent*) /d/qt/5/kdab/qt5-clang/qtbase/src/corelib/kernel/qcoreapplication.cpp:940 (libQt5Core.so.5+0x00000077611e)
      #29 QCoreApplication::sendEvent(QObject*, QEvent*) /s/qt/5/kdab/qt5-clang/build/qtbase/src/corelib/../../include/QtCore/../../../../qtbase/src/corelib/kernel/qcoreapplication.h:237 (libQt5Core.so.5+0x0000007806fa)
      #30 QCoreApplicationPrivate::sendPostedEvents(QObject*, int, QThreadData*) /d/qt/5/kdab/qt5-clang/qtbase/src/corelib/kernel/qcoreapplication.cpp:1544 (libQt5Core.so.5+0x0000007791f7)
      #31 QCoreApplication::sendPostedEvents(QObject*, int) /d/qt/5/kdab/qt5-clang/qtbase/src/corelib/kernel/qcoreapplication.cpp:1402 (libQt5Core.so.5+0x0000007775f4)
      #32 postEventSourceDispatch(_GSource*, int (void*), void*) /d/qt/5/kdab/qt5-clang/qtbase/src/corelib/kernel/qeventdispatcher_glib.cpp:279 (libQt5Core.so.5+0x0000008ef9e8)
      #33 g_main_dispatch /usr/src/debug/glib-2.38.2/glib/gmain.c:3066 (libglib-2.0.so.0+0x00000004b315)
      #34 QEventLoop::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) /d/qt/5/kdab/qt5-clang/qtbase/src/corelib/kernel/qeventloop.cpp:136 (libQt5Core.so.5+0x00000076ca36)
      #35 QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) /d/qt/5/kdab/qt5-clang/qtbase/src/corelib/kernel/qeventloop.cpp:212 (libQt5Core.so.5+0x00000076cecd)
      #36 QCoreApplication::exec() /d/qt/5/kdab/qt5-clang/qtbase/src/corelib/kernel/qcoreapplication.cpp:1193 (libQt5Core.so.5+0x0000007772a7)
      #37 tst_QCoreApplication::deliverInDefinedOrder() /d/qt/5/kdab/qt5-clang/qtbase/tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.cpp:461 (exe+0x00000004f180)
      #38 tst_QCoreApplication::qt_static_metacall(QObject*, QMetaObject::Call, int, void**) /s/qt/5/kdab/qt5-clang/build/qtbase/tests/auto/corelib/kernel/qcoreapplication/.moc/moc_tst_qcoreapplication.cpp:126 (exe+0x00000005f411)
      #39 QMetaMethod::invoke(QObject*, Qt::ConnectionType, QGenericReturnArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument) const /d/qt/5/kdab/qt5-clang/qtbase/src/corelib/kernel/qmetaobject.cpp:2169 (libQt5Core.so.5+0x000000797476)
      #40 QMetaObject::invokeMethod(QObject*, char const*, Qt::ConnectionType, QGenericReturnArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument) /d/qt/5/kdab/qt5-clang/qtbase/src/corelib/kernel/qmetaobject.cpp:1463 (libQt5Core.so.5+0x000000796585)
      #41 QMetaObject::invokeMethod(QObject*, char const*, Qt::ConnectionType, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument) /s/qt/5/kdab/qt5-clang/build/qtbase/src/testlib/../../include/QtCore/../../../../qtbase/src/corelib/kernel/qobjectdefs.h:398 (libQt5Test.so.5+0x0000000271f5)
      #42 QTest::qInvokeTestMethodDataEntry(char*) /d/qt/5/kdab/qt5-clang/qtbase/src/testlib/qtestcase.cpp:1889 (libQt5Test.so.5+0x000000018969)
      #43 QTest::qInvokeTestMethod(char const*, char const*) /d/qt/5/kdab/qt5-clang/qtbase/src/testlib/qtestcase.cpp:2015 (libQt5Test.so.5+0x000000017f32)
      #44 QTest::qInvokeTestMethods(QObject*) /d/qt/5/kdab/qt5-clang/qtbase/src/testlib/qtestcase.cpp:2242 (libQt5Test.so.5+0x000000012d6f)
      #45 QTest::qExec(QObject*, int, char**) /d/qt/5/kdab/qt5-clang/qtbase/src/testlib/qtestcase.cpp:2475 (libQt5Test.so.5+0x0000000122dd)
      #46 main /d/qt/5/kdab/qt5-clang/qtbase/tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.cpp:803 (exe+0x000000052183)

      next() calls
      newid = v[at].next | (id & ~ConstantsType::IndexMask);

      and released() calls
      v[at].next = x & ConstantsType::IndexMask;

      which is indeed a race.
      I suppose next should be changed from an int to an atomic int?

      Attachments

        No reviews matched the request. Check your Options in the drop-down menu of this sections header.

        Activity

          People

            dfaure_kdab David Faure
            dfaure David Faure (Private)
            Votes:
            0 Vote for this issue
            Watchers:
            4 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved:

              Gerrit Reviews

                There are no open Gerrit changes