PDA

View Full Version : Qt console application gives application error when shut down



ustulation
22nd August 2012, 07:36
{using Qt 4.7.0, Windows Xp, Visual Studio 2005}

hi, i've develope a Qt console project to implement a protocol which is up and running on the intended product for quite sometime now. But recently a problem has come up. The application is never meant to shutdown so there is nothing to quit it from inside the application. What it does is it implements a new thread for each client connection on the developed protocol and when the client disconnects, it ends the thread and continues polling for new connections, which is all fine. Now when the tester runs it in debug mode the console window pops up showing the logs of the ongoing activities. The problem is when this console window is manually closed it gives an error "the instruction at 0xwhatever referenced memory at 0xwhatever which could not be read. Click Ok to terminate". I've identified this problem and it comes because one of the shutdown functions is not called.

How do i call this custom shutdown function whenever the application is closed in such a way? (by the way, if one "ends process" in the task manager this problem does not pop up and that's why the release mode shutdowns are always fine as they don't pop up a console window and only way to do is is through task manager)

p.s: i have tried using QCoreApplication's aboutToQuit() signal to call a custom slot which calls the shutdown functions indicated above. This does not seem to work. I don't know if the signal is fired up in such application shutdown events.

StrikeByte
22nd August 2012, 08:42
I assume you use sockets, do you close them and then exit the program?

ChrisW67
22nd August 2012, 09:29
The use of Ctrl-C on Windows console windows results in a SIGINT signal, and termination of the event loop without returning. The console window close box might use SIGKILL or SIGTERM, not sure. You need to catch the SIGINT and handle it within the limitations of signal handlers:
http://doc.qt.nokia.com/4.6/unix-signals.html
I don't know how well this translates into Microsoft environments.

yeye_olive
22nd August 2012, 10:46
I have done this before for Windows and Linux. On Linux, you have to catch some Unix signals as ChrisW67 says. The relevant ones are SIGHUP, SIGINT, SIGQUIT, and SIGTERM.

On Windows there are no such signals. You need to call the Win32 SetConsoleCtrlHandler() function to register a callback function. This callback will be executed in a dedicated thread when the program receives a shutdown request. In that callback function you are allowed to do many more things than in a Unix signal handler; you do not have to use self-pipe tricks; instead you can simply make a QObject emit a signal or call QCoreApplication::postEvent() with a custom event (these facilities are thread-safe) to inform the application that it needs to quit.

amleto
22nd August 2012, 13:33
Wow, I had an idea right out of left field... how about he does the sensible thing and adds a quit command (instead of trying non portable code solutions)?


How do i call this custom shutdown function whenever the application is closed in such a way? (by the way, if one "ends process" in the task manager this problem does not pop up and that's why the release mode shutdowns are always fine as they don't pop up a console window and only way to do is is through task manager)
That more than likely just means you don't see the error, rather than 'shutdowns are always fine'.

yeye_olive
22nd August 2012, 14:37
@amleto

Agreed, adding a quit command may be a sensible thing to do, but that will not make the shutdown code be executed when the application is terminated by Ctrl+C, through the task manager, or when the user logs out while the application is still running. Whether or not this is acceptable is up to the OP.

amleto
22nd August 2012, 14:46
ctrl+c and task manager kills are not nice ways to close a program so don't think much time should be invested in handling these cases.

At least for windows, logging users out seems to attempt to close programs nicely (sometimes windows warns that a program doesn't want to close)

yeye_olive
22nd August 2012, 16:10
At least for windows, logging users out seems to attempt to close programs nicely (sometimes windows warns that a program doesn't want to close)
Yes, Windows notifies applications but they have to handle the notification or be killed. It is similar to Linux sending SIGTERM to all processes, waiting for a few seconds for them to exit gracefully, then sending SIGKILL.

If I remember correctly, Windows is a bit complex in that it treats console applications, GUI applications, and services differently when it comes to notifying that the user logs off or that the system shuts down. For GUI applications it seems that Windows sends window messages, so there is a good chance that Qt picks them up and does the right thing (close the widgets). I have not tested it, though.

The situation is different for console applications (which is apparently what the OP is interested in). From the documentation for SetConsoleCtrlHandler():

The handler functions also handle signals generated by the system when the user closes the console, logs off, or shuts down the system.
Not setting a handler means that the console application will ignore the notification and be subsequently killed.

ustulation
23rd August 2012, 20:28
Wow! I's too occupied yesterday and got to see the post only just now and there's so much information :)

@yeye_olive : you have understood my problem and I'm going to try incorporating the windows function you've suggested.

@amleto : you've answered me in almost all my posts and have always been more than a big help. i agree it'll be platform specific but there seems no other way to do it. maybe i need a few #defines to define the environment and code for platform customization. the start of the protocol app is triggered by the boot routines of the product on which it is intended to run and it dies with the shutdown of the product. the user is oblivious to all this and there is no quitting the application. the console shows up only in the Debug mode. in release mode deployment there is no (trivial) way to kill it. the O.S is embedded and is locked and hidden.