Segmentation fault on SIGINT interception when trying to exit the QCoreApplication
-
Hi,
I want to use a cleanup function when my QCoreApplication is destroyed (intercepting a SIGINT).
I've tried two methods:
First to connect the QCoreApplication::aboutToQuit to a slot that would do the job but I don't end up in the slot when the application is closed by a SIGINT or even if close manually the app (launched via QT Creator)...So my second option would be to use signal interceptions. Here is what I do:
#include <csignal> Proxy *theProxy = NULL; QCoreApplication *app = NULL; void handleShutDown(int signal){ Proxy::shutDown(); std::cout << "Try to exit the event loop\n"; app->exit(0); } int main(int argc, char *argv[]) { app = new QCoreApplication(argc, argv); signal(SIGINT, &handleShutDown);// shut down on ctrl-c signal(SIGTERM, &handleShutDown);// shut down on killall theProxy = Proxy::getInstance(); // QObject::connect(app, &QCoreApplication::aboutToQuit, theProxy, &Proxy::deleteInstance); if (!theProxy->start()){ std::cout << "Error starting Proxy...\n"; return 1; } app->exec(); // Run the event loop std::cout << "Event loop ended..."; return 0; }
So here is what I get when I stop my app with a SIGINT:
^CTry to exit the event loop Segmentation fault
I can see that the cleanup funtion is well executed but then there is a segmentation fault when I try to exit the QCoreApplication.
I've no clue how I could debug this...
Any idea what I'm doing wrong or how I could get traces to understand more the issue?Thanks.
-
Hello,
Firstly, do not create theQCoreApplication
instance in the heap, you gain only headaches. Secondly, if you really need a global static variable (which I believe you don't) you should use Q_GLOBAL_STATIC. You would want to intercept the signals only if you have some very specific setup where you need to cleanup some global resources that don't belong to your application (i.e. a shutdown routine for a driver). Global variables are like premature optimization, they're troublesome and in most cases purely unnecessary, don't use them unless you're forced to.Kind regards.
-
Hi,
To add to @kshegunov, you can access the instance of QCoreApplication through qApp.
-
Ok, I've let the QCoreApplication on the stack and don't use anymore a global variable for my Proxy. I don't really need to as I'm using the singleton pattern. Both constructor and destructor are private.
I'm using a static method to get/create the instance and another one to delete it.
Here is the new code.#include <csignal> void handleShutDown(int signal){ std::cout << "Try to shutdown the proxy\n"; Proxy::shutDown(); std::cout << "Try to exit the event loop\n"; qApp->exit(0); } int main(int argc, char *argv[]) { QCoreApplication app(argc, argv); signal(SIGINT, &handleShutDown);// shut down on ctrl-c signal(SIGTERM, &handleShutDown);// shut down on killall Proxy *theProxy = Proxy::getInstance(); // QObject::connect(app, &QCoreApplication::aboutToQuit, theProxy, &Proxy::deleteInstance); if (!theProxy->start()){ std::cout << "Error starting Proxy...\n"; return 1; } app.exec(); // Run the event loop std::cout << "Event loop ended..."; return 0; }
I'm still having the same segmentation fault. Any idea why? The object I'm deleting inherit from QTcpServer and is just listening.
I'm having the crash without having done anything.
As I said, the object is destructed and the crash seems to happen after on the exit call to stop the event loop.Server started, listening on port: 11111 ^CTry to shutdown the proxy Try to exit the event loop Segmentation fault
PS: I need to have a cleanup function. In most cases, my program will be stopped by an interruption and I want to make sure it releases the resources properly and take the time to write final logs before shutting down.
-
Alright the handling of the shutdown interruption is working fine.
I've managed to find what was causing the segmentation fault. It is the construction/deletion of my SQL class that do a QSqlDatabase::addDatabase...
I'm going to try to understand what could be the problem and open another post if I don't manage to get what is wrong. -
Also, what backtrace to you get from the debugger ?