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

Deadlock in QQuickFontLoader

    XMLWordPrintable

    Details

    • Type: Bug
    • Status: Closed
    • Priority: P0: Blocker
    • Resolution: Done
    • Affects Version/s: 5.10
    • Fix Version/s: 5.10.0 Alpha
    • Component/s: Core: Object Model
    • Labels:
      None
    • Environment:
      qtbase ca92ee2518fdbd77fcbe3f8ef4f412aa5950b1b9 or later
    • Commits:
      942922652481347659a0dae78758c334778a58d2

      Description

      qAddPostRoutine() & friends have been made thread-safe in Qt 5.10 (https://codereview.qt-project.org/#/c/204229/). QQuickFontLoader has a pre-routine that adds a post-routine (added in https://codereview.qt-project.org/#/c/126501/), which leads to a deadlock.

      Minimal test case:

      import QtQuick 2.7
      import QtQuick.Window 2.2
      
      Window {
          id: window
          width: 360
          height: 360
          visible: true
      
          FontLoader {
              source: "http://www.mysite.com/myfont.ttf"
          }
      }
      

      Running tst_dialogs from qtquickcontrols (1) repo is also a reliable way to reproduce the deadlock: http://10.212.3.36:8080/coin/api/results/qt/qtquickcontrols/0a343f27df7c35d5b7bb01586473278a42737351/LinuxRHEL_7_2x86_64LinuxRHEL_7_2x86_64GCCqtci-linux-RHEL-7.2-x86_64-7ec3acRelease_NoUseGoldLinker/e372f4ccb856a79fe317147b3c4e8046da840fbd/test_1504602526/testlog.txt.gz (https://codereview.qt-project.org/#/c/204362/).

      Stacktrace:

      #0  0x00007f24920f8559 in syscall () at /lib64/libc.so.6
      #1  0x00007f24931f1e1a in _q_futex (timeout=0x0, val=3, op=0, addr=<optimized out>) at thread/qmutex_linux.cpp:121
      #2  0x00007f24931f1e1a in lockInternal_helper<false> (elapsedTimer=<optimized out>, timeout=<optimized out>, d_ptr=...) at thread/qmutex_linux.cpp:162
      #3  0x00007f24931f1e1a in QBasicMutex::lockInternal() (this=0x7f24936ab280 <globalRoutinesMutex>) at thread/qmutex_linux.cpp:178
      #4  0x00007f24931f2064 in QMutex::lock() (this=this@entry=0x7f24936ab280 <globalRoutinesMutex>) at thread/qmutex.cpp:229
      #5  0x00007f24933c681c in QMutexLocker::QMutexLocker(QBasicMutex*) (m=0x7f24936ab280 <globalRoutinesMutex>, this=0x7fffffffaff8) at ../../include/QtCore/../../src/corelib/thread/qmutex.h:200
      #6  0x00007f24933c681c in qAddPostRoutine(void (*)()) (p=p@entry=0x7f2494262665 <q_QFontLoaderFontsStaticReset()>) at kernel/qcoreapplication.cpp:296
      #7  0x00007f2494260f14 in q_QFontLoaderFontsAddReset() () at util/qquickfontloader.cpp:161
      #8  0x00007f24933c66f9 in qAddPreRoutine(void (*)()) (p=p@entry=0x7f2494260f04 <q_QFontLoaderFontsAddReset()>) at kernel/qcoreapplication.cpp:286
      #9  0x00007f2494261d25 in QFontLoaderFonts::QFontLoaderFonts() (this=0x7f24945ed9d8 <(anonymous namespace)::Q_QGS_fontLoaderFonts::innerFunction()::holder>) at util/qquickfontloader.cpp:169
      #10 0x00007f2494261d25 in (anonymous namespace)::Q_QGS_fontLoaderFonts::Holder::Holder (this=0x7f24945ed9d8 <(anonymous namespace)::Q_QGS_fontLoaderFonts::innerFunction()::holder>)
          at util/qquickfontloader.cpp:194
      #11 0x00007f2494261d25 in (anonymous namespace)::Q_QGS_fontLoaderFonts::innerFunction () at util/qquickfontloader.cpp:194
      #12 0x00007f2494261d25 in QGlobalStatic<QFontLoaderFonts, (anonymous namespace)::Q_QGS_fontLoaderFonts::innerFunction, (anonymous namespace)::Q_QGS_fontLoaderFonts::guard>::operator() (this=<optimized out>)
          at /home/jpnurmi/Projects/qt-510/qtbase/include/QtCore/../../src/corelib/global/qglobalstatic.h:135
      #13 0x00007f2494261d25 in QQuickFontLoader::setSource(QUrl const&) (this=0xb56440, url=...) at util/qquickfontloader.cpp:257
      #14 0x00007f2494262660 in QQuickFontLoader::qt_static_metacall(QObject*, QMetaObject::Call, int, void**) (_o=<optimized out>, _c=<optimized out>, _id=<optimized out>, _a=<optimized out>)
          at .moc/moc_qquickfontloader_p.cpp:162
      #15 0x00007f24939b358c in QQmlPropertyData::writeProperty(QObject*, void*, QFlags<QQmlPropertyData::WriteFlag>) const (this=this@entry=0x7f246032f5d8, target=<optimized out>, value=value@entry=0x7fffffffb1a0, flags=...) at /home/jpnurmi/Projects/qt-510/qtbase/include/QtQml/5.10.0/QtQml/private/../../../../../../qtdeclarative/src/qml/qml/qqmlpropertycache_p.h:320
      #16 0x00007f2493a4a750 in QQmlObjectCreator::setPropertyValue(QQmlPropertyData const*, QV4::CompiledData::Binding const*) (this=this@entry=0x7fffffffc0f0, property=property@entry=0x7f246032f5d8, binding=binding@entry=0x7f24603564f4) at qml/qqmlobjectcreator.cpp:377
      #17 0x00007f2493a4e5b4 in QQmlObjectCreator::setPropertyBinding(QQmlPropertyData const*, QV4::CompiledData::Binding const*) (this=this@entry=0x7fffffffc0f0, property=property@entry=0x7f246032f5d8, binding=binding@entry=0x7f24603564f4) at qml/qqmlobjectcreator.cpp:991
      #18 0x00007f2493a4fdbd in QQmlObjectCreator::setupBindings(bool) (this=this@entry=0x7fffffffc0f0, applyDeferredBindings=applyDeferredBindings@entry=false) at qml/qqmlobjectcreator.cpp:703
      #19 0x00007f2493a4ce7b in QQmlObjectCreator::populateInstance(int, QObject*, QObject*, QQmlPropertyData const*) (this=this@entry=0x7fffffffc0f0, index=0, 
          index@entry=1, instance=0xb47040, bindingTarget=0xb47040, valueTypeProperty=valueTypeProperty@entry=0x0) at qml/qqmlobjectcreator.cpp:1356
      #20 0x00007f2493a4dd95 in QQmlObjectCreator::createInstance(int, QObject*, bool) (this=this@entry=0x7fffffffc0f0, index=1, parent=<optimized out>, isContextObject=isContextObject@entry=false)
          at qml/qqmlobjectcreator.cpp:1199
      #21 0x00007f2493a4e29c in QQmlObjectCreator::setPropertyBinding(QQmlPropertyData const*, QV4::CompiledData::Binding const*) (this=this@entry=0x7fffffffc0f0, property=property@entry=0x7f24600a9978, binding=binding@entry=0x7f2460356480) at qml/qqmlobjectcreator.cpp:751
      #22 0x00007f2493a4fdbd in QQmlObjectCreator::setupBindings(bool) (this=this@entry=0x7fffffffc0f0, applyDeferredBindings=applyDeferredBindings@entry=false) at qml/qqmlobjectcreator.cpp:703
      #23 0x00007f2493a4ce7b in QQmlObjectCreator::populateInstance(int, QObject*, QObject*, QQmlPropertyData const*) (this=this@entry=0x7fffffffc0f0, index=-1, 
          index@entry=0, instance=0x0, bindingTarget=0x0, valueTypeProperty=valueTypeProperty@entry=0x0) at qml/qqmlobjectcreator.cpp:1356
      #24 0x00007f2493a4dd95 in QQmlObjectCreator::createInstance(int, QObject*, bool) (this=this@entry=0x7fffffffc0f0, index=index@entry=0, parent=parent@entry=0x0, isContextObject=isContextObject@entry=true)
          at qml/qqmlobjectcreator.cpp:1199
      #25 0x00007f2493a50512 in QQmlObjectCreator::create(int, QObject*, QQmlInstantiationInterrupt*) (this=this@entry=0x7fffffffc0f0, subComponentIndex=subComponentIndex@entry=-1, parent=parent@entry=0x0, interrupt=interrupt@entry=0x0) at qml/qqmlobjectcreator.cpp:202
      #26 0x00007f2493a4d7d1 in QQmlObjectCreator::createInstance(int, QObject*, bool) (this=this@entry=0xb42620, index=index@entry=69, parent=parent@entry=0x0, isContextObject=isContextObject@entry=true)
          at qml/qqmlobjectcreator.cpp:1110
      #27 0x00007f2493a50512 in QQmlObjectCreator::create(int, QObject*, QQmlInstantiationInterrupt*) (this=0xb42620, subComponentIndex=<optimized out>, parent=parent@entry=0x0, interrupt=interrupt@entry=0x7fffffffc4d0) at qml/qqmlobjectcreator.cpp:202
      #28 0x00007f24939bb678 in QQmlIncubatorPrivate::incubate(QQmlInstantiationInterrupt&) (this=this@entry=0xb42540, i=...) at qml/qqmlincubator.cpp:298
      #29 0x00007f24939bc0b9 in QQmlEnginePrivate::incubate(QQmlIncubator&, QQmlContextData*) (this=this@entry=0x567000, i=..., forContext=forContext@entry=0xb42460) at qml/qqmlincubator.cpp:89
      #30 0x00007f24939b57a4 in QQmlComponent::create(QQmlIncubator&, QQmlContext*, QQmlContext*) (this=<optimized out>, incubator=..., context=<optimized out>, forContext=forContext@entry=0x0)
          at qml/qqmlcomponent.cpp:1040
      #31 0x00007f24943e7027 in QQuickLoaderPrivate::_q_sourceLoaded() (this=this@entry=0xa3ae30) at items/qquickloader.cpp:723
      #32 0x00007f24943e716e in QQuickLoaderPrivate::load() (this=this@entry=0xa3ae30) at items/qquickloader.cpp:605
      #33 0x00007f24943e7825 in QQuickLoader::componentComplete() (this=0xa3ad80) at items/qquickloader.cpp:815
      #34 0x00007f2493a4be9e in QQmlObjectCreator::finalize(QQmlInstantiationInterrupt&) (this=0x6442c0, interrupt=...) at qml/qqmlobjectcreator.cpp:1238
      #35 0x00007f24939b4eeb in QQmlComponentPrivate::complete(QQmlEnginePrivate*, QQmlComponentPrivate::ConstructionState*) (enginePriv=0x567000, state=state@entry=0x58df80) at qml/qqmlcomponent.cpp:900
      #36 0x00007f24939b4f81 in QQmlComponentPrivate::completeCreate() (this=0x58dee0) at qml/qqmlcomponent.cpp:936
      #37 0x00007f24939b5049 in QQmlComponent::completeCreate() (this=<optimized out>) at qml/qqmlcomponent.cpp:929
      #38 0x00007f24939b4d37 in QQmlComponent::create(QQmlContext*) (this=0x9cbd90, context=<optimized out>) at qml/qqmlcomponent.cpp:769
      #39 0x00007f24943eba47 in QQuickView::continueExecute() (this=this@entry=0x5fe290) at items/qquickview.cpp:471
      #40 0x00007f24943ec331 in QQuickViewPrivate::execute() (this=this@entry=0x9c8800) at items/qquickview.cpp:107
      #41 0x00007f24943ec3b1 in QQuickView::setSource(QUrl const&) (this=this@entry=0x5fe290, url=...) at items/qquickview.cpp:236
      #42 0x000000000040569c in tst_dialogs::fileDialogDefaultModality() (this=0x7fffffffd390) at tst_dialogs.cpp:120
      #43 0x000000000040c2de in tst_dialogs::qt_static_metacall(QObject*, QMetaObject::Call, int, void**) (_o=_o@entry=0x7fffffffd390, _c=_c@entry=QMetaObject::InvokeMetaMethod, _id=_id@entry=4, _a=_a@entry=0x7fffffffcc10) at .moc/tst_dialogs.moc:95
      #44 0x00007f24933d2261 in QMetaMethod::invoke(QObject*, Qt::ConnectionType, QGenericReturnArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument) const (this=0x559a20, object=0x7fffffffd390, connectionType=connectionType@entry=Qt::DirectConnection, returnValue=..., val0=..., val1=..., val2=..., val3=..., val4=..., val5=..., val6=..., val7=..., val8=..., val9=...) at kernel/qmetaobject.cpp:2305
      #45 0x00007f24936c1d36 in QMetaMethod::invoke(QObject*, Qt::ConnectionType, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument) const (val9=..., val8=..., val7=..., val6=..., val5=..., val4=..., val3=..., val2=..., val1=..., val0=..., connectionType=Qt::DirectConnection, object=<optimized out>, this=<optimized out>) at ../../include/QtCore/../../src/corelib/kernel/qmetaobject.h:123
      #46 0x00007f24936c1d36 in QTest::TestMethods::invokeTestOnData(int) const (this=this@entry=0x7fffffffd2c0, index=index@entry=2) at qtestcase.cpp:895
      #47 0x00007f24936c2ad4 in QTest::TestMethods::invokeTest(int, char const*, QTest::WatchDog*) const (this=this@entry=0x7fffffffd2c0, index=index@entry=2, data=data@entry=0x0, watchDog=watchDog@entry=0x0)
          at qtestcase.cpp:1076
      #48 0x00007f24936c31fd in QTest::TestMethods::invokeTests(QObject*) const (this=this@entry=0x7fffffffd2c0, testObject=0x7fffffffd390) at qtestcase.cpp:1393
      #49 0x00007f24936c3861 in QTest::qRun() () at qtestcase.cpp:1833
      #50 0x00007f24936c39b6 in QTest::qExec(QObject*, int, char**) (testObject=testObject@entry=0x7fffffffd390, argc=<optimized out>, argv=argv@entry=0x7fffffffd4b8) at qtestcase.cpp:1720
      #51 0x000000000040c371 in main(int, char**) (argc=<optimized out>, argv=0x7fffffffd4b8) at tst_dialogs.cpp:210
      

        Attachments

          Issue Links

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

            Activity

              People

              Assignee:
              thiago Thiago Macieira
              Reporter:
              jpnurmi J-P Nurmi
              Votes:
              0 Vote for this issue
              Watchers:
              3 Start watching this issue

                Dates

                Created:
                Updated:
                Resolved:

                  Gerrit Reviews

                  There are no open Gerrit changes