PDA

View Full Version : Qt application output says crashed



rawfool
3rd August 2015, 16:54
I have written a small console application that prints something on QTimer timeout. I have a counter, which emits a signal to stop the QTimer when it reaches a predetermined value. Everything looks fine, except the application output says crashed when I close the console.


// main.cpp
#include <QCoreApplication>
#include <QDebug>
#include "worker.h"
#include <QThread>
#include <QTimer>
#include <QPointer>

int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);

QTimer timer;
Worker * worker = new Worker;
// I tried QPointer<Worker> worker = new Worker; also but still gives the same application output

QCoreApplication::connect(&timer, SIGNAL(timeout()), worker, SLOT(process()));
QCoreApplication::connect(worker, SIGNAL(stopThread()), &timer, SLOT(stop()));
QCoreApplication::connect(worker, SIGNAL(stopThread()), worker, SLOT(deleteLater()));
timer.start(1000);

return a.exec();
}


//worker.h
#ifndef WORKER_H
#define WORKER_H

#include <QObject>

class Worker : public QObject
{
Q_OBJECT

int nCounter;
public:
explicit Worker(QObject *parent = 0);
~Worker();

signals:
void stopThread(void);
public slots:
void process(void);
};

#endif // WORKER_H


// worker.cpp
#include "worker.h"
#include <QDebug>
#include <QTime>
#include <QThread>

Worker::Worker(QObject *parent) : QObject(parent),
nCounter(0)
{}

Worker::~Worker()
{

}

void Worker::process(void)
{
nCounter++;
qDebug() << QTime::currentTime().toString("hh:mm:ss");
if (nCounter == 10)
{
qDebug() << "-x-x-x- Count Reached 10 -x-x-x-";
emit stopThread();
}
}

Kindly help me identify the why the message says the application crashes.

Starting /home/rahul/Documents/build-qonsole-Desktop_Qt_5_4_1_GCC_32bit-Debug/qonsole...
/home/rahul/Documents/build-qonsole-Desktop_Qt_5_4_1_GCC_32bit-Debug/qonsole crashed

anda_skoa
3rd August 2015, 17:25
You'll have to have a look at the stack trace of the crash.

Cheers,
_

yeye_olive
3rd August 2015, 17:33
Does the output show "-x-x-x- Count Reached 10 -x-x-x-" if you wait long enough?

There is nothing wrong with your application, except that:

there is a race condition between slots: worker->stopThread() is connected to both timer.stop() and worker->deleteLater(); worker could be deleted first, thus preventing timer.stop() from being run. Since the order in which the slots are run is unspecified in general, this may or may not happen in practice.
the application never terminates. Nothing causes the event loop to exit.

I cannot see why stopping the timer would be necessary. However, you should probably exit the event loop cleanly. Here is a proposal that exits the program after the worker has finished its work:

int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QTimer timer;
Worker worker; // No need to allocate this on the heap; the stack is fine, and the object will be automatically destroyed at the end of the function (just like a and timer)
QCoreApplication::connect(&timer, SIGNAL(timeout()), &worker, SLOT(process()));
QCoreApplication::connect(&worker, SIGNAL(stopThread()), &a, SLOT(quit()));
timer.start(1000);
return a.exec();
}

rawfool
3rd August 2015, 18:24
Does the output show "-x-x-x- Count Reached 10 -x-x-x-" if you wait long enough?Yes! The output prints the same.


the application never terminates. Nothing causes the event loop to exit.I'm closing the console window. So, doesn't that mean that a signal to terminate the application is emitted implicitly ?

Your solution worked cleanly though, thank you. :)

anda_skoa
3rd August 2015, 18:34
there is a race condition between slots: worker->stopThread() is connected to both timer.stop() and worker->deleteLater(); worker could be deleted first, thus preventing timer.stop() from being run. Since the order in which the slots are run is unspecified in general, this may or may not happen in practice.

Actually, as of Qt5 the order of slot invocations it now specified as being in order of connects.
This is de-facto also the case for Qt4.

Cheers,
_

yeye_olive
3rd August 2015, 23:05
I'm closing the console window. So, doesn't that mean that a signal to terminate the application is emitted implicitly ?
No. It is possible to make this happen, but Qt offers no built-in platform-agnostic way to do it. There are several threads discussing solutions on this forum. That being said, the default behavior (the application is killed without having the opportunity to run clean-up code) is often acceptable.


Actually, as of Qt5 the order of slot invocations it now specified as being in order of connects. This is de-facto also the case for Qt4.
Thanks, I must have missed that.