简体   繁体   中英

Qt5 App crashes on close (QWidget::show)

So I have been stuck at this problem for a while now. For some reason, my application always crashes on close and this is the error message I get:

The inferior stopped because it triggered an exception.

Stopped in thread 0 by: Exception at 0x50c15a08, code: 0xc0000005: read access violation at: 0x0, flags=0x0 (first chance)

The stack shows the following:

QWidget::show Line: 7030

And this is what my main.cpp currently looks like:

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

I have no clue why the crash is occurring.

A little background: This is a multi-threaded application (using both QThread and QtConcurrent). When the threads are NOT started, the application closes just fine. Hence I added the following check to ensure that the thread is being terminated properly but this is not helping:

    void MainWindow::closeEvent(QCloseEvent *event)
    {
            if (thread->isRunning()) {
                thread->terminate();
                while(!thread->isFinished()){
                }
                event->accept();
            }
    }

EDIT: How the new thread was created

QThread *myThread = new QThread(this);
        Worker *worker  = new Worker(this, user, p);
        worker->moveToThread(myThread);

        connect(myThread, SIGNAL(started()), worker, SLOT(doWork()));
        connect(worker, SIGNAL(workDone()), this, SLOT(deleteThread()));
        myThread->start();

...and this is how I am handling the deletion of the thread after the download completes:

void MainWindow::deleteThread(){
    worker->deleteLater();
    myThread->quit();
    while(!myThread->isFinished()){
    }
    myThread->deleteLater();
}

You should either listen for terminated signal from the thread or wait for the thread to terminate. Telling the thread to terminate doesn't block, so if you then immediately accept the close event you will get your exception.

This is described in more detail in the documentation for the terminate slot

Proper QThread stop code is:

myThread->quit();
myThread->wait();

Also you have used moveToThread(this);

You need to moveToThread back to parent thread first.

For example your code is:

moveToThread(this);
start();

You need to save currentThread() before moveToThread() like this:

QThread *savedThread=currentThread();

moveToThread(this);
start();

And before quit or terminate you need to restore it:

moveToThread(savedThread);

quit();
wait();

You can put it on destructor of course.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM