[SOLVED] Unexplained Segmentation Fault with QDialog::show() and QDialog::exec()



  • In a Qt 4.7.1 project in Ubuntu 10.10 x64, I have subclassed QDialog and am calling it in the following way:

    @
    //Create a dialog window to get the requested difficulty
    this->generateNewDialog = new GenerateNewDialog(this);
    connect(this->generateNewDialog, SIGNAL(difficultySelected(int)), this, SLOT(generationDifficultySelected(int)));

    this->generateNewDialog->exec();
    

    @

    Without fail, this always produces a segmentation fault and crashes my program on the exec() call (not before). Looking at the call stack, the fault occurs at:

    QWidgetPrivate::create_sys
    QWidget::create
    QWidget::setVisible
    QDialog::setVisible
    show
    QDialog::exec

    Does anyone see a reason for the behavior? I don't.

    header file
    @
    #ifndef GENERATENEWDIALOG_H
    #define GENERATENEWDIALOG_H

    #include <QDialog>
    #include <QSpinBox>
    #include <QDialogButtonBox>
    #include <QVBoxLayout>
    #include <QHBoxLayout>
    #include <QLabel>
    #include <QSpinBox>
    #include <QPushButton>
    #include <QDebug>
    class GenerateNewDialog : public QDialog
    {
    Q_OBJECT
    private:
    void setupInterface();
    void setupActions();
    QVBoxLayout * m_mainLayout;
    QHBoxLayout * m_firstSetting;
    QLabel * m_label1;
    QSpinBox * m_difficultyPicker;
    QPushButton * m_cancel, * m_start;
    QDialogButtonBox *buttonBox;
    int m_difficulty;
    public:
    explicit GenerateNewDialog(QWidget *parent = 0);
    virtual ~GenerateNewDialog();
    signals:
    void difficultySelected(int difficulty);
    private slots:
    void accept();
    void reject();
    public slots:

    };

    #endif // GENERATENEWDIALOG_H
    @

    class file
    @
    #include "generatenewdialog.h"

    GenerateNewDialog::GenerateNewDialog(QWidget *parent) :
    QDialog(parent, Qt::Sheet)
    {
    setupInterface();
    setupActions();
    }
    //----------------------------------------------------------------------------
    // Constructor & destructor.

    GenerateNewDialog::~GenerateNewDialog(void) {
    // Is automatically deleted, because it's a child of of the main widget.
    //delete m_mainLayout;
    delete m_firstSetting;
    delete m_label1;
    delete m_difficultyPicker;
    delete m_cancel;
    delete m_start;
    }

    //----------------------------------------------------------------------------
    // Private slots.

    /**

    • The dialog was accepted. Emit the newGame() signal.
      */
      void GenerateNewDialog::accept(void) {
      m_difficulty = m_difficultyPicker->value();

      close();

      emit difficultySelected(m_difficulty);
      }

    //----------------------------------------------------------------------------
    // Private methods.

    /**

    • Create the UI.
      */
      void GenerateNewDialog::setupInterface(void) {
      setContextMenuPolicy(Qt::NoContextMenu);
      setModal(true);

      // Configure layouts.
      m_mainLayout = new QVBoxLayout(this);
      m_firstSetting = new QHBoxLayout();
      m_mainLayout->addLayout(m_firstSetting);

      // Set up the buttons.
      this->buttonBox = new QDialogButtonBox(this);
      this->buttonBox->setOrientation(Qt::Horizontal);
      m_cancel = new QPushButton(tr("&Cancel"));
      this->buttonBox->addButton(m_cancel, QDialogButtonBox::RejectRole);
      m_start = new QPushButton(tr("&Start!"));
      m_start->setDefault(true);
      this->buttonBox->addButton(m_start, QDialogButtonBox::AcceptRole);
      m_mainLayout->addWidget(buttonBox);

      // Difficulty label.
      m_label1 = new QLabel(this);
      m_label1->setText(tr("Difficulty level"));
      m_firstSetting->addWidget(m_label1);
      m_firstSetting->setAlignment(m_label1, Qt::AlignLeft);

      // Difficulty spinbox.
      m_difficultyPicker = new QSpinBox(this);
      m_difficultyPicker->setMinimum(1);
      m_difficultyPicker->setMaximum(5);
      m_difficultyPicker->setSingleStep(1);
      m_difficultyPicker->setValue(1);
      m_firstSetting->addWidget(m_difficultyPicker);
      m_firstSetting->setAlignment(m_difficultyPicker, Qt::AlignRight);

      // Connect the signals from the buttonbox to the GenerateNewDialog.
      connect(buttonBox, SIGNAL(accepted()), this, SLOT(accept()));
      connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
      }
      void GenerateNewDialog::setupActions(){
      // Connect the signals from the buttonbox to the NewGameDialog.
      connect(this->buttonBox, SIGNAL(accepted()), this, SLOT(accept()));
      connect(this->buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
      }

    void GenerateNewDialog::reject(){
    qDebug() << "GenerateNewDialog received reject signal.";
    close();
    }
    @



  • I cannot reproduce any error when I put the class into a testproject.

    Can you create a short, complete, compilable and running program that demonstrates the error. Put everything into a ZIP (including the project file) and put it on dropbox or something else. We then can grab the sources and have a look.



  • Great... so I tried to create a program that consists of only a button, but the dialog window works in this case :(. In the program where I am observing the segmentation fault, I have a main window with 4 QDockWidgets and a QStatusBar. Could this have anything to do with it?

    I didn't modify the dialog window class at all, and I called it the same way, so I'm not sure why calling exec() would seg fault in one program but not another...



  • Here is the relevant part of my main window code... I'm registering a generateNew slot to receive signals triggered by a new action. Then in a dock widget, I have a button press registered to trigger the new action, causing me to enter my generateNew() slot, where then the seg fault is always occurring on the call to exec(). Could there be a problem with a button press in a dock widget triggering an action and causing a dialog window in the main widget?

    @
    #include "mainwindow.h"
    #include <QDesktopWidget>
    #include <QApplication>
    #include <QResizeEvent>
    #include "engine/engine.h"
    #include "storage/storage.h"
    #include "gui/actionmanager.h"

    MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent)
    {
    //Test something manually
    //test();

    //Create actions
    createActions();
    
    //Create window internals
    createMainSceneAndView();
    
    //Create dock windows
    createDockWindows();
    
    //Additional Settings for this Window
    configureWindow();
    
    restoreSettings();
    
    show();
    

    }
    void MainWindow::createActions(){

    ActionManager::generateNewAction = new QAction(this);
    connect(ActionManager::generateNewAction, SIGNAL(triggered()), this, SLOT(generateNew()));
    

    }
    void MainWindow::generateNew(){
    qDebug() << "MainWindow got generate new event.";

    //Create a dialog window to get the requested difficulty
    this->generateNewDialog = new GenerateNewDialog(this);
    connect(this->generateNewDialog, SIGNAL(difficultySelected(int)), this, SLOT(generationDifficultySelected(int)));
    
    this->generateNewDialog->exec&#40;&#41;;
    

    }
    @



  • [quote author="Volker" date="1298677672"]Can you create a short, complete, compilable and running program that demonstrates the error. Put everything into a ZIP (including the project file) and put it on dropbox or something else. We then can grab the sources and have a look.[/quote]

    What's so hard to understand about these sentences?



  • No need to be rude, nothing is hard about it. I just told you, I attempted to do so, and the same dialog window was called in the same way but worked with no problem. Therefore, it is only logical that there is something else wrong in my main code.

    Here is a link to the simple example I made where the code DOES work:
    http://dl.dropbox.com/u/7027137/dialog_example.zip

    I will post a link to my main project where the dialog does NOT work as soon as it finishes uploading to my public dropbox folder (I'm somewhere where the Internet connection is very poor).



  • Alright, I trimmed some fat and it's done uploading:

    http://dl.dropbox.com/u/7027137/git_code.zip

    Specifically, the "new" button in the GameTab class should trigger the new game action, which should spawn the dialog window (which instead is seg-faulting). If you can figure out why it seg faults here but not in my other simple example, I'd be quite grateful!



  • I'll have a look at it - stay tuned.



  • It runs on Mac OS X with Qt 4.7.1 without problems (once I fixed a compiler error in GUI::event(): m_mainWindow is not present there). Although it crashes on application shutdown, because you add one single instance of a widget multiple times (eg. QSpacerItem *gap in settingstab.cpp).

    I'll have a look at Linux once I have a recent Kubuntu box running.



  • Next serious error: The signatures of the following methods are wrong.

    @
    class GUI : public QApplication
    {
    public:
    static GUI* getInstance(int argc, char **argv){

    GUI(int argc, char ** argv);
    

    };
    @

    Please read the API docs on "QCoreApplication::QCoreApplication() ":http://doc.qt.nokia.com/4.7-snapshot/qcoreapplication.html#QCoreApplication and adhere to the warning there - it's not without reason! And of course change the method and constructor signatures accordingly. It could be that this is the reason for the application crash on Linux.

    Second: For what you want to do, a QApplication subclass is not necessary (look at event filters!). The code inside your constructor can easily be moved to the main() function.



  • Thank you very much for taking the time to look at it! I will use your feedback going forward and hopefully resolve the segmentation fault.



  • You got it, Volker. Passing an int instead of int & to the constructor was causing the crash.

    I have my own reasons for subclassing QApplication and keeping that code out of the main method. I actually am going to have 5 high-level components, of which the GUI is just one, the goal being to keep things modular and easily maintainable. Also, getInstance() doesn't have anything to do with QApplication::instance(). It is just simply meant to make the GUI class a singleton.

    Anyway, thanks again for your help. Problem solved :)



  • Glad to hear that it was that easy :-)


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.