Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

QMenuBar creates QThread?



  • Hi all,

    I'm trying to debug my code and I've run my application through Helgrind and found some peculiar results.

    new QMenuBar( this )  ;
    

    results in a helgrind output of pointing to the line of this new

    Thread #3 was created. 
    

    From there on out I consistently get lock order violations from this thread and it appears to be running its own event loop.

    What is going on?


  • Qt Champions 2019

    Use a debugger and take a look who spawns it.



  • I'm not sure if my post made it clear enough. The constructor of QMenuBar spans the new thread. Where is that in the documentation and why?


  • Lifetime Qt Champion

    @HunterMetcalfe
    hi
    I think Helgrind is wrong.
    Looking over
    https://code.woboq.org/qt5/qtbase/src/widgets/widgets/qmenubar.cpp.html
    There is no signs of any usage of a thread.

    Also from a rational standpoint, why would it need one and what could it possibly use it for.

    So unless its related to some platform-specific use of a native control,
    im not sure we can conclude it does make a thread.



  • @mrjj said in QMenuBar creates QThread?:

    There is no signs of any usage of a thread.

    So that's along the lines of thinking I had. It shouldn't need a second thread as the main QApplication event loop will handle all events. Perhaps Helgrind is incorrect. I have found numerous compatibility issues with Valgrind and Helgrind. However, since QThread was built upon pthread, I'm not so quick to discount the output. I've replaced my class names with the 'YourWidget' moniker below.

     ==19972== Thread #3 was created
     ==19972==    at 0x7CC5E6E: clone (in /usr/lib64/libc-2.17.so)
     ==19972==    by 0x7193F89: do_clone.constprop.4 (in /usr/lib64/libpthread-2.17.so)
     ==19972==    by 0x7195499: pthread_create@@GLIBC_2.2.5 (in /usr/lib64/libpthread-2.17.so)
     ==19972==    by 0x4C3062A: pthread_create_WRK (hg_intercepts.c:427)
    ==19972==    by 0x4C31708: pthread_create@* (hg_intercepts.c:460)
    ==19972==    by 0x686DDC5: QThread::start(QThread::Priority) (in /usr/local/qt/5.9.4/gcc_64/lib/libQt5Core.so.5.9.4)
    ==19972==    by 0x12F5A473: ??? (in /usr/local/qt/5.9.4/gcc_64/lib/libQt5DBus.so.5.9.4)
    ==19972==    by 0x12F5B82B: QDBusConnection::sessionBus() (in /usr/local/qt/5.9.4/gcc_64/lib/libQt5DBus.so.5.9.4)
     ==19972==    by 0x127755DA: ??? (in /usr/local/qt/5.9.4/gcc_64/lib/libQt5XcbQpa.so.5.9.4)
     ==19972==    by 0x5AB4297: ??? (in /usr/local/qt/5.9.4/gcc_64/lib/libQt5Widgets.so.5.9.4)
     ==19972==    by 0x4A90DA: YourWidgetParent::YourWidgetParent(QWidget*) (YourWidgetParent.cpp:62)
    ==19972==    by 0x49D9CF: YourWidget::YourWidget(QWidget*) (YourWidget.cpp:10)
    

    Where YourWidget.cpp:10 is simply this

    YourWidget::YourWidget( QWidget * parent ) : YourWidgetParent( parent )
    

    and YourWidgetParent.cpp:62 is

    SetMenuBar( new QMenuBar( this )  ) ;
    

    implementation for SetMenuBar

       QMutexLocker locker( &m_mutex ) ;
       m_menuBar = menuBar ;
    

    Thank you!


  • Lifetime Qt Champion

    Hi
    It does a little strange.
    And it only gives " Thread #3 was created" if its a QMenuBar ?
    Like if you new something else, its not shown ?
    Also, did you try it in a clean project (seems so) to be sure nothing else can have an effect?


  • Lifetime Qt Champion

    Hi,

    One thing to take into account is that other dependencies might trigger threads creation as part of the normal run of an application which is outside of Qt's control.

    [edit: fixed text SGaist]



  • @SGaist I don't think that's true. The OS should not be creating threads unless you explicitly told it to do so. Such behavior would be vastly non-deterministic. By default, the first thread created in main is the root application thread. From there each thread creation event is tied to an explicit call to pthread_create ( even for QThreads). The OS should have nothing to do with it other than scheduling the threads.

    The reason this is an issue is I'm seeing very non-deterministic behavior. I constantly receive these outputs in Helgrind from Thread #3. My application randomly crashes when I click on the QMenuBar as well.

     313 ==19972== Thread #3: lock order "0xBDA77F0 before 0xBCF1820" violated
     314 ==19972== 
     315 ==19972== Observed (incorrect) order is: acquisition of lock at 0xBCF1820
     316 ==19972==    at 0x4C2FE72: QMutex_lock_WRK (hg_intercepts.c:3043)
     317 ==19972==    by 0x4C3239F: QMutex::lock() (hg_intercepts.c:3055)
     318 ==19972==    by 0x12F6B93F: ??? (in /usr/local/qt/5.9.4/gcc_64/lib/libQt5DBus.so.5.9.4)
     319 ==19972==    by 0x12FB2A54: ??? (in /usr/local/qt/5.9.4/gcc_64/lib/libQt5DBus.so.5.9.4)
     320 ==19972==    by 0x6A68E70: QObject::event(QEvent*) (in /usr/local/qt/5.9.4/gcc_64/lib/libQt5Core.so.5.9.4)
     321 ==19972==    by 0x6A3D8B2: QCoreApplication::notifyInternal2(QObject*, QEvent*) (in /usr/local/qt/5.9.4/gcc_64/lib/libQt5Core.so.5.9.4)
     322 ==19972==    by 0x6A3FF5A: QCoreApplicationPrivate::sendPostedEvents(QObject*, int, QThreadData*) (in /usr/local/qt/5.9.4/gcc_64/lib/libQt5Core.so.5.9.4)
     323 ==19972==    by 0x6A90BB2: ??? (in /usr/local/qt/5.9.4/gcc_64/lib/libQt5Core.so.5.9.4)
     324 ==19972==    by 0xA831048: g_main_context_dispatch (in /usr/lib64/libglib-2.0.so.0.5600.1)
     325 ==19972==    by 0xA8313A7: ??? (in /usr/lib64/libglib-2.0.so.0.5600.1)
     326 ==19972==    by 0xA83145B: g_main_context_iteration (in /usr/lib64/libglib-2.0.so.0.5600.1)
     327 ==19972==    by 0x6A901FE: QEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) (in /usr/local/qt/5.9.4/gcc_64/lib/libQt5Core.so.5.9.4)
     328 ==19972== 
     329 ==19972==  followed by a later acquisition of lock at 0xBDA77F0
     330 ==19972==    at 0x4C2DC90: mutex_lock_WRK (hg_intercepts.c:909)
     331 ==19972==    by 0x4C31AED: pthread_mutex_lock (hg_intercepts.c:925)
     332 ==19972==    by 0x13E5F7C2: dbus_connection_dispatch (in /usr/lib64/libdbus-1.so.3.14.14)
     333 ==19972==    by 0x12F6B970: ??? (in /usr/local/qt/5.9.4/gcc_64/lib/libQt5DBus.so.5.9.4)
     334 ==19972==    by 0x12FB2A54: ??? (in /usr/local/qt/5.9.4/gcc_64/lib/libQt5DBus.so.5.9.4)
     335 ==19972==    by 0x6A68E70: QObject::event(QEvent*) (in /usr/local/qt/5.9.4/gcc_64/lib/libQt5Core.so.5.9.4)
     336 ==19972==    by 0x6A3D8B2: QCoreApplication::notifyInternal2(QObject*, QEvent*) (in /usr/local/qt/5.9.4/gcc_64/lib/libQt5Core.so.5.9.4)
     337 ==19972==    by 0x6A3FF5A: QCoreApplicationPrivate::sendPostedEvents(QObject*, int, QThreadData*) (in /usr/local/qt/5.9.4/gcc_64/lib/libQt5Core.so.5.9.4)
     338 ==19972==    by 0x6A90BB2: ??? (in /usr/local/qt/5.9.4/gcc_64/lib/libQt5Core.so.5.9.4)
     339 ==19972==    by 0xA831048: g_main_context_dispatch (in /usr/lib64/libglib-2.0.so.0.5600.1)
     340 ==19972==    by 0xA8313A7: ??? (in /usr/lib64/libglib-2.0.so.0.5600.1)
     341 ==19972==    by 0xA83145B: g_main_context_iteration (in /usr/lib64/libglib-2.0.so.0.5600.1)
     343 ==19972== Required order was established by acquisition of lock at 0xBDA77F0
     344 ==19972==    at 0x4C2DC90: mutex_lock_WRK (hg_intercepts.c:909)
     345 ==19972==    by 0x4C31AED: pthread_mutex_lock (hg_intercepts.c:925)
     346 ==19972==    by 0x13E5CDCC: dbus_connection_set_watch_functions (in /usr/lib64/libdbus-1.so.3.14.14)
     347 ==19972==    by 0x12F69B7D: ??? (in /usr/local/qt/5.9.4/gcc_64/lib/libQt5DBus.so.5.9.4)
     348 ==19972==    by 0x12F5C183: ??? (in /usr/local/qt/5.9.4/gcc_64/lib/libQt5DBus.so.5.9.4)
     349 ==19972==    by 0x6A68E70: QObject::event(QEvent*) (in /usr/local/qt/5.9.4/gcc_64/lib/libQt5Core.so.5.9.4)
     350 ==19972==    by 0x6A3D8B2: QCoreApplication::notifyInternal2(QObject*, QEvent*) (in /usr/local/qt/5.9.4/gcc_64/lib/libQt5Core.so.5.9.4)
     351 ==19972==    by 0x6A3FF5A: QCoreApplicationPrivate::sendPostedEvents(QObject*, int, QThreadData*) (in /usr/local/qt/5.9.4/gcc_64/lib/libQt5Core.so.5.9.4)
     352 ==19972==    by 0x6A90BB2: ??? (in /usr/local/qt/5.9.4/gcc_64/lib/libQt5Core.so.5.9.4)
     353 ==19972==    by 0xA831048: g_main_context_dispatch (in /usr/lib64/libglib-2.0.so.0.5600.1)
     354 ==19972==    by 0xA8313A7: ??? (in /usr/lib64/libglib-2.0.so.0.5600.1)
     355 ==19972==    by 0xA83145B: g_main_context_iteration (in /usr/lib64/libglib-2.0.so.0.5600.1)
     356 ==19972== 
     357 ==19972==  followed by a later acquisition of lock at 0xBCF1820
     358 ==19972==    at 0x4C2FE72: QMutex_lock_WRK (hg_intercepts.c:3043)
     359 ==19972==    by 0x4C3239F: QMutex::lock() (hg_intercepts.c:3055)
     360 ==19972==    by 0x12F67494: ??? (in /usr/local/qt/5.9.4/gcc_64/lib/libQt5DBus.so.5.9.4)
     361 ==19972==    by 0x13E767D2: _dbus_watch_list_set_functions (in /usr/lib64/libdbus-1.so.3.14.14)
     362 ==19972==    by 0x13E5CDEE: dbus_connection_set_watch_functions (in /usr/lib64/libdbus-1.so.3.14.14)
     363 ==19972==    by 0x12F69B7D: ??? (in /usr/local/qt/5.9.4/gcc_64/lib/libQt5DBus.so.5.9.4)
     364 ==19972==    by 0x12F5C183: ??? (in /usr/local/qt/5.9.4/gcc_64/lib/libQt5DBus.so.5.9.4)
     365 ==19972==    by 0x6A68E70: QObject::event(QEvent*) (in /usr/local/qt/5.9.4/gcc_64/lib/libQt5Core.so.5.9.4)
     366 ==19972==    by 0x6A3D8B2: QCoreApplication::notifyInternal2(QObject*, QEvent*) (in /usr/local/qt/5.9.4/gcc_64/lib/libQt5Core.so.5.9.4)
     367 ==19972==    by 0x6A3FF5A: QCoreApplicationPrivate::sendPostedEvents(QObject*, int, QThreadData*) (in /usr/local/qt/5.9.4/gcc_64/lib/libQt5Core.so.5.9.4)
     368 ==19972==    by 0x6A90BB2: ??? (in /usr/local/qt/5.9.4/gcc_64/lib/libQt5Core.so.5.9.4)
     369 ==19972==    by 0xA831048: g_main_context_dispatch (in /usr/lib64/libglib-2.0.so.0.5600.1)
    
    
    

  • Qt Champions 2019

    @HunterMetcalfe said in QMenuBar creates QThread?:

    My application randomly crashes when I click on the QMenuBar as well.

    This for sure has nothing to do with a Qt internal thread.

    The thread above looks like an internal thread needed for communication with dbus. I doubt it's only created when QMenuBar is created but also others. When you install the debug informations for Qt5XcbQpa, Widgets and dbus you will see more where it is called.


  • Lifetime Qt Champion

    Sorry, I miswrote what I had in mind. I fixed it.

    What likely happens is that the new thread you see is triggered by the use of DBus. IIRC, there's something with an application menu and DBus on Linux but I currently don't recall all the details.



  • @Christian-Ehrlicher and @SGaist thank you! These are the details for which I was looking. @Christian-Ehrlicher you're right that I don't have the debug information for Qt5XcbQpa. That must be why I have the '???' for the function call.

    I wanted to rule this out as a potential issue with the crash I'm seeing.

    Thank you


Log in to reply