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

local static variables in other threads might block while constructor for Q_GLOBAL_STATIC object is running

    XMLWordPrintable

    Details

    • Type: Bug
    • Status: Closed
    • Priority: P1: Critical
    • Resolution: Done
    • Affects Version/s: 5.2.0 Alpha
    • Fix Version/s: 5.2.0 Beta1
    • Component/s: Core: Other
    • Labels:
      None
    • Commits:
      816e7f11f192b199e62c7128efedbc63c05ffd79

      Description

      clang on the mac inserts cxa_guards around local static variables, which however are global. Q_GLOBAL_STATIC also uses a local static variable, which might result in other threads to lock on construction of (unrelated) static variables while the Q_GLOBAL_STATIC constructor is running.

      This was the source of a lot of instability e.g. in the qml debugger infrastructure:

      http://pastebin.com/hWgqgVfP

      Also this has been the source of bugs before:

      https://bugreports.qt-project.org/browse/QTBUG-24554

      Attached is a pretty minimal test case demonstrating the issue.

      What I'd expect is that, even though thread 1 is blocked, the WorkerThread should print continuously to the console.

      What happens is that the WorkerThread is blocked while trying to create a local static variable:

      * thread #1: tid = 0x1803, 0x0000000100003e78 locktest`GlobalStatic::GlobalStatic(this=0x00000001000053e9) + 8 at main.cpp:10, stop reason = signal SIGSTOP
          frame #0: 0x0000000100003e78 locktest`GlobalStatic::GlobalStatic(this=0x00000001000053e9) + 8 at main.cpp:10
          frame #1: 0x0000000100003e65 locktest`GlobalStatic::GlobalStatic(this=0x00000001000053e9) + 21 at main.cpp:11
          frame #2: 0x00000001000035e8 locktest`(this=0x00000001000053e9)::Q_QGS_globalStatic::innerFunction()::Holder::Holder() + 24 at main.cpp:14
          frame #3: 0x0000000100003545 locktest`(this=0x00000001000053e9)::Q_QGS_globalStatic::innerFunction()::Holder::Holder() + 21 at main.cpp:14
          frame #4: 0x00000001000034c8 locktest`(anonymous namespace)::Q_QGS_globalStatic::innerFunction() + 56 at main.cpp:14
          frame #5: 0x0000000100003444 locktest`QGlobalStatic<GlobalStatic, (this=0x00000001000053e8)::Q_QGS_globalStatic::innerFunction(), (anonymous namespace)::Q_QGS_globalStatic::guard>::operator()() + 52 at qglobalstatic.h:123
          frame #6: 0x000000010000372b locktest`MainApp::lockStatic(this=0x00007fff5fbffd50) + 27 at main.cpp:33
          frame #7: 0x0000000100003214 locktest`MainApp::qt_static_metacall(_o=0x00007fff5fbffd50, _c=InvokeMetaMethod, _id=0, _a=0x0000000100e004e0) + 68 at main.moc:133
          frame #8: 0x00000001006d9f10 QtCore`QObject::event(QEvent*) + 752
          frame #9: 0x00000001006af9e9 QtCore`QCoreApplication::notify(QObject*, QEvent*) + 185
          frame #10: 0x00000001006b04fa QtCore`QCoreApplicationPrivate::sendPostedEvents(QObject*, int, QThreadData*) + 778
          frame #11: 0x00000001006fe3ca QtCore`QEventDispatcherUNIX::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) + 58
          frame #12: 0x00000001006ace1d QtCore`QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) + 397
          frame #13: 0x00000001006afe9d QtCore`QCoreApplication::exec() + 349
          frame #14: 0x0000000100002f94 locktest`main(argc=1, argv=0x00007fff5fbffdc0) + 148 at main.cpp:47
          frame #15: 0x0000000100002ef4 locktest`start + 52
      
        thread #2: tid = 0x1d03, 0x00007fff8ac66d16 libsystem_kernel.dylib`kevent + 10
          frame #0: 0x00007fff8ac66d16 libsystem_kernel.dylib`kevent + 10
          frame #1: 0x00007fff84ef2dea libdispatch.dylib`_dispatch_mgr_invoke + 883
          frame #2: 0x00007fff84ef29ee libdispatch.dylib`_dispatch_mgr_thread + 54
      
        thread #3: tid = 0x1e03, 0x00007fff8ac66122 libsystem_kernel.dylib`__psynch_mutexwait + 10
          frame #0: 0x00007fff8ac66122 libsystem_kernel.dylib`__psynch_mutexwait + 10
          frame #1: 0x00007fff82a8edfd libsystem_c.dylib`pthread_mutex_lock + 536
          frame #2: 0x00007fff85141261 libc++abi.dylib`__cxa_guard_acquire + 33
          frame #3: 0x00000001006f9feb QtCore`QCoreGlobalData::instance() + 59
          frame #4: 0x00000001007048ec QtCore`QTextCodec::codecForLocale() + 12
          frame #5: 0x000000010060c42e QtCore`QTextStreamPrivate::reset() + 142
          frame #6: 0x000000010060c2e9 QtCore`QTextStreamPrivate::QTextStreamPrivate(QTextStream*) + 233
          frame #7: 0x000000010060d465 QtCore`QTextStream::QTextStream(QString*, QFlags<QIODevice::OpenModeFlag>) + 53
          frame #8: 0x00000001004c085e QtCore`QMessageLogger::debug() const + 46
          frame #9: 0x00000001000037d3 locktest`WorkerThread::run(this=0x00007fff5fbffd70) + 67 at main.cpp:23
          frame #10: 0x00000001004cf7d0 QtCore`QThreadPrivate::start(void*) + 352
          frame #11: 0x00007fff82a897a2 libsystem_c.dylib`_pthread_start + 327
          frame #12: 0x00007fff82a761e1 libsystem_c.dylib`thread_start + 13
      

        Attachments

          Issue Links

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

            Activity

              People

              • Assignee:
                kkohne Kai Köhne
                Reporter:
                kkohne Kai Köhne
              • Votes:
                0 Vote for this issue
                Watchers:
                4 Start watching this issue

                Dates

                • Created:
                  Updated:
                  Resolved:

                  Gerrit Reviews

                  There are no open Gerrit changes