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

Qt5WinExtras Crash on QApplication Shutdown

    XMLWordPrintable

Details

    • Bug
    • Resolution: Cannot Reproduce
    • Not Evaluated
    • None
    • 5.12.6, 5.12.8
    • Extras: Win
    • None
    • I am using Qt 5.12.8 on Windows SDK 10.0.17763.0
    • Windows

    Description

      My application is crashing during exit and the stack trace indicates an issue with deleting the QWinExtra. Seems like a double delete is occurring. The QWindow has already been deleted when the QWinThumbnailToolBarPrivate::hasHandle() checks for the handle.

       

      Is there something special I need to do to properly destruct the QWinThumbnailToolBar?

      Crash Report:

       Exception thrown: read access violation.
       d was 0xFFFFFFFFFFFFFF7F.

       

      Stack Trace:

          Qt5Guid.dll!QWindow::handle() Line 1929 C++
          Qt5WinExtrasd.dll!QWinThumbnailToolBarPrivate::hasHandle() Line 460 C++
          Qt5WinExtrasd.dll!QWinThumbnailToolBarPrivate::handle() Line 465    C++
          Qt5WinExtrasd.dll!QWinThumbnailToolBarPrivate::nativeEventFilter(const QByteArray & __formal, void * message, long * result) Line 549   C++
          Qt5Cored.dll!QAbstractEventDispatcher::filterNativeEvent(const QByteArray & eventType, void * message, long * result) Line 484  C++
          [External Code] 
          Qt5Guid.dll!QWindowPrivate::destroy() Line 1914 C++
          Qt5Guid.dll!QWindow::destroy() Line 1864    C++
          Qt5Widgetsd.dll!QWidgetPrivate::deleteTLSysExtra() Line 1891    C++
          Qt5Widgetsd.dll!QWidget::destroy(bool destroyWindow, bool destroySubWindows) Line 12515 C++
          Qt5Widgetsd.dll!QApplication::~QApplication() Line 798  C++
      

       

      My Implementation:

      I have a simple subclass of QDialog called DDialog with the following implementation:

       

      Dialog.h

      #pragma once
      #include <QDialog>
      #include <QWinThumbnailToolBar>
      #include <QWinThumbnailToolButton>
      
      class DDialog : public QDialog
      { 
      Q_OBJECT
      
      public: 
         DDialog(QWidget *parent = Q_NULLPTR); virtual ~DDialog();
         void SetupWinThumbnailToolbar();
      protected slots: 
         void ToggleKeepDialogLockedOnTop();
      protected: 
         QWinThumbnailToolBar* m_pThumbnailToolbar; 
         QWinThumbnailToolButton* m_pLockOnTopToolButton;
      };
      

       

      Dialog.cpp

      #include "Dialog.h"
      
      DDialog::DDialog(QWidget* parent)
      : QDialog(parent), m_pThumbnailToolbar(nullptr), m_pLockOnTopToolButton(nullptr)
      {}
      
      void DDialog::ToggleKeepDialogLockedOnTop()
      {
          if (windowFlags() & Qt::WindowStaysOnTopHint)
          {
              setWindowFlags(windowFlags() & ~Qt::WindowStaysOnTopHint);
              m_pLockOnTopToolButton->setToolTip("Enable Window Lock");
              m_pLockOnTopToolButton->setIcon(QIcon(":/appbase/Resources/window_unlocked.png"));
          }
          else
          {
              setWindowFlags(windowFlags() | Qt::WindowStaysOnTopHint);
              m_pLockOnTopToolButton->setToolTip("Disable Window Lock");
              m_pLockOnTopToolButton->setIcon(QIcon(":/appbase/Resources/window_locked.png"));
          }
          // https://doc.qt.io/qt-5/qwidget.html#windowFlags-prop
          // Per Qt Documentation, setWindowFlags causes for the widget to be hidden
          // for this reason it needs to be shown again
          show(); 
      }
      
      DDialog::~DDialog()
      {
          close();
      }
      
      void DDialog::SetupWinThumbnailToolbar()
      {
          if (windowHandle() && !m_pThumbnailToolbar)
          {
              m_pThumbnailToolbar = new QWinThumbnailToolBar(this);
              m_pThumbnailToolbar->setWindow(windowHandle());
      
              m_pLockOnTopToolButton = new QWinThumbnailToolButton(m_pThumbnailToolbar);
              m_pLockOnTopToolButton->setToolTip("Enable Window Lock");
              m_pLockOnTopToolButton->setIcon(QIcon(":/appbase/Resources/window_unlocked.png"));
              m_pLockOnTopToolButton->setDismissOnClick(true);
              connect(m_pLockOnTopToolButton, &QWinThumbnailToolButton::clicked, this, &DDialog::ToggleKeepDialogLockedOnTop);
      
              m_pThumbnailToolbar->addButton(m_pLockOnTopToolButton);
          }
      }
      

       

      How I am calling it:

      int main(int argc, char *argv[])
      {
          QApplication a(argc, argv);
      
          QMainWindow* pMainWindow = new QMainWindow;
          QObject::connect(&a, &QApplication::aboutToQuit, pMainWindow, &QObject::deleteLater);
      
          DDialog* pDialog1 = new DDialog(pMainWindow);
          DDialog* pDialog2 = new DDialog(pMainWindow);
          
          pMainWindow->show();
      
          pDialog1->show();
          pDialog1->SetupWinThumbnailToolbar();
      
          pDialog2->show();
          pDialog2->SetupWinThumbnailToolbar();
      
          return a.exec();
      }
      

      Attachments

        Activity

          People

            kleint Friedemann Kleint
            rudyb Rudy Bermudez
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved: