Re-implementation of QApplication::Notify not catching exceptions
-
Hi All -
I'm using Qt 5.5 on an ARM platform. I'm using gcc with the C++11/14 switch turned on, and if it matters, am using some of those features; but in this context, the only such feature I'm using is the C++11 "override " function specifier, which shouldn't modify generated machine code, as it just flags the compiler to verify that any function it's specified for is indeed overriding a base class's virtual function.
I've search all over and experimented like crazy with this, but can't figure this out. I've been away from Qt for a few years, but had two classes from back then, one that extends QApplication, and one that extends QCoreApplication, that both re-implement the ::notify method to catch exceptions. I've done this in the way that is recommended all over the internet (and everything I can find still says that's the way to do it). I also know that the re-implentation of QApplication used to work when I last used it a few years back
bool SomeClass::notify(QObject* receiver, QEvent* e) { try { //If extending QCoreApplicaiton: return QCoreApplication::notify(receiver, e); //or, if extending QApplication: return QApplication::notify(receiver, e); //or, if extending QGuiApplication: return QGuiApplication::notify(receiver, e); } catch (const SomeException& e) { //Do something } catch (...) { //Do Something } return false; }
The problem I'm having is that for QCoreApplication, any exceptions thrown from the event loop are caught, but for QApplication, any exceptions thrown from the event loop are NOT caught - instead, std::terminate is being called, which is of course what happens when an exception is not caught. Note that on a whim, I also tried extending QGuiApplication, and re-implemetning its notify method, and exceptions were caught. So the issue appears to be only with QApplication.
I've gone so far as to make a toy example that works for QCoreApplication, and then simply found/replaced every instance of QCoreApplication in SomeClass's header and source file with QApplication (and also QGuiApplication, which as I said, works), then recompiled - but QApplication still has the same issue. Of course, there's only four instances of QCoreApplication to replace: the include statement and public inheritance statement in the header, and the call to the base class constructor in the constructor's initializer list and the call to base class notify function in notify.
I've also tried throwing exceptions from both gui and non-gui related events (e.g. exception when clicking a button and exception when reading from a socket due to a socket notifier event).
Since the try catch blocks enclosing notify must catch any exception thrown from notify or any function it calls, I'm not even sure how this is possible... Unless, for some reason, the SomeClass::notify method is not being called because some or part of the Qt event loop is processed via some other QApplication function in addition to, or instead of, notify. This would have to be a function that is not called from notify, but is called directly from the Qt engine, because again, the try/catch block must catch anything thrown by QApplication::notify.
So does QApplication process events in some other function besides notify (i.e. does Qt 5 have other functions, in addition - or instead of - notify that need to be re-implemented with try/catch in order to catch exceptions from QApplication event loops)? I actually looked at all of the functions listed under event handling on the QApplication web page doc, and besides notify, only the QObject::event function was virtual; I tried re-implementing it (just as for notify) and that didn't work either. So I'm not sure what else there is to re-implement, unless one needs to re-implement a non-virtual function, which would be bad for obvious reasons.
One other odd thing, that I don't remember from when I worked with Qt before, is that if I don't re-implement notify, QCoreApplication prints out a warning about not throwing exceptions from event loops; but if I use QApplication (and interestingly, QGuiApplication, despite the fact that I can catch its exceptions), notify doesn't print this warning. The Qt documentation states that QApplication (eventually, after a few classes in between) extends QCoreApplication, but I don't know if QApplication actually ever calls QCoreApplication::notify, so maybe that's why the warning isn't printed. I do know that the warning comes from QCoreApplication::notify; I've glanced at the source, but haven't yet followed everything from QApplication::notify back up to QCoreApplication. If QApplication::notify does call QCoreApplication::notify, then this lack of a warning message may be a clue that for whatever reason, the QApplication event loop is indeed being partially processed by a function that is not called from notify.
Thanks in advance!
-
Hi and welcome to devnet,
Taking a quick look a QApplication's code doesn't show any call to QCoreApplication nor QGuiApplication notify function.
In any case, it does sound strange. I'd recommend taking a look at the bug report system to see if it's something known. If not please consider opening a new report providing a minimal compilable example reproducing that behavior.
-
Thanks for the response and for verifying QApplication doesn't call the other class's notify function. That at least starts to explain why QApplication and QCoreApplication may be behaving differently.
I did a quick search of the bugs database. I found one match that states the exact problem I'm having.
https://bugreports.qt.io/browse/QTBUG-15197?jql=text ~ "Exception QApplication"However, it's for an older version of Qt (4 - I'm using 5) and has apparently been fixed.
Further, the bug was for Mac. The poster said the problem didn't exist on Windows, but he didn't mention Linux (I'm sure because he didn't try it on Linux), which is my platform.
Finally, the comments to the bug report mention some workarounds, but to me, the workarounds don't seem to match the initial bug-report. Of course, I've been away from Qt for a long time, and never did much with the GUI side of things (the GUI I'm trying to add exception handling for is someone else's code).
I guess at this point, given the lack of any other leads, I'd say it needs a bug report; I'll try to file one when I get a chance.
Thanks!
-
Indeed, don't forget to provide a minimal compilable example. That will help greatly.