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

[Regression] QEventLoopLocker causes application to quit even with open windows

    XMLWordPrintable

Details

    • Linux/X11
    • 0b494c47d (dev), a8ef8ea55 (6.7), 538b92840 (tqtc/lts-6.5)

    Description

      With the KDE platform plugin theme, closing a file dialog seems to quit the QApplication:

      #include <QApplication>
      #include <QUrl>
      #include <QTimer>
      #include <QFileDialog>
      #include <QWidget>
      
      int main(int argc, char *argv[]) {
          // Without this (i.e. GTK file dialog), doesn't reproduce
          qputenv("QT_QPA_PLATFORMTHEME", QByteArray("kde"));
      
          QApplication app(argc, argv);
          
          // If there is no widget, reproduces always.
          // If there is a widget, setQuitOnLastWindowClosed(false)
          // (sic!) is needed to reproduce.
          app.setQuitOnLastWindowClosed(false);
          QWidget w;
          w.show();
          
          // Calling this directly before main loop runs -> doesn't reproduce
          QTimer::singleShot(0, []() { QFileDialog::getOpenFileName(); });
          
          return app.exec();
      }
      

      This seems to be a recent regression: I got two people who seem to run into this on Archlinux as of around 3 weeks ago. I'm not sure what exactly is the culprit, however (and I can't reproduce this with the other Qt versions I have installed because the platform plugin is missing). It might be that it got introduced with Qt 6.7, but it might also be the switch from KDE 5 to 6...

      I'm a bit at a loss on how to debug this, unfortunately. After some different attempts at finding the culprit, I ended up with:

      diff --git i/src/corelib/kernel/qcoreapplication.cpp w/src/corelib/kernel/qcoreapplication.cpp
      index 1ce2642cf2..8d6d91cc2e 100644
      --- i/src/corelib/kernel/qcoreapplication.cpp
      +++ w/src/corelib/kernel/qcoreapplication.cpp
      @@ -108,6 +108,7 @@
       #include <algorithm>
       #include <memory>
       #include <string>
      +#include <csignal>
       
       QT_BEGIN_NAMESPACE
       
      @@ -1650,6 +1651,9 @@ QCoreApplicationPrivate::QPostEventListLocker QCoreApplicationPrivate::lockThrea
       */
       void QCoreApplication::postEvent(QObject *receiver, QEvent *event, int priority)
       {
      +    if (event->type() == QEvent::Quit) {
      +        std::raise(SIGTRAP);
      +    }
           Q_ASSERT_X(event, "QCoreApplication::postEvent", "Unexpected null event");
       
           Q_TRACE_SCOPE(QCoreApplication_postEvent, receiver, event, event->type());
      

      which lead me to:

      #0  __pthread_kill_implementation (threadid=<optimized out>, signo=signo@entry=5, no_tid=no_tid@entry=0) at pthread_kill.c:44
      #1  0x00007ffff78ab393 in __pthread_kill_internal (signo=5, threadid=<optimized out>) at pthread_kill.c:78
      #2  0x00007ffff785a6c8 in __GI_raise (sig=5) at ../sysdeps/posix/raise.c:26
      #3  0x00007ffff5964233 in QCoreApplication::postEvent(QObject*, QEvent*, int) () at /usr/lib/libQt6Core.so.6
      #4  0x00007ffff596e731 in QEventLoopLocker::~QEventLoopLocker() () at /usr/lib/libQt6Core.so.6
      #5  0x00007fffd29a1897 in KJobPrivate::~KJobPrivate (this=0x555557a01310, this=<optimized out>) at /usr/src/debug/kcoreaddons/kcoreaddons-6.1.0/src/lib/jobs/kjob.cpp:26
      #6  0x00007fffd29a193e in KCompositeJobPrivate::~KCompositeJobPrivate (this=0x555557a01310, this=<optimized out>) at /usr/src/debug/kcoreaddons/kcoreaddons-6.1.0/src/lib/jobs/kcompositejob.cpp:18
      #7  0x00007fffd29ab614 in std::default_delete<KJobPrivate>::operator() (__ptr=<optimized out>, this=<optimized out>) at /usr/include/c++/13.2.1/bits/unique_ptr.h:93
      #8  std::unique_ptr<KJobPrivate, std::default_delete<KJobPrivate> >::~unique_ptr (this=0x55555797f8f0, this=<optimized out>) at /usr/include/c++/13.2.1/bits/unique_ptr.h:404
      #9  KJob::~KJob (this=0x55555797f8e0, this=<optimized out>) at /usr/src/debug/kcoreaddons/kcoreaddons-6.1.0/src/lib/jobs/kjob.cpp:51
      #10 0x00007fffd2f9b6fe in KIO::ListJob::~ListJob (this=0x55555797f8e0, this=<optimized out>) at /usr/src/debug/kio/kio-6.1.0/src/core/listjob.cpp:82
      #11 0x00007ffff59a9218 in QObject::event(QEvent*) () at /usr/lib/libQt6Core.so.6
      #12 0x00007ffff237bcdc in QApplicationPrivate::notify_helper(QObject*, QEvent*) () at /usr/lib/libQt6Widgets.so.6
      ...
      #23 0x00007ffff5968ec4 in QCoreApplication::exec() () at /usr/lib/libQt6Core.so.6
      

      but it's still unclear to me why the QEventLoopLocker being destroyed here leads to the QApplication quitting - after all, it still has a window open! Also, ironically, with the default setQuitOnLastWindowClosed(true), this isn't reproducable.

      Downstream bug: https://github.com/qutebrowser/qutebrowser/issues/8143

      Happy to provide more information if someone can tell me how to best track this down further.

      Attachments

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

        Activity

          People

            vestbo Tor Arne Vestbø
            the compiler Florian Bruhin
            Votes:
            1 Vote for this issue
            Watchers:
            7 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved:

              Gerrit Reviews