PDA

View Full Version : qFatal is killing my application with msg handler installed.



33333
5th July 2014, 00:49
Hi

I realize the default behavior of qFatal() is to terminate an application. However the documentation suggests if I install a message handler it wont. But it is. How can I stop qFatal() from killing my application?

To clarify I have the following code. I actually do want to quit on qFatal() but I want to do clean up too. In this code the qApp->quit() slot is never executed because its asyncronous and something is killing my app before the event loop has a chance to pick it up. (omitting the arbitrary bit of code somewhere that actually calls a `qFatal()` because its not important):



#include <QtGlobal>
#include <QApplication>
#include <unistd.h>
#include <stdio.h>

void LogMsgHandler(QtMsgType type, const char *msg)
{
switch (type) {
#ifndef QT_NO_DEBUG_OUTPUT
case QtDebugMsg:
printf("DEBUG: %s\n", msg);
break;
#endif
case QtWarningMsg:
printf("WARNING: %s\n", msg);
break;
case QtCriticalMsg:
printf("CRITICAL: %s\n", msg);
break;
case QtFatalMsg:
printf("FATAL: %s\n", msg);
qApp->quit(); // Does not generate aboutToQuit(). Does not exit event loop.
}
printf("Exiting handler\n");
}

int main(int argc, char *argv[])
{
qInstallMsgHandler(LogMsgHandler);
QCoreApplication app(argc, argv);
Controller controller;
app.exec();
printf("Never get here. Because something kill my app.\n");
}


Thanks.

ChrisW67
5th July 2014, 09:11
qFatal() calls qt_message_output() internally which, after calling your handler, terminates the program using the _CrtDbgBreak(), abort(), or exit(1) call (depends on platform). The message handler allows you to do something custom with the message, not suppress the termination. You could just call your clean up code before returning from your message handler for fatal messages (or warnings where QT_FATAL_WARNINGS is set). Alternatively,

You can install a signal handler for SIGABRT to trap the abort() call.
You can use atexit() or something similar to register a function to run after exit() is called.
I have no idea how you intercept the Windows function.

33333
5th July 2014, 10:51
Ah OK. It aborts on Linux. The docs didn't quite say overriding the msg handler would override the abort behavior though the wording suggested it. Suks a bit. The whole motivation for me was reusing the q(Debug|Message|Critical|Fatal) function and semantics - except for the abort(). They're kind of limiting anyway, so maybe I'll just write my own layer, use that in my own code exclusively, and just use the message handler to pipe stuff from third party libs that use these appropriately.

On catching SIGABRT; I really wanted to use aboutToQuit() to decouple the cleanup() from the signal handler (if its a safe signal to return from). `abort()` never returns, so if Qt actually uses abort() the event loop won't be reentered. I'll have to investigate .

Thanks.