I have a console-based QCoreApplication
which has timers and does socket communication and also uses locked mutex.
When I close the application manually
Turns out that closing command line application (checked on Win7 & VS2010) by pressing 'close' (red x button on title bar) passes the STATUS_CONTROL_C_EXIT
signal to the application. All threads are aborted with this code.
The thread 'Main Thread' (0x980) has exited with code -1073741510 (0xc000013a).
The thread 'QThread' (0x2388) has exited with code -1073741510 (0xc000013a).
That means that there is no way to intercept this with the QCoreApplication::aboutToQuit()
signal.
Take a look at winnt.h
or ntstatus.h
. That is the value assigned to the
manifest constant STATUS_CONTROL_C_EXIT
. The runtime is just
choosing to end your program with the code to note the user's cancel
operation.
Cleanup should be handled by destructors and child-parent relationship.
Make your master object (the one in the main) a child of QApplication so it is destructed with all its childs before QApplication is.
Are you sure you killed all your threads? If it is a thread with an eventloop be sure to call QThread::quit()
to exit the eventloop before you call QThread::wait()
You can also use the void QApplication::qAddPostRoutine ( QtCleanUpFunction ptr )
to do some special cleanup.
For debugging those messages you can use QtMsgHandler qInstallMsgHandler ( QtMsgHandler h )
and write your own message handler to capture those warnings. If you can simulate the problem you can set a breakpoint on the message and see on the stack where the message is coming from.
void debugMessageHandler( QtMsgType type, const char *msg ){
if(QString(msg).contains( "The message you can see in the console" )){
int breakPointOnThisLine(0);
}
switch ( type ) {
case QtDebugMsg:
fprintf( stderr, "Debug: %s\n", msg );
break;
case QtWarningMsg:
fprintf( stderr, "Warning: %s\n", msg );
break;
case QtFatalMsg:
fprintf( stderr, "Fatal: %s\n", msg );
abort();
}
}
In order to clean up with destructor and child-parent relation ship you can catch the console close signal and call QCoreApplication::exit()
to the application instance.
#include <csignal>
#include <QtCore/QCoreApplication>
using namespace std;
struct CleanExit{
CleanExit() {
signal(SIGINT, &CleanExit::exitQt);
signal(SIGTERM, &CleanExit::exitQt);
signal(SIGBREAK, &CleanExit::exitQt) ;
}
static void exitQt(int sig) {
QCoreApplication::exit(0);
}
};
int main(int argc, char *argv[])
{
CleanExit cleanExit;
QCoreApplication a(argc, argv);
return a.exec();
}
you can connect to QCoreApplication::aboutToQuit signal and do the necessary clean up there.