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

SIGSEGV when closing GUI app / widget ownership error



  • Hi,
    I am facing some issue when closing my Qt app. A SIGSEGV signal is emitted and the Backtrace is pointing the line "delete window" in my application code. Here is the code:
    main_window.h

    #ifndef TU_ALIM_MAINWINDOW_H
    #define TU_ALIM_MAINWINDOW_H
    
    #include "ledbutton.h"
    #include "powerbutton.h"
    #include "model_dsssd.h"
    #include "model_pm.h"
    #include "automatonStateMachine.h"
    
    #include <QMainWindow>
    #include <QTableView>
    #include <QTimer>
    #include <memory>
    
    QT_BEGIN_NAMESPACE
    
    class QScxmlEvent;
    class QScxmlStateMachine;
    
    QT_END_NAMESPACE
    
    
    class TU_Alim_MainWindow : public QMainWindow
    {
        Q_OBJECT
    
    public:
        explicit TU_Alim_MainWindow(ModelDsssd *model_dsssd, ModelPM *model_pm, std::shared_ptr<QLabel> label_bat ,std::shared_ptr<automatonStateMachine> state_machine, QWidget *parent = nullptr);
        ~TU_Alim_MainWindow() override;
    
    signals:
        void statusChange(void);
    
    private:
        //
        // state machine
        //
        std::shared_ptr<automatonStateMachine> m_state_machine;
    
        //
        // buttons
        //
        ledButton *m_rec_btn;
        ledButton *m_stop_btn;
        PowerButton *m_pwr_btn;
    
        QSpacerItem *btn_spacer;
        QSpacerItem *btn_spacer2;
        //
        // models
        //
        ModelDsssd *m_model_dsssd;
        ModelPM    *m_model_pm;
        //
        // views
        //
        QTableView *m_tv_dsssd;
        QTableView *m_tv_pm;
    
        //
        // labels
        //
        QLabel *m_label_bat_info;
        std::shared_ptr<QLabel> m_label_bat;
        QLabel *m_label_SM;
    
        //
        // layout
        //
        QVBoxLayout *m_vlayout;
        QHBoxLayout *m_hlayout;
    
        //
        // Widgets
        //
        QWidget *w_btn;
        QWidget *window;
    };
    #endif // TU_ALIM_MAINWINDOW_H
    

    main_window.cpp

    #include "delegate_dsssd.h"
    #include "delegate_pm.h"
    #include "tu_alim_mainwindow.h"
    
    #include <QHeaderView>
    #include <QDebug>
    #include <memory>
    
    TU_Alim_MainWindow::TU_Alim_MainWindow(ModelDsssd *model_dsssd, ModelPM *model_pm, std::shared_ptr<QLabel> label_bat, std::shared_ptr<automatonStateMachine> state_machine, QWidget *parent)
        : QMainWindow(parent)
    {
        window = new QWidget(nullptr);
    
        //
        // State Machine
        //
        m_state_machine = state_machine;
    
        //
        // DSSSD Model/View
        //
        m_tv_dsssd = new QTableView(window);
        m_model_dsssd = model_dsssd;
    
    
        //
        // PM Model/View
        //
        m_tv_pm = new QTableView(window);
        m_model_pm = model_pm;
    
    
    
        //
        // labels batt
        //
        m_label_bat_info = new QLabel(window);
        m_label_bat = label_bat;
    
        //
        // Buttons(REC, POWER, STOP)
        //
        m_pwr_btn = new PowerButton(window);
        m_rec_btn = new ledButton(false, ledButton::ButtonType::REC, window);
        m_stop_btn = new ledButton(true, ledButton::STOP, window);
    
        //
        //  layouts & disposition
        //
        btn_spacer = new QSpacerItem(WIDTH_SPACE_BUTTON, HEIGHT_SPACE_BUTTON);
        btn_spacer2 = new QSpacerItem(30, HEIGHT_SPACE_BUTTON);
        m_hlayout = new QHBoxLayout(window);
        m_vlayout = new QVBoxLayout(window);
    
        w_btn = new QWidget(window);
        w_btn->setLayout(m_hlayout);
    
        m_vlayout->addWidget(m_tv_dsssd);
        m_vlayout->addWidget(m_tv_pm);
        m_vlayout->addWidget(w_btn);
        m_vlayout->setAlignment(m_tv_pm, Qt::AlignCenter);
    
    
        window->setLayout(m_vlayout);
        setCentralWidget(window);
    }
    
    TU_Alim_MainWindow::~TU_Alim_MainWindow()
    {
        delete window;  //here is where the bt points
    }
    

    main.cpp

    
    #include <QApplication>
    #include <QDebug>
    
    #include "tu_alim_mainwindow.h"
    #include "Constant.h"
    #include "automatonStateMachine.h"
    #include "core_alim.h"
    
    using namespace Constant;
    
    //
    // automaton
    //
    static std::shared_ptr<automatonStateMachine> sm;
    
    //
    // Main
    //
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
    
        sm = std::make_shared<automatonStateMachine>();
        sm->start();
    
        //
        // data
        //
        auto p_dsssd = std::make_shared<QVector<QVector<qint32>>>();
        auto p_pm = std::make_shared<QVector<QVector<qint32>>>();
        auto p_label_bat = std::make_shared<QLabel>();
    
        //
        // models
        //
        ModelPM    m_model_pm(p_pm);
        ModelDsssd m_model_dsssd(p_dsssd);
    
        TU_Alim_MainWindow w(&m_model_dsssd, &m_model_pm, p_label_bat, sm);
    
        QPalette palette;
        palette.setColor(QPalette::Window, TABLE_BACKGROUND_COLOR);
        w.setPalette(palette);
    
        w.show();
        int ret = a.exec();
    
        alim.Stop();
    
        return ret;
    }
    

    I suppose that is du to the destruction of some objects but for now i have no idea how to solve this.
    Any suggestion?


  • Qt Champions 2017

    I suspect these two lines. You are trying to set the layout multiple times.
    Also you are setting using the setLayout(....) as well.
    Please remove these & see how it goes.
    ```
    m_hlayout = new QHBoxLayout(window);
    m_vlayout = new QVBoxLayout(window);

    Also you are trying to pass the stack object from main to constructor.
    As a best practice you should avoid it.


  • @dheerendra, thank you for taking in your time to propose a solution for my issue.
    Since i use the setLayout function lower for m_hlayout & m_vlayout , i replace this by the following:

        m_hlayout = new QHBoxLayout(nullptr);
        m_vlayout = new QVBoxLayout(nullptr);
    

    But the problem still continues.


  • Lifetime Qt Champion

    Since you set window as centralWidget there is no need to delete it manually: https://doc.qt.io/qt-5/qmainwindow.html#setCentralWidget



  • Thank you @Christian-Ehrlicher . I remove the delete of the widget on the destructor. Now i have an empty destructor and the problem is still remaining. The backtrace points to the destructor:

    TU_Alim_MainWindow::~TU_Alim_MainWindow()
    

  • Lifetime Qt Champion

    Please post the complete backtrace.



  • here is the content of the backtrace:

    GNU gdb (Ubuntu 8.1-0ubuntu3.2) 8.1.0.20180409-git
    Copyright (C) 2018 Free Software Foundation, Inc.
    License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
    This is free software: you are free to change and redistribute it.
    There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
    and "show warranty" for details.
    This GDB was configured as "x86_64-linux-gnu".
    Type "show configuration" for configuration details.
    For bug reporting instructions, please see:
    <http://www.gnu.org/software/gdb/bugs/>.
    Find the GDB manual and other documentation resources online at:
    <http://www.gnu.org/software/gdb/documentation/>.
    For help, type "help".
    Type "apropos word" to search for commands related to "word"...
    Reading symbols from TU_Alim_UI...done.
    [New LWP 17916]
    [New LWP 17917]
    [New LWP 17918]
    [New LWP 17919]
    [New LWP 17920]
    [New LWP 17923]
    [New LWP 17924]
    [Thread debugging using libthread_db enabled]
    Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
    Core was generated by `./TU_Alim_UI'.
    Program terminated with signal SIGSEGV, Segmentation fault.
    #0  0x0000000000000031 in ?? ()
    [Current thread is 1 (Thread 0x7fe06ee7b440 (LWP 17916))]
    (gdb) bt
    #0  0x0000000000000031 in  ()
    #1  0x00007fe06e5b2bbf in QBoxLayoutItem::~QBoxLayoutItem() (this=<optimized out>, __in_chrg=<optimized out>) at kernel/qboxlayout.cpp:56
    #2  0x00007fe06e5b2bbf in QBoxLayoutPrivate::deleteAll() (this=0x55bd899de8f0) at kernel/qboxlayout.cpp:121
    #3  0x00007fe06e5b2bbf in QBoxLayout::~QBoxLayout() (this=0x55bd899de8c0, __in_chrg=<optimized out>) at kernel/qboxlayout.cpp:570
    #4  0x00007fe06e5b2c49 in QHBoxLayout::~QHBoxLayout() (this=0x55bd899de8c0, __in_chrg=<optimized out>) at kernel/qboxlayout.cpp:1276
    #5  0x00007fe06e5d60f8 in QWidget::~QWidget() (this=0x55bd89930e60, __in_chrg=<optimized out>) at kernel/qwidget.cpp:1594
    #6  0x00007fe06e5d6519 in QWidget::~QWidget() (this=0x55bd89930e60, __in_chrg=<optimized out>) at kernel/qwidget.cpp:1720
    #7  0x00007fe06c7756b3 in QObjectPrivate::deleteChildren() (this=this@entry=0x55bd897db4c0) at kernel/qobject.cpp:2016
    #8  0x00007fe06e5d62f8 in QWidget::~QWidget() (this=0x55bd898ab1c0, __in_chrg=<optimized out>) at kernel/qwidget.cpp:1696
    #9  0x00007fe06e5d6519 in QWidget::~QWidget() (this=0x55bd898ab1c0, __in_chrg=<optimized out>) at kernel/qwidget.cpp:1720
    #10 0x00007fe06c7756b3 in QObjectPrivate::deleteChildren() (this=this@entry=0x55bd898b2810) at kernel/qobject.cpp:2016
    #11 0x00007fe06e5d62f8 in QWidget::~QWidget() (this=0x7ffe9e91e3c0, __in_chrg=<optimized out>) at kernel/qwidget.cpp:1696
    #12 0x000055bd87f83da8 in TU_Alim_MainWindow::~TU_Alim_MainWindow() (this=0x7ffe9e91e3c0, __in_chrg=<optimized out>)
        at /home/sconte/projects/comptoncam/Comptoncam/Application/Equipments/Alim/TU/tu_alim_mainwindow.cpp:156
    #13 0x000055bd87f7f1c9 in main(int, char**) (argc=1, argv=0x7ffe9e91e598) at /home/sconte/projects/comptoncam/Comptoncam/Application/Equipments/Alim/TU/main.cpp:78
    

  • Lifetime Qt Champion

    @vladzouth said in SIGSEGV when closing GUI app / widget ownership error:

    auto p_label_bat = std::make_shared<QLabel>();

    I would guess this is the problem - this must not be a shared pointer since the ownership is passed to TU_Alim_MainWindow when it is added as a child.
    Using shared pointers + qobject trees don't work together and therefore should be avoided.



  • @Christian-Ehrlicher , Thank you for your help. I finally resolve the issue by removing the shared pointer for the label.