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

Program crashed after close the mainwindow



  • Environment:
    macOS 10.15.4
    Qt: 5.12.8
    Qt Creator: 4.11.2 (based on Qt 5.14.2 Clang 10.0.0)

    I got this output after I quit the program (Command + Q)

    02:47:10: The process was ended forcefully.
    02:47:10: xxx/build-surimage-tool-Desktop_Qt_5_12_8_clang_64bit-Debug/surimage-tool.app/Contents/MacOS/surimage-tool crashed.
    

    Here is my main.cpp

    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
        MainWindow w;
        w.show();
        return a.exec();
    }
    

    I find this line has to do with the crash:

    /* mainwindow.cpp */
    MainWindow::~MainWindow() {
        // the line causing the crash
        // the crash disappears as soon as I comment the following line
        delete ui; 
    }
    

    where ui is defined as

    /* mainwindow.h */
    private:
        Ui::MainWindow *ui;
    

    and here is my ui header (automatically generated by ui designer)

    /********************************************************************************
    ** Form generated from reading UI file 'mainwindow.ui'
    **
    ** Created by: Qt User Interface Compiler version 5.12.8
    **
    ** WARNING! All changes made in this file will be lost when recompiling UI file!
    ********************************************************************************/
    
    #ifndef UI_MAINWINDOW_H
    #define UI_MAINWINDOW_H
    
    #include <QtCore/QVariant>
    #include <QtWidgets/QAction>
    #include <QtWidgets/QApplication>
    #include <QtWidgets/QGridLayout>
    #include <QtWidgets/QLabel>
    #include <QtWidgets/QMainWindow>
    #include <QtWidgets/QMenu>
    #include <QtWidgets/QMenuBar>
    #include <QtWidgets/QStatusBar>
    #include <QtWidgets/QToolBar>
    #include <QtWidgets/QWidget>
    
    QT_BEGIN_NAMESPACE
    
    class Ui_MainWindow
    {
    public:
        QAction *actionCapture;
        QAction *actionRecord;
        QAction *action_4;
        QAction *action_5;
        QAction *actionCalibrate;
        QAction *actionStartCamera;
        QAction *actionStopCamera;
        QWidget *centralwidget;
        QGridLayout *gridLayout;
        QGridLayout *gridLayout_2;
        QLabel *labelDisplay_1;
        QLabel *labelDisplay_2;
        QLabel *labelDisplay_3;
        QMenuBar *menubar;
        QMenu *menuFile;
        QMenu *menuDevices;
        QStatusBar *statusbar;
        QToolBar *toolBar;
    
        void setupUi(QMainWindow *MainWindow)
        {
            if (MainWindow->objectName().isEmpty())
                MainWindow->setObjectName(QString::fromUtf8("MainWindow"));
            MainWindow->resize(800, 600);
            actionCapture = new QAction(MainWindow);
            actionCapture->setObjectName(QString::fromUtf8("actionCapture"));
            actionRecord = new QAction(MainWindow);
            actionRecord->setObjectName(QString::fromUtf8("actionRecord"));
            action_4 = new QAction(MainWindow);
            action_4->setObjectName(QString::fromUtf8("action_4"));
            action_5 = new QAction(MainWindow);
            action_5->setObjectName(QString::fromUtf8("action_5"));
            actionCalibrate = new QAction(MainWindow);
            actionCalibrate->setObjectName(QString::fromUtf8("actionCalibrate"));
            actionStartCamera = new QAction(MainWindow);
            actionStartCamera->setObjectName(QString::fromUtf8("actionStartCamera"));
            actionStopCamera = new QAction(MainWindow);
            actionStopCamera->setObjectName(QString::fromUtf8("actionStopCamera"));
            centralwidget = new QWidget(MainWindow);
            centralwidget->setObjectName(QString::fromUtf8("centralwidget"));
            gridLayout = new QGridLayout(centralwidget);
            gridLayout->setObjectName(QString::fromUtf8("gridLayout"));
            gridLayout_2 = new QGridLayout();
            gridLayout_2->setObjectName(QString::fromUtf8("gridLayout_2"));
            labelDisplay_1 = new QLabel(centralwidget);
            labelDisplay_1->setObjectName(QString::fromUtf8("labelDisplay_1"));
            QSizePolicy sizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
            sizePolicy.setHorizontalStretch(0);
            sizePolicy.setVerticalStretch(0);
            sizePolicy.setHeightForWidth(labelDisplay_1->sizePolicy().hasHeightForWidth());
            labelDisplay_1->setSizePolicy(sizePolicy);
    
            gridLayout_2->addWidget(labelDisplay_1, 0, 0, 1, 1);
    
            labelDisplay_2 = new QLabel(centralwidget);
            labelDisplay_2->setObjectName(QString::fromUtf8("labelDisplay_2"));
            sizePolicy.setHeightForWidth(labelDisplay_2->sizePolicy().hasHeightForWidth());
            labelDisplay_2->setSizePolicy(sizePolicy);
    
            gridLayout_2->addWidget(labelDisplay_2, 0, 1, 1, 1);
    
            labelDisplay_3 = new QLabel(centralwidget);
            labelDisplay_3->setObjectName(QString::fromUtf8("labelDisplay_3"));
    
            gridLayout_2->addWidget(labelDisplay_3, 1, 0, 1, 1);
    
    
            gridLayout->addLayout(gridLayout_2, 0, 0, 1, 1);
    
            MainWindow->setCentralWidget(centralwidget);
            menubar = new QMenuBar(MainWindow);
            menubar->setObjectName(QString::fromUtf8("menubar"));
            menubar->setGeometry(QRect(0, 0, 800, 22));
            menuFile = new QMenu(menubar);
            menuFile->setObjectName(QString::fromUtf8("menuFile"));
            menuDevices = new QMenu(menubar);
            menuDevices->setObjectName(QString::fromUtf8("menuDevices"));
            MainWindow->setMenuBar(menubar);
            statusbar = new QStatusBar(MainWindow);
            statusbar->setObjectName(QString::fromUtf8("statusbar"));
            MainWindow->setStatusBar(statusbar);
            toolBar = new QToolBar(MainWindow);
            toolBar->setObjectName(QString::fromUtf8("toolBar"));
            MainWindow->addToolBar(Qt::TopToolBarArea, toolBar);
    
            menubar->addAction(menuFile->menuAction());
            menubar->addAction(menuDevices->menuAction());
            menuFile->addAction(actionStartCamera);
            menuFile->addAction(actionStopCamera);
            menuFile->addAction(actionCapture);
            menuFile->addAction(actionRecord);
            menuFile->addSeparator();
            menuFile->addAction(action_4);
            menuFile->addAction(action_5);
            menuFile->addSeparator();
            menuFile->addAction(actionCalibrate);
            menuFile->addSeparator();
            toolBar->addAction(actionCapture);
            toolBar->addAction(actionRecord);
            toolBar->addAction(actionCalibrate);
    
            retranslateUi(MainWindow);
    
            QMetaObject::connectSlotsByName(MainWindow);
        } // setupUi
    
        void retranslateUi(QMainWindow *MainWindow)
        {
            MainWindow->setWindowTitle(QApplication::translate("MainWindow", "Surimage Tool", nullptr));
            actionCapture->setText(QApplication::translate("MainWindow", "\346\213\215\347\205\247", nullptr));
            actionRecord->setText(QApplication::translate("MainWindow", "\345\275\225\345\203\217", nullptr));
            action_4->setText(QApplication::translate("MainWindow", "\345\210\266\344\275\234\345\233\272\344\273\266", nullptr));
            action_5->setText(QApplication::translate("MainWindow", "\346\233\264\346\226\260\345\233\272\344\273\266", nullptr));
            actionCalibrate->setText(QApplication::translate("MainWindow", "\346\240\207\345\256\232", nullptr));
            actionStartCamera->setText(QApplication::translate("MainWindow", "\345\220\257\345\212\250", nullptr));
            actionStopCamera->setText(QApplication::translate("MainWindow", "\345\201\234\346\255\242", nullptr));
            labelDisplay_1->setText(QApplication::translate("MainWindow", "TextLabel", nullptr));
            labelDisplay_2->setText(QApplication::translate("MainWindow", "TextLabel", nullptr));
            labelDisplay_3->setText(QApplication::translate("MainWindow", "TextLabel", nullptr));
            menuFile->setTitle(QApplication::translate("MainWindow", "\346\226\207\344\273\266", nullptr));
            menuDevices->setTitle(QApplication::translate("MainWindow", "\350\256\276\345\244\207", nullptr));
            toolBar->setWindowTitle(QApplication::translate("MainWindow", "toolBar", nullptr));
        } // retranslateUi
    
    };
    
    namespace Ui {
        class MainWindow: public Ui_MainWindow {};
    } // namespace Ui
    
    QT_END_NAMESPACE
    
    #endif // UI_MAINWINDOW_H
    

    Since MainWindow w is the parent of all the components of the ui, I think it's definitely okay leave the cleaning work to the MainWindow w since w itself is created on the stack. But according to Qt it is also fine to delete the ui manually, I'm very confused why delete ui would cause the program crash on exiting?

    Surely I have code in some other files, but I don't think they are related to the problem.

    In the Qt Example: Camera, I find that it doesn't delete ui, so when I add the delete ui for it's mainwindow, the crash occurs. Is it abnormal?


  • Lifetime Qt Champion

    Hi and welcome to devnet,

    Can you show your MainWindow header as well as the constructor code ?



  • @SGaist Yes (sorry I have to wait 10min before the forum allows me to post again)

    /* mainwindow.h */
    #ifndef MAINWINDOW_H
    #define MAINWINDOW_H
    
    #include <QMainWindow>
    #include <QCamera>
    #include <QCameraImageCapture>
    #include <QMediaRecorder>
    #include <QScopedPointer>
    #include <QCloseEvent>
    
    #include "survideosurface.h"
    
    QT_BEGIN_NAMESPACE
    namespace Ui { class MainWindow; }
    QT_END_NAMESPACE
    
    class MainWindow : public QMainWindow
    {
        Q_OBJECT
    
    public:
        MainWindow(QWidget *parent = nullptr);
        ~MainWindow();
    
    private slots:
        void setCamera(const QCameraInfo&);
        void updateCameraState(QCamera::State);
        void updateCameraDevice(QAction*);
        void displayCameraError();
        void rcvFrame(QVideoFrame& m_currentFrame);
        // void updateCaptureMode();
    
    
    
    private:
        Ui::MainWindow *ui;
    
        QScopedPointer<QCamera> m_camera;
        SurVideoSurface* m_video_surface;// camera==>video_surface
    };
    #endif // MAINWINDOW_H
    

    and

    /* mainwindow.cpp */
    Q_DECLARE_METATYPE(QCameraInfo)
    
    MainWindow::MainWindow(QWidget *parent)
        : QMainWindow(parent), ui(new Ui::MainWindow) {
      ui->setupUi(this);
      m_video_surface = new SurVideoSurface(this);
    
      // Camera devices:
      QActionGroup *videoDevicesGroup = new QActionGroup(this);
      videoDevicesGroup->setExclusive(true);
      const QList<QCameraInfo> availableCameras = QCameraInfo::availableCameras();
      for (const QCameraInfo &cameraInfo : availableCameras) {
        QAction *videoDeviceAction =
            new QAction(cameraInfo.description(), videoDevicesGroup);
        videoDeviceAction->setCheckable(true);
        qDebug() << cameraInfo.description();
        videoDeviceAction->setData(
            QVariant::fromValue(cameraInfo)); // TODO: confused
        if (cameraInfo == QCameraInfo::defaultCamera())
          videoDeviceAction->setChecked(true);
    
        ui->menuDevices->addAction(videoDeviceAction);
      }
    
      connect(videoDevicesGroup, &QActionGroup::triggered, this,
              &MainWindow::updateCameraDevice);
      //  connect(ui->captureWidget, &QTabWidget::currentChanged, this,
      //          &Camera::updateCaptureMode);
    
      setCamera(QCameraInfo::defaultCamera());
    }
    

  • Lifetime Qt Champion

    Do you have the stack trace of the crash ?
    I am suspecting a double delete.



  • @SGaist Double delete seems likely to me, too.
    Unfortunately I don't know how to look at the stack trace yet, I'll learn the debugger first and then report back.



  • @SGaist Now I have another discover, because I'm using the QCamera, I add a line before deleting the ui, then the crash goes away:

    MainWindow::~MainWindow() {
        m_camera->stop();  // this is the new line
        delete ui;
    }
    

    I cannot dig into the stack trace of the crash because in debug mode, there's an error getting the MacBook Facetime camera on (that is another problem which I'm exploring), so the crash never happens in debug mode:

    CMIO_DAL_PlugIn.cpp:269:StreamCopyBufferQueue Error: 1852797029, got an error from the plug-in routine
    

Log in to reply