Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Global static QPixmapCache in Qt internals
QtWS25 Last Chance

Global static QPixmapCache in Qt internals

Scheduled Pinned Locked Moved Unsolved General and Desktop
34 Posts 7 Posters 2.4k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • kshegunovK kshegunov

    @JKSH said in QApplication in std::thread:

    I believe it is fixable with m_qPlotsControl->deleteLater();... but that needs to be done before QApplication::exec() returns, because QDeferredDeleteEvent won't be processed without an event loop.

    I still don't understand this. For what reason should that be the case, and why would this generate a crash? I'm pretty sure deferred deletes are processed after the event loop has exited (see for example the QThread::finished -> QObject::deleteLater), but even if that weren't the case the QPushButton's destructor is going to be run before the thread actually finishes and before the application object's destructor's run (there's no difference between main() and any other function from c++'s point of view).

    JKSHJ Offline
    JKSHJ Offline
    JKSH
    Moderators
    wrote on last edited by JKSH
    #1

    [Forked from https://forum.qt.io/topic/126128/qapplication-in-std-thread -- Sorry, I messed up the order of posts when I did the fork; this top post should be further down]

    @kshegunov said in QApplication in std::thread:

    why would this generate a crash?

    Since the widget creates a timer in the background, then it's probably receiving background events/signals. delete could cause the event/signal handler to act on a dangling pointer -- that's how it could generate a crash. And that's why deleteLater() can fix the crash. (Alternatively, we could change from a heap-allocated widget to a stack-allocated widget)

    I'm pretty sure deferred deletes are processed after the event loop has exited (see for example the QThread::finished -> QObject::deleteLater)

    The code below prints "Bye" but not "Widget destroyed", proving that the Widget's destructor is not run:

    // widget.h
    #include <QWidget>
    
    class Widget : public QWidget
    {
        Q_OBJECT
    public:
        Widget(QWidget *parent = nullptr) : QWidget(parent) {}
        ~Widget(){ qDebug("Widget destroyed"); }
    };
    
    // main.cpp
    #include "widget.h"
    #include <QApplication>
    #include <chrono>
    #include <thread>
    
    using namespace std::chrono_literals;
    
    int main(int argc, char *argv[])
    {
        std::thread thr([&]
        {
            QApplication a(argc, argv);
            auto w = new Widget;
            w->show();
            a.exec();
    
            // delete w; // This WILL run the Widget's destructor
    
            w->deleteLater(); // This WON'T run the Widget's destructor
        });
    
        std::this_thread::sleep_for(5000ms);
    
        QMetaObject::invokeMethod(qApp, &QApplication::quit);
        thr.join();
    
        std::this_thread::sleep_for(5000ms);
        qDebug("Bye");
    }
    

    Anyway, I was trying to say that @Suthiro can't simply replace delete m_qPlotsControl; with m_qPlotsControl->deleteLater(); in-place at https://stackoverflow.com/questions/67257329/weird-qpushbutton-bug . Some re-shuffling is required.

    Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

    kshegunovK 1 Reply Last reply
    0
    • kshegunovK kshegunov

      @JKSH said in QApplication in std::thread:

      That's what I asked @Suthiro too :-) I don't have any crashing code to work with.

      I meant the trace from QT_FATAL_WARNINGS, so we could see what was called leading to the mentioned warning.

      @JKSH said in QApplication in std::thread:

      When main() is about to return, the program tries to unload the timer. But the unloading is done by the main() thread, not the Qt thread. Hence the complaint, "QObject::~QObject: Timers cannot be stopped from another thread".

      I really doubt this as the runtime doesn't run your destructors automatically. In any case if that is the case, then it's a bug in the push button, which should be posted on the tracker.

      JKSHJ Offline
      JKSHJ Offline
      JKSH
      Moderators
      wrote on last edited by
      #2

      @kshegunov said in QApplication in std::thread:

      I meant the trace from QT_FATAL_WARNINGS, so we could see what was called leading to the mentioned warning.

      Nothing useful from GDB:

      1 qt_message_fatal(QtMsgType, QMessageLogContext const&, QString const&) [clone .isra.4]   0x68e23630 
      2 ??                                                                                       0x3121a30  
      

      @JKSH said in QApplication in std::thread:

      When main() is about to return, the program tries to unload the timer. But the unloading is done by the main() thread, not the Qt thread. Hence the complaint, "QObject::~QObject: Timers cannot be stopped from another thread".

      I really doubt this as the runtime doesn't run your destructors automatically.

      I don't have a better explanation for this. Do you?:

      #include <QApplication>
      #include <QPushButton>
      #include <QDebug>
      #include <chrono>
      #include <thread>
      
      int main(int argc, char *argv[])
      {
          std::thread thr([&]
          {
              QApplication a(argc, argv);
              QPushButton btn("Push");
              btn.show();
              a.exec();
      
              qDebug("Event loop stopped");
          });
      
          // Play with the QPushButton within the next 5 seconds
          using namespace std::chrono_literals;
          std::this_thread::sleep_for(5000ms);
      
          QMetaObject::invokeMethod(qApp, &QApplication::quit);
          thr.join();
          qDebug("Thread stopped");
      
          std::this_thread::sleep_for(5000ms);
          qDebug("Waiting, waiting...");
          
          std::this_thread::sleep_for(5000ms);
          qDebug("Program shutting down");
      }
      

      The output sequence is:

      1. (Pause 5s)
      2. "Event loop stopped"
      3. "Thread stopped"
      4. (Pause 5s)
      5. "Waiting, waiting..."
      6. (Pause 5s)
      7. "Program shutting down"
      8. "QObject::~QObject: Timers cannot be stopped from another thread"

      If you don't interact with the button, then #8 doesn't appear. No difference if qDebug is switched to std::cout with flush.

      In any case if that is the case, then it's a bug in the push button, which should be posted on the tracker.

      QPushButton's timers aren't alone.

      For example, the global QPixmapCache object hangs around after the destruction of QApplication too.

      Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

      kshegunovK J.HilkJ 2 Replies Last reply
      0
      • JKSHJ JKSH

        @kshegunov said in QApplication in std::thread:

        I meant the trace from QT_FATAL_WARNINGS, so we could see what was called leading to the mentioned warning.

        Nothing useful from GDB:

        1 qt_message_fatal(QtMsgType, QMessageLogContext const&, QString const&) [clone .isra.4]   0x68e23630 
        2 ??                                                                                       0x3121a30  
        

        @JKSH said in QApplication in std::thread:

        When main() is about to return, the program tries to unload the timer. But the unloading is done by the main() thread, not the Qt thread. Hence the complaint, "QObject::~QObject: Timers cannot be stopped from another thread".

        I really doubt this as the runtime doesn't run your destructors automatically.

        I don't have a better explanation for this. Do you?:

        #include <QApplication>
        #include <QPushButton>
        #include <QDebug>
        #include <chrono>
        #include <thread>
        
        int main(int argc, char *argv[])
        {
            std::thread thr([&]
            {
                QApplication a(argc, argv);
                QPushButton btn("Push");
                btn.show();
                a.exec();
        
                qDebug("Event loop stopped");
            });
        
            // Play with the QPushButton within the next 5 seconds
            using namespace std::chrono_literals;
            std::this_thread::sleep_for(5000ms);
        
            QMetaObject::invokeMethod(qApp, &QApplication::quit);
            thr.join();
            qDebug("Thread stopped");
        
            std::this_thread::sleep_for(5000ms);
            qDebug("Waiting, waiting...");
            
            std::this_thread::sleep_for(5000ms);
            qDebug("Program shutting down");
        }
        

        The output sequence is:

        1. (Pause 5s)
        2. "Event loop stopped"
        3. "Thread stopped"
        4. (Pause 5s)
        5. "Waiting, waiting..."
        6. (Pause 5s)
        7. "Program shutting down"
        8. "QObject::~QObject: Timers cannot be stopped from another thread"

        If you don't interact with the button, then #8 doesn't appear. No difference if qDebug is switched to std::cout with flush.

        In any case if that is the case, then it's a bug in the push button, which should be posted on the tracker.

        QPushButton's timers aren't alone.

        For example, the global QPixmapCache object hangs around after the destruction of QApplication too.

        kshegunovK Offline
        kshegunovK Offline
        kshegunov
        Moderators
        wrote on last edited by kshegunov
        #3

        @JKSH said in QApplication in std::thread:

        @kshegunov said in QApplication in std::thread:

        I meant the trace from QT_FATAL_WARNINGS, so we could see what was called leading to the mentioned warning.

        Nothing useful from GDB:

        1 qt_message_fatal(QtMsgType, QMessageLogContext const&, QString const&) [clone .isra.4]   0x68e23630 
        2 ??                                                                                       0x3121a30  
        

        Did you run this with a release Qt or with -developer-build? :)
        (The address is rather odd, though)

        @JKSH said in QApplication in std::thread:

        If you don't interact with the button, then #8 doesn't appear. No difference if qDebug is switched to std::cout with flush.

        Can't reproduce:

        
        09:01:47: Debugging starts
        Event loop stopped
        Thread stopped
        Waiting, waiting...
        Program shutting down
        

        What's your kit?
        I have 5.15.2 from the repo with gcc 10.2.1.

        Read and abide by the Qt Code of Conduct

        JKSHJ 1 Reply Last reply
        0
        • JKSHJ JKSH

          @kshegunov said in QApplication in std::thread:

          I meant the trace from QT_FATAL_WARNINGS, so we could see what was called leading to the mentioned warning.

          Nothing useful from GDB:

          1 qt_message_fatal(QtMsgType, QMessageLogContext const&, QString const&) [clone .isra.4]   0x68e23630 
          2 ??                                                                                       0x3121a30  
          

          @JKSH said in QApplication in std::thread:

          When main() is about to return, the program tries to unload the timer. But the unloading is done by the main() thread, not the Qt thread. Hence the complaint, "QObject::~QObject: Timers cannot be stopped from another thread".

          I really doubt this as the runtime doesn't run your destructors automatically.

          I don't have a better explanation for this. Do you?:

          #include <QApplication>
          #include <QPushButton>
          #include <QDebug>
          #include <chrono>
          #include <thread>
          
          int main(int argc, char *argv[])
          {
              std::thread thr([&]
              {
                  QApplication a(argc, argv);
                  QPushButton btn("Push");
                  btn.show();
                  a.exec();
          
                  qDebug("Event loop stopped");
              });
          
              // Play with the QPushButton within the next 5 seconds
              using namespace std::chrono_literals;
              std::this_thread::sleep_for(5000ms);
          
              QMetaObject::invokeMethod(qApp, &QApplication::quit);
              thr.join();
              qDebug("Thread stopped");
          
              std::this_thread::sleep_for(5000ms);
              qDebug("Waiting, waiting...");
              
              std::this_thread::sleep_for(5000ms);
              qDebug("Program shutting down");
          }
          

          The output sequence is:

          1. (Pause 5s)
          2. "Event loop stopped"
          3. "Thread stopped"
          4. (Pause 5s)
          5. "Waiting, waiting..."
          6. (Pause 5s)
          7. "Program shutting down"
          8. "QObject::~QObject: Timers cannot be stopped from another thread"

          If you don't interact with the button, then #8 doesn't appear. No difference if qDebug is switched to std::cout with flush.

          In any case if that is the case, then it's a bug in the push button, which should be posted on the tracker.

          QPushButton's timers aren't alone.

          For example, the global QPixmapCache object hangs around after the destruction of QApplication too.

          J.HilkJ Offline
          J.HilkJ Offline
          J.Hilk
          Moderators
          wrote on last edited by
          #4

          @JKSH this actually crashes for me on btn.show()

          1  __pthread_kill                                                                                                                                                                                                                                            (x86_64) /usr/lib/system/libsystem_kernel.dylib                                                0x7fff2030d462 
          2  pthread_kill                                                                                                                                                                                                                                              (x86_64) /usr/lib/system/libsystem_pthread.dylib                                               0x7fff2033b610 
          3  abort                                                                                                                                                                                                                                                     (x86_64) /usr/lib/system/libsystem_c.dylib                                                     0x7fff2028e720 
          4  abort_message                                                                                                                                                                                                                                             (x86_64) /usr/lib/libc++abi.dylib                                                              0x7fff20300418 
          5  demangling_terminate_handler()                                                                                                                                                                                                                            (x86_64) /usr/lib/libc++abi.dylib                                                              0x7fff202f1a7d 
          6  _objc_terminate()                                                                                                                                                                                                                                         (x86_64h) /usr/lib/libobjc.A.dylib                                                             0x7fff201e79b1 
          7  std::__terminate(void ( *)())                                                                                                                                                                                                                             (x86_64) /usr/lib/libc++abi.dylib                                                              0x7fff202ff847 
          8  __cxxabiv1::failed_throw(__cxxabiv1::__cxa_exception *)                                                                                                                                                                                                   (x86_64) /usr/lib/libc++abi.dylib                                                              0x7fff20302167 
          9  __cxa_throw                                                                                                                                                                                                                                               (x86_64) /usr/lib/libc++abi.dylib                                                              0x7fff2030212e 
          10 objc_exception_throw                                                                                                                                                                                                                                      (x86_64h) /usr/lib/libobjc.A.dylib                                                             0x7fff201e54f7 
          11 -[NSException raise]                                                                                                                                                                                                                                      (x86_64h) /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation        0x7fff204d5a9a 
          12 -[NSWindow(NSWindow_Theme) _postWindowNeedsToResetDragMarginsUnlessPostingDisabled]                                                                                                                                                                       (x86_64) /System/Library/Frameworks/AppKit.framework/Versions/C/AppKit                         0x7fff22c7597d 
          13 -[NSWindow _initContent:styleMask:backing:defer:contentView:]                                                                                                                                                                                             (x86_64) /System/Library/Frameworks/AppKit.framework/Versions/C/AppKit                         0x7fff22c606d5 
          14 -[NSWindow initWithContentRect:styleMask:backing:defer:]                                                                                                                                                                                                  (x86_64) /System/Library/Frameworks/AppKit.framework/Versions/C/AppKit                         0x7fff22c6016f 
          15 -[NSWindow initWithContentRect:styleMask:backing:defer:screen:]                                                                                                                                                                                           (x86_64) /System/Library/Frameworks/AppKit.framework/Versions/C/AppKit                         0x7fff22f6a2c8 
          16 -[QNSWindow initWithContentRect:styleMask:backing:defer:screen:platformWindow:]                                                                                                                                                                           (x86_64) /Users/jonashilk/Qt/5.15.2/clang_64/plugins/platforms/libqcocoa.dylib                 0x10b335725    
          17 QCocoaWindow::createNSWindow(bool)                                                                                                                                                                                                                        (x86_64) /Users/jonashilk/Qt/5.15.2/clang_64/plugins/platforms/libqcocoa.dylib                 0x10b322cac    
          18 QCocoaWindow::recreateWindowIfNeeded()                                                                                                                                                                                                                    (x86_64) /Users/jonashilk/Qt/5.15.2/clang_64/plugins/platforms/libqcocoa.dylib                 0x10b31c672    
          19 QCocoaWindow::initialize()                                                                                                                                                                                                                                (x86_64) /Users/jonashilk/Qt/5.15.2/clang_64/plugins/platforms/libqcocoa.dylib                 0x10b31c0fe    
          20 QWindowPrivate::create(bool, unsigned long long)                                                                                                                                                                                                          (x86_64) /Users/jonashilk/Qt/5.15.2/clang_64/lib/QtGui.framework/Versions/5/QtGui              0x1007aceb7    
          21 QWidgetPrivate::create()                                                                                                                                                                                                                                  (x86_64) /Users/jonashilk/Qt/5.15.2/clang_64/lib/QtWidgets.framework/Versions/5/QtWidgets      0x10016c771    
          22 QWidget::create(unsigned long long, bool, bool)                                                                                                                                                                                                           (x86_64) /Users/jonashilk/Qt/5.15.2/clang_64/lib/QtWidgets.framework/Versions/5/QtWidgets      0x10016b414    
          23 QWidgetPrivate::setVisible(bool)                                                                                                                                                                                                                          (x86_64) /Users/jonashilk/Qt/5.15.2/clang_64/lib/QtWidgets.framework/Versions/5/QtWidgets      0x10017e81d    
          24 main::$_0::operator()() const                                                                                                                                                                                                                             main.cpp                                                                                  13   0x100006538    
          25 decltype(std::forward<main::$_0>(fp)()) std::__invoke<main::$_0>(main::$_0&&)                                                                                                                                                                             type_traits                                                                               3545 0x10000647d    
          26 void std::__thread_execute<std::unique_ptr<std::__thread_struct, std::default_delete<std::__thread_struct>>, main::$_0>(std::tuple<std::unique_ptr<std::__thread_struct, std::default_delete<std::__thread_struct>>, main::$_0>&, std::__tuple_indices<>) thread                                                                                    273  0x1000063e5    
          27 void * std::__thread_proxy<std::tuple<std::unique_ptr<std::__thread_struct, std::default_delete<std::__thread_struct>>, main::$_0>>(void *)                                                                                                               thread                                                                                    284  0x100005c16    
          28 _pthread_start                                                                                                                                                                                                                                            (x86_64) /usr/lib/system/libsystem_pthread.dylib                                               0x7fff2033b950 
          29 thread_start                                                                                                                                                                                                                                              (x86_64) /usr/lib/system/libsystem_pthread.dylib                                               0x7fff2033747b 
          
          

          Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


          Q: What's that?
          A: It's blue light.
          Q: What does it do?
          A: It turns blue.

          kshegunovK 1 Reply Last reply
          0
          • J.HilkJ J.Hilk

            @JKSH this actually crashes for me on btn.show()

            1  __pthread_kill                                                                                                                                                                                                                                            (x86_64) /usr/lib/system/libsystem_kernel.dylib                                                0x7fff2030d462 
            2  pthread_kill                                                                                                                                                                                                                                              (x86_64) /usr/lib/system/libsystem_pthread.dylib                                               0x7fff2033b610 
            3  abort                                                                                                                                                                                                                                                     (x86_64) /usr/lib/system/libsystem_c.dylib                                                     0x7fff2028e720 
            4  abort_message                                                                                                                                                                                                                                             (x86_64) /usr/lib/libc++abi.dylib                                                              0x7fff20300418 
            5  demangling_terminate_handler()                                                                                                                                                                                                                            (x86_64) /usr/lib/libc++abi.dylib                                                              0x7fff202f1a7d 
            6  _objc_terminate()                                                                                                                                                                                                                                         (x86_64h) /usr/lib/libobjc.A.dylib                                                             0x7fff201e79b1 
            7  std::__terminate(void ( *)())                                                                                                                                                                                                                             (x86_64) /usr/lib/libc++abi.dylib                                                              0x7fff202ff847 
            8  __cxxabiv1::failed_throw(__cxxabiv1::__cxa_exception *)                                                                                                                                                                                                   (x86_64) /usr/lib/libc++abi.dylib                                                              0x7fff20302167 
            9  __cxa_throw                                                                                                                                                                                                                                               (x86_64) /usr/lib/libc++abi.dylib                                                              0x7fff2030212e 
            10 objc_exception_throw                                                                                                                                                                                                                                      (x86_64h) /usr/lib/libobjc.A.dylib                                                             0x7fff201e54f7 
            11 -[NSException raise]                                                                                                                                                                                                                                      (x86_64h) /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation        0x7fff204d5a9a 
            12 -[NSWindow(NSWindow_Theme) _postWindowNeedsToResetDragMarginsUnlessPostingDisabled]                                                                                                                                                                       (x86_64) /System/Library/Frameworks/AppKit.framework/Versions/C/AppKit                         0x7fff22c7597d 
            13 -[NSWindow _initContent:styleMask:backing:defer:contentView:]                                                                                                                                                                                             (x86_64) /System/Library/Frameworks/AppKit.framework/Versions/C/AppKit                         0x7fff22c606d5 
            14 -[NSWindow initWithContentRect:styleMask:backing:defer:]                                                                                                                                                                                                  (x86_64) /System/Library/Frameworks/AppKit.framework/Versions/C/AppKit                         0x7fff22c6016f 
            15 -[NSWindow initWithContentRect:styleMask:backing:defer:screen:]                                                                                                                                                                                           (x86_64) /System/Library/Frameworks/AppKit.framework/Versions/C/AppKit                         0x7fff22f6a2c8 
            16 -[QNSWindow initWithContentRect:styleMask:backing:defer:screen:platformWindow:]                                                                                                                                                                           (x86_64) /Users/jonashilk/Qt/5.15.2/clang_64/plugins/platforms/libqcocoa.dylib                 0x10b335725    
            17 QCocoaWindow::createNSWindow(bool)                                                                                                                                                                                                                        (x86_64) /Users/jonashilk/Qt/5.15.2/clang_64/plugins/platforms/libqcocoa.dylib                 0x10b322cac    
            18 QCocoaWindow::recreateWindowIfNeeded()                                                                                                                                                                                                                    (x86_64) /Users/jonashilk/Qt/5.15.2/clang_64/plugins/platforms/libqcocoa.dylib                 0x10b31c672    
            19 QCocoaWindow::initialize()                                                                                                                                                                                                                                (x86_64) /Users/jonashilk/Qt/5.15.2/clang_64/plugins/platforms/libqcocoa.dylib                 0x10b31c0fe    
            20 QWindowPrivate::create(bool, unsigned long long)                                                                                                                                                                                                          (x86_64) /Users/jonashilk/Qt/5.15.2/clang_64/lib/QtGui.framework/Versions/5/QtGui              0x1007aceb7    
            21 QWidgetPrivate::create()                                                                                                                                                                                                                                  (x86_64) /Users/jonashilk/Qt/5.15.2/clang_64/lib/QtWidgets.framework/Versions/5/QtWidgets      0x10016c771    
            22 QWidget::create(unsigned long long, bool, bool)                                                                                                                                                                                                           (x86_64) /Users/jonashilk/Qt/5.15.2/clang_64/lib/QtWidgets.framework/Versions/5/QtWidgets      0x10016b414    
            23 QWidgetPrivate::setVisible(bool)                                                                                                                                                                                                                          (x86_64) /Users/jonashilk/Qt/5.15.2/clang_64/lib/QtWidgets.framework/Versions/5/QtWidgets      0x10017e81d    
            24 main::$_0::operator()() const                                                                                                                                                                                                                             main.cpp                                                                                  13   0x100006538    
            25 decltype(std::forward<main::$_0>(fp)()) std::__invoke<main::$_0>(main::$_0&&)                                                                                                                                                                             type_traits                                                                               3545 0x10000647d    
            26 void std::__thread_execute<std::unique_ptr<std::__thread_struct, std::default_delete<std::__thread_struct>>, main::$_0>(std::tuple<std::unique_ptr<std::__thread_struct, std::default_delete<std::__thread_struct>>, main::$_0>&, std::__tuple_indices<>) thread                                                                                    273  0x1000063e5    
            27 void * std::__thread_proxy<std::tuple<std::unique_ptr<std::__thread_struct, std::default_delete<std::__thread_struct>>, main::$_0>>(void *)                                                                                                               thread                                                                                    284  0x100005c16    
            28 _pthread_start                                                                                                                                                                                                                                            (x86_64) /usr/lib/system/libsystem_pthread.dylib                                               0x7fff2033b950 
            29 thread_start                                                                                                                                                                                                                                              (x86_64) /usr/lib/system/libsystem_pthread.dylib                                               0x7fff2033747b 
            
            
            kshegunovK Offline
            kshegunovK Offline
            kshegunov
            Moderators
            wrote on last edited by
            #5

            @J-Hilk said in QApplication in std::thread:

            @JKSH this actually crashes for me on btn.show()

            That's expected. MacOS does not support plugging into the event loop from a thread different from main(). Should work on linux and windows, though.

            Read and abide by the Qt Code of Conduct

            J.HilkJ 1 Reply Last reply
            2
            • kshegunovK kshegunov

              @JKSH said in QApplication in std::thread:

              @kshegunov said in QApplication in std::thread:

              I meant the trace from QT_FATAL_WARNINGS, so we could see what was called leading to the mentioned warning.

              Nothing useful from GDB:

              1 qt_message_fatal(QtMsgType, QMessageLogContext const&, QString const&) [clone .isra.4]   0x68e23630 
              2 ??                                                                                       0x3121a30  
              

              Did you run this with a release Qt or with -developer-build? :)
              (The address is rather odd, though)

              @JKSH said in QApplication in std::thread:

              If you don't interact with the button, then #8 doesn't appear. No difference if qDebug is switched to std::cout with flush.

              Can't reproduce:

              
              09:01:47: Debugging starts
              Event loop stopped
              Thread stopped
              Waiting, waiting...
              Program shutting down
              

              What's your kit?
              I have 5.15.2 from the repo with gcc 10.2.1.

              JKSHJ Offline
              JKSHJ Offline
              JKSH
              Moderators
              wrote on last edited by JKSH
              #6

              @kshegunov said in QApplication in std::thread:

              Did you run this with a release Qt or with -developer-build? :)
              (The address is rather odd, though)

              Ah, right... I thought the Debug build would suffice. Don't have a dev build right now.

              Can't reproduce:

              ...

              What's your kit?
              I have 5.15.2 from the repo with gcc 10.2.1.

              Same result for me on Windows 10 20H2, with all official builds of:

              • Qt 5.12.10 MSVC 2017 64-bit (using MSVC 2019 compiler)
              • Qt 5.14.2 MinGW 7.3.0 32-bit
              • Qt 5.15.2 MSVC 2019 64-bit

              Might be Windows-specific.

              Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

              kshegunovK 1 Reply Last reply
              1
              • JKSHJ JKSH

                @kshegunov said in QApplication in std::thread:

                Did you run this with a release Qt or with -developer-build? :)
                (The address is rather odd, though)

                Ah, right... I thought the Debug build would suffice. Don't have a dev build right now.

                Can't reproduce:

                ...

                What's your kit?
                I have 5.15.2 from the repo with gcc 10.2.1.

                Same result for me on Windows 10 20H2, with all official builds of:

                • Qt 5.12.10 MSVC 2017 64-bit (using MSVC 2019 compiler)
                • Qt 5.14.2 MinGW 7.3.0 32-bit
                • Qt 5.15.2 MSVC 2019 64-bit

                Might be Windows-specific.

                kshegunovK Offline
                kshegunovK Offline
                kshegunov
                Moderators
                wrote on last edited by
                #7

                @JKSH said in QApplication in std::thread:

                Ah, right... I thought the Debug build would suffice. Don't have a dev build right now.

                Not once in a universe lifetime.

                @JKSH said in QApplication in std::thread:

                Might be Windows-specific.

                Possibly. Unfortunately I don't have windows on hand (or rather I'm too lazy now to boot into it). Maybe, I'll check it later.

                Read and abide by the Qt Code of Conduct

                JKSHJ 1 Reply Last reply
                0
                • kshegunovK kshegunov

                  @J-Hilk said in QApplication in std::thread:

                  @JKSH this actually crashes for me on btn.show()

                  That's expected. MacOS does not support plugging into the event loop from a thread different from main(). Should work on linux and windows, though.

                  J.HilkJ Offline
                  J.HilkJ Offline
                  J.Hilk
                  Moderators
                  wrote on last edited by
                  #8

                  @kshegunov Apple does a lot of funky stuff, in that regard, let me fire up my vm


                  Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


                  Q: What's that?
                  A: It's blue light.
                  Q: What does it do?
                  A: It turns blue.

                  1 Reply Last reply
                  2
                  • kshegunovK kshegunov

                    @JKSH said in QApplication in std::thread:

                    Ah, right... I thought the Debug build would suffice. Don't have a dev build right now.

                    Not once in a universe lifetime.

                    @JKSH said in QApplication in std::thread:

                    Might be Windows-specific.

                    Possibly. Unfortunately I don't have windows on hand (or rather I'm too lazy now to boot into it). Maybe, I'll check it later.

                    JKSHJ Offline
                    JKSHJ Offline
                    JKSH
                    Moderators
                    wrote on last edited by JKSH
                    #9

                    @kshegunov said in QApplication in std::thread:

                    Not once in a universe lifetime.

                    Duly noted :-D

                    But before we get too sidetracked: @Suthiro's main issue isn't the message about timers. Rather, it's the crash which I believe is caused by delete m_qPlotsControl; (see https://stackoverflow.com/questions/67257329/weird-qpushbutton-bug ).

                    I believe it is fixable with m_qPlotsControl->deleteLater();... but that needs to be done before QApplication::exec() returns, because QDeferredDeleteEvent won't be processed without an event loop.

                    Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

                    J.HilkJ kshegunovK 2 Replies Last reply
                    0
                    • JKSHJ JKSH

                      @kshegunov said in QApplication in std::thread:

                      Not once in a universe lifetime.

                      Duly noted :-D

                      But before we get too sidetracked: @Suthiro's main issue isn't the message about timers. Rather, it's the crash which I believe is caused by delete m_qPlotsControl; (see https://stackoverflow.com/questions/67257329/weird-qpushbutton-bug ).

                      I believe it is fixable with m_qPlotsControl->deleteLater();... but that needs to be done before QApplication::exec() returns, because QDeferredDeleteEvent won't be processed without an event loop.

                      J.HilkJ Offline
                      J.HilkJ Offline
                      J.Hilk
                      Moderators
                      wrote on last edited by
                      #10

                      @JKSH Ok I can reproduce it as well, (on the VM) Qt 15.3 & MSVC2019


                      Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


                      Q: What's that?
                      A: It's blue light.
                      Q: What does it do?
                      A: It turns blue.

                      1 Reply Last reply
                      1
                      • JKSHJ JKSH

                        @kshegunov said in QApplication in std::thread:

                        Not once in a universe lifetime.

                        Duly noted :-D

                        But before we get too sidetracked: @Suthiro's main issue isn't the message about timers. Rather, it's the crash which I believe is caused by delete m_qPlotsControl; (see https://stackoverflow.com/questions/67257329/weird-qpushbutton-bug ).

                        I believe it is fixable with m_qPlotsControl->deleteLater();... but that needs to be done before QApplication::exec() returns, because QDeferredDeleteEvent won't be processed without an event loop.

                        kshegunovK Offline
                        kshegunovK Offline
                        kshegunov
                        Moderators
                        wrote on last edited by
                        #11

                        @JKSH said in QApplication in std::thread:

                        I believe it is fixable with m_qPlotsControl->deleteLater();... but that needs to be done before QApplication::exec() returns, because QDeferredDeleteEvent won't be processed without an event loop.

                        I still don't understand this. For what reason should that be the case, and why would this generate a crash? I'm pretty sure deferred deletes are processed after the event loop has exited (see for example the QThread::finished -> QObject::deleteLater), but even if that weren't the case the QPushButton's destructor is going to be run before the thread actually finishes and before the application object's destructor's run (there's no difference between main() and any other function from c++'s point of view).

                        Read and abide by the Qt Code of Conduct

                        JKSHJ 1 Reply Last reply
                        0
                        • JKSHJ JKSH

                          [Forked from https://forum.qt.io/topic/126128/qapplication-in-std-thread -- Sorry, I messed up the order of posts when I did the fork; this top post should be further down]

                          @kshegunov said in QApplication in std::thread:

                          why would this generate a crash?

                          Since the widget creates a timer in the background, then it's probably receiving background events/signals. delete could cause the event/signal handler to act on a dangling pointer -- that's how it could generate a crash. And that's why deleteLater() can fix the crash. (Alternatively, we could change from a heap-allocated widget to a stack-allocated widget)

                          I'm pretty sure deferred deletes are processed after the event loop has exited (see for example the QThread::finished -> QObject::deleteLater)

                          The code below prints "Bye" but not "Widget destroyed", proving that the Widget's destructor is not run:

                          // widget.h
                          #include <QWidget>
                          
                          class Widget : public QWidget
                          {
                              Q_OBJECT
                          public:
                              Widget(QWidget *parent = nullptr) : QWidget(parent) {}
                              ~Widget(){ qDebug("Widget destroyed"); }
                          };
                          
                          // main.cpp
                          #include "widget.h"
                          #include <QApplication>
                          #include <chrono>
                          #include <thread>
                          
                          using namespace std::chrono_literals;
                          
                          int main(int argc, char *argv[])
                          {
                              std::thread thr([&]
                              {
                                  QApplication a(argc, argv);
                                  auto w = new Widget;
                                  w->show();
                                  a.exec();
                          
                                  // delete w; // This WILL run the Widget's destructor
                          
                                  w->deleteLater(); // This WON'T run the Widget's destructor
                              });
                          
                              std::this_thread::sleep_for(5000ms);
                          
                              QMetaObject::invokeMethod(qApp, &QApplication::quit);
                              thr.join();
                          
                              std::this_thread::sleep_for(5000ms);
                              qDebug("Bye");
                          }
                          

                          Anyway, I was trying to say that @Suthiro can't simply replace delete m_qPlotsControl; with m_qPlotsControl->deleteLater(); in-place at https://stackoverflow.com/questions/67257329/weird-qpushbutton-bug . Some re-shuffling is required.

                          kshegunovK Offline
                          kshegunovK Offline
                          kshegunov
                          Moderators
                          wrote on last edited by kshegunov
                          #12

                          @JKSH said in QApplication in std::thread:

                          The code below prints "Bye" but not "Widget destroyed", proving that the Widget's destructor is not run:

                          I meant connecting to the aboutToQuit signal, but anyhow it's not that important.

                          Since the widget creates a timer in the background, then it's probably receiving background events/signals. delete could cause the event/signal handler to act on a dangling pointer -- that's how it could generate a crash.

                          I think this shouldn't happen, but can't investigate it currently.

                          Anyway, I was trying to say that @Suthiro can't simply replace delete m_qPlotsControl; with m_qPlotsControl->deleteLater(); in-place at https://stackoverflow.com/questions/67257329/weird-qpushbutton-bug . Some re-shuffling is required.

                          I suppose, but that timer message should go away, otherwise the code can break at any moment (this applies to your code too - the one you mentioned where you get the warning).

                          Read and abide by the Qt Code of Conduct

                          1 Reply Last reply
                          0
                          • Chris KawaC Offline
                            Chris KawaC Offline
                            Chris Kawa
                            Lifetime Qt Champion
                            wrote on last edited by Chris Kawa
                            #13

                            I reproduced this on Windows and the message about timers comes from a destructor of a static QPixmapCache object that happens on the main() thread. That's not something the user's code does. It's in Qt's internals.

                            Right, so remember the rule that no QObject should outlive the application object and this means no static QObjects? Apparently Qt itself doesn't respect that rule and also creates static objects that run code in the main thread no matter where the application object is created :/

                            I would consider this a Qt bug and expect it to crash all over the place.

                            EDIT: I missed that JKSH already mentioned this, but yeah, this seems to be the culprit.

                            kshegunovK 1 Reply Last reply
                            3
                            • Chris KawaC Chris Kawa

                              I reproduced this on Windows and the message about timers comes from a destructor of a static QPixmapCache object that happens on the main() thread. That's not something the user's code does. It's in Qt's internals.

                              Right, so remember the rule that no QObject should outlive the application object and this means no static QObjects? Apparently Qt itself doesn't respect that rule and also creates static objects that run code in the main thread no matter where the application object is created :/

                              I would consider this a Qt bug and expect it to crash all over the place.

                              EDIT: I missed that JKSH already mentioned this, but yeah, this seems to be the culprit.

                              kshegunovK Offline
                              kshegunovK Offline
                              kshegunov
                              Moderators
                              wrote on last edited by kshegunov
                              #14

                              @Chris-Kawa said in QApplication in std::thread:

                              I reproduced this on Windows and the message about timers comes from a destructor of a static QPixmapCache object that happens on the main() thread. That's not something the user's code does. It's in Qt's internals.

                              Hm, interesting. Do you have a woboq location?

                              Right, so remember the rule that no QObject should outlive the application object and this means no static QObjects?
                              Apparently Qt itself doesn't respect that rule and also creates static objects that run code in the main thread no matter where the application object is created :/

                              Yeah. Not living up to its own expectations it seems. :(

                              I would consider this a Qt bug and expect it to crash all over the place.

                              Me too, which is what I wrote somewhere upstairs - this should be fixed at the vendor side.

                              Read and abide by the Qt Code of Conduct

                              Chris KawaC 1 Reply Last reply
                              1
                              • kshegunovK kshegunov

                                @Chris-Kawa said in QApplication in std::thread:

                                I reproduced this on Windows and the message about timers comes from a destructor of a static QPixmapCache object that happens on the main() thread. That's not something the user's code does. It's in Qt's internals.

                                Hm, interesting. Do you have a woboq location?

                                Right, so remember the rule that no QObject should outlive the application object and this means no static QObjects?
                                Apparently Qt itself doesn't respect that rule and also creates static objects that run code in the main thread no matter where the application object is created :/

                                Yeah. Not living up to its own expectations it seems. :(

                                I would consider this a Qt bug and expect it to crash all over the place.

                                Me too, which is what I wrote somewhere upstairs - this should be fixed at the vendor side.

                                Chris KawaC Offline
                                Chris KawaC Offline
                                Chris Kawa
                                Lifetime Qt Champion
                                wrote on last edited by Chris Kawa
                                #15

                                @kshegunov said in QApplication in std::thread:

                                Hm, interesting. Do you have a woboq location?

                                Instance declaration is here:
                                https://code.woboq.org/qt5/qtbase/src/gui/image/qpixmapcache.cpp.html#pm_cache

                                And here's Windows with MSVC crash callstack on exit:

                                1   QPMCache::~QPMCache                                                                                   qpixmapcache.cpp 269
                                2   ``anonymous namespace'::Q_QGS_pm_cache::innerFunction'::`2'::Holder::~Holder                          Qt5Guid             
                                3   ``anonymous namespace'::Q_QGS_pm_cache::innerFunction'::`2'::`dynamic atexit destructor for 'holder'' Qt5Guid             
                                4   initterm_e                                                                                            ucrtbased           
                                5   initterm_e                                                                                            ucrtbased           
                                6   initterm_e                                                                                            ucrtbased           
                                7   execute_onexit_table                                                                                  ucrtbased           
                                8   __scrt_dllmain_uninitialize_c                                                                         utility.cpp      399
                                9   dllmain_crt_process_detach                                                                            dll_dllmain.cpp  182
                                10  dllmain_crt_dispatch                                                                                  dll_dllmain.cpp  220
                                11  dllmain_dispatch                                                                                      dll_dllmain.cpp  293
                                12  _DllMainCRTStartup                                                                                    dll_dllmain.cpp  335
                                13  RtlActivateActivationContextUnsafeFast                                                                ntdll               
                                14  LdrShutdownProcess                                                                                    ntdll               
                                15  RtlExitUserProcess                                                                                    ntdll               
                                16  FatalExit                                                                                             KERNEL32            
                                17  wassert                                                                                               ucrtbased           
                                18  wassert                                                                                               ucrtbased           
                                19  exit                                                                                                  ucrtbased           
                                20  __scrt_common_main_seh                                                                                exe_common.inl   297
                                

                                I used this simplified code:

                                int main(int argc, char *argv[])
                                {
                                    std::thread thr([](int argc, char *argv[])
                                    {
                                        QApplication a(argc, argv);
                                        QPushButton btn("Push");
                                        btn.show();
                                        a.exec();
                                    }, argc, argv);
                                
                                    thr.join();
                                }
                                
                                kshegunovK 1 Reply Last reply
                                2
                                • Chris KawaC Chris Kawa

                                  @kshegunov said in QApplication in std::thread:

                                  Hm, interesting. Do you have a woboq location?

                                  Instance declaration is here:
                                  https://code.woboq.org/qt5/qtbase/src/gui/image/qpixmapcache.cpp.html#pm_cache

                                  And here's Windows with MSVC crash callstack on exit:

                                  1   QPMCache::~QPMCache                                                                                   qpixmapcache.cpp 269
                                  2   ``anonymous namespace'::Q_QGS_pm_cache::innerFunction'::`2'::Holder::~Holder                          Qt5Guid             
                                  3   ``anonymous namespace'::Q_QGS_pm_cache::innerFunction'::`2'::`dynamic atexit destructor for 'holder'' Qt5Guid             
                                  4   initterm_e                                                                                            ucrtbased           
                                  5   initterm_e                                                                                            ucrtbased           
                                  6   initterm_e                                                                                            ucrtbased           
                                  7   execute_onexit_table                                                                                  ucrtbased           
                                  8   __scrt_dllmain_uninitialize_c                                                                         utility.cpp      399
                                  9   dllmain_crt_process_detach                                                                            dll_dllmain.cpp  182
                                  10  dllmain_crt_dispatch                                                                                  dll_dllmain.cpp  220
                                  11  dllmain_dispatch                                                                                      dll_dllmain.cpp  293
                                  12  _DllMainCRTStartup                                                                                    dll_dllmain.cpp  335
                                  13  RtlActivateActivationContextUnsafeFast                                                                ntdll               
                                  14  LdrShutdownProcess                                                                                    ntdll               
                                  15  RtlExitUserProcess                                                                                    ntdll               
                                  16  FatalExit                                                                                             KERNEL32            
                                  17  wassert                                                                                               ucrtbased           
                                  18  wassert                                                                                               ucrtbased           
                                  19  exit                                                                                                  ucrtbased           
                                  20  __scrt_common_main_seh                                                                                exe_common.inl   297
                                  

                                  I used this simplified code:

                                  int main(int argc, char *argv[])
                                  {
                                      std::thread thr([](int argc, char *argv[])
                                      {
                                          QApplication a(argc, argv);
                                          QPushButton btn("Push");
                                          btn.show();
                                          a.exec();
                                      }, argc, argv);
                                  
                                      thr.join();
                                  }
                                  
                                  kshegunovK Offline
                                  kshegunovK Offline
                                  kshegunov
                                  Moderators
                                  wrote on last edited by
                                  #16

                                  Yes, this is constructed appropriately, however the deallocation should've been tied to the QCoreApplication::aboutToQuit. I doubt anyone is going to bother fixing it though, I'm not sure if it's not going to be discarded with "this is unsupported" even ...

                                  Read and abide by the Qt Code of Conduct

                                  JKSHJ 1 Reply Last reply
                                  0
                                  • kshegunovK kshegunov

                                    Yes, this is constructed appropriately, however the deallocation should've been tied to the QCoreApplication::aboutToQuit. I doubt anyone is going to bother fixing it though, I'm not sure if it's not going to be discarded with "this is unsupported" even ...

                                    JKSHJ Offline
                                    JKSHJ Offline
                                    JKSH
                                    Moderators
                                    wrote on last edited by
                                    #17

                                    Good detective work, @Chris-Kawa!

                                    I encountered this a few years ago but had forgotten most of the details.

                                    @kshegunov said in Global static QPixmapCache in Qt internals:

                                    Yes, this is constructed appropriately, however the deallocation should've been tied to the QCoreApplication::aboutToQuit. I doubt anyone is going to bother fixing it though, I'm not sure if it's not going to be discarded with "this is unsupported" even ...

                                    Since a QPixmap requires a QGuiApplication, would a simple(?) and correct fix be to allocate the QPixmapCache in the QGuiApplication constructor, and deallocate it from the QGuiApplication destructor?

                                    Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

                                    kshegunovK 1 Reply Last reply
                                    0
                                    • JKSHJ JKSH

                                      Good detective work, @Chris-Kawa!

                                      I encountered this a few years ago but had forgotten most of the details.

                                      @kshegunov said in Global static QPixmapCache in Qt internals:

                                      Yes, this is constructed appropriately, however the deallocation should've been tied to the QCoreApplication::aboutToQuit. I doubt anyone is going to bother fixing it though, I'm not sure if it's not going to be discarded with "this is unsupported" even ...

                                      Since a QPixmap requires a QGuiApplication, would a simple(?) and correct fix be to allocate the QPixmapCache in the QGuiApplication constructor, and deallocate it from the QGuiApplication destructor?

                                      kshegunovK Offline
                                      kshegunovK Offline
                                      kshegunov
                                      Moderators
                                      wrote on last edited by kshegunov
                                      #18

                                      Possibly. Or it can be a pseudo-singleton (similarly to QCoreApplication) and be initialized on demand in the instance retrieving function (dropping the global static that it currently uses). You could poke Thiago, but as written, I wouldn't hold my breath.

                                      Read and abide by the Qt Code of Conduct

                                      jeremy_kJ 1 Reply Last reply
                                      0
                                      • Christian EhrlicherC Online
                                        Christian EhrlicherC Online
                                        Christian Ehrlicher
                                        Lifetime Qt Champion
                                        wrote on last edited by Christian Ehrlicher
                                        #19

                                        There are some reports about such an issue:
                                        https://bugreports.qt.io/browse/QTBUG-48709
                                        https://bugreports.qt.io/browse/QTBUG-21807

                                        And it does not crash here for me on Linux and Windows (MSVC, debug-build) with 5.15.x

                                        Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                                        Visit the Qt Academy at https://academy.qt.io/catalog

                                        kshegunovK 1 Reply Last reply
                                        0
                                        • Christian EhrlicherC Christian Ehrlicher

                                          There are some reports about such an issue:
                                          https://bugreports.qt.io/browse/QTBUG-48709
                                          https://bugreports.qt.io/browse/QTBUG-21807

                                          And it does not crash here for me on Linux and Windows (MSVC, debug-build) with 5.15.x

                                          kshegunovK Offline
                                          kshegunovK Offline
                                          kshegunov
                                          Moderators
                                          wrote on last edited by
                                          #20

                                          @Christian-Ehrlicher said in Global static QPixmapCache in Qt internals:

                                          And it does not crash here for me on Linux and Windows (MSVC, debug-build) with 5.15.x

                                          We are talking about the QTimers from another thread message. JKSH, split the threads. The other stuff (the supposed crash) contines to befuddle me.

                                          Read and abide by the Qt Code of Conduct

                                          1 Reply Last reply
                                          0

                                          • Login

                                          • Login or register to search.
                                          • First post
                                            Last post
                                          0
                                          • Categories
                                          • Recent
                                          • Tags
                                          • Popular
                                          • Users
                                          • Groups
                                          • Search
                                          • Get Qt Extensions
                                          • Unsolved