0

If you google for "QCoreApplicationPrivate::sendPostedEvents exception", you'll find a ton of hits, probably at least in part because this method eats exceptions thrown in event handlers (such as paint event handlers, ...). Programmers consequently don't know where the exceptions were thrown and have difficulty locating their bugs. I am looking for a workaround for this yet-another pain Qt imposes on programmers. Here's the actual code snippet from qcoreapplication.cpp:

#ifdef QT_NO_EXCEPTIONS
        QCoreApplication::sendEvent(r, e);
#else
        try {
            QCoreApplication::sendEvent(r, e);
        } catch (...) {
            delete e;
            locker.relock();

            // since we were interrupted, we need another pass to make sure we clean everything up
            data->canWait = false;

            // uglehack: copied from below
            --data->postEventList.recursion;
            if (!data->postEventList.recursion && !data->canWait && data->eventDispatcher)
                data->eventDispatcher->wakeUp();
            throw;              // rethrow
        }
#endif

Way to go Qt geniuses! Deep in the bowels of my code, an exception is thrown, but I don't know where because of this gem. A way to work around it presents itself in the above code: disable the exception support and recompile Qt, or change the code and recompile. Even though it probably is not possible: does some other workaround to this problem under any operating system exist?

EDIT: I am using Qt4.8.

user1095108
  • 14,119
  • 9
  • 58
  • 116
  • I'm really confused about what your complaint is here. The code catches exceptions, cleans up, and rethrows them. What else would you expect it to do? – Dan Milburn Apr 29 '14 at 09:07
  • It winds up the stack frame when it catches, erasing information about where the throw occurred. Just click on the link I provided and you'll see a plethora of bug reports. Some RAII technique might have sufficed for cleaning up, but they are afraid to touch the holy code. – user1095108 Apr 29 '14 at 09:09
  • Right, but your complaint is not that there's a problem with Qt's exception handling, but that they're catching the exception at all. This is not reasonable. Anyway, my suggestion would be to stop the exception getting to that point in the first place. If necessary, subclass Q(Core)Application, override the notify() method and catch exceptions there. – Dan Milburn Apr 29 '14 at 09:32
  • Dan, I did my research thoroughly and subclassing does not work for this purpose. The stack frame is wound up and partially gone as soon as the exception is caught - hence on can't get a backtrace. The subclassing may work for gracefully handling uncaught exceptions. – user1095108 Apr 29 '14 at 09:35
  • The exception has to be caught somewhere! – Dan Milburn Apr 29 '14 at 09:44
  • Why? If it is not caught `::std::terminate()` is called and you can see where it was thrown. http://en.cppreference.com/w/cpp/error/terminate – user1095108 Apr 29 '14 at 10:09
  • Because exiting prematurely for no good reason is not generally desirable behaviour in an application. An exception is a notification that there was an error which should be handled elsewhere, *not* in most cases an attempt to close. Even in cases where there has been a catastrophic error and the program needs to exit, it's a good idea to catch exceptions and e.g. attempt to save a user's work before exiting. If you want them to behave like an assert, I suggest you use assert. – Dan Milburn Apr 29 '14 at 14:53
  • Sure, yes, but sometimes, one does not have control over what and when gets thrown, sometimes `STL` throws (which is what happened in this case). – user1095108 Apr 29 '14 at 16:37

2 Answers2

1

In Qt 5, all you need to do is to reimplement QCoreApplication::notify and catch your exception before Qt does. That's it. See, for example, this answer.

In Qt 4, you need to backport code from Qt 5.

Community
  • 1
  • 1
Kuba hasn't forgotten Monica
  • 95,931
  • 16
  • 151
  • 313
  • I fail to see how overriding a method could possibly solve this problem, even in `Qt5`. If the stack frame is left untouched, no overriding should be necessary, if it is not left untouched, I don't see how overriding could help. – user1095108 Apr 30 '14 at 08:33
  • @user1095108 Oh for crying out loud just do it and see how the stack looks within `notify`. There's your answer. – Kuba hasn't forgotten Monica Apr 30 '14 at 12:34
  • It does seem Qt5 does not suffer from this issue anymore, but you're wrong in asserting one should subclass `QCoreApplication`, as I was not trying to handle an unhandled exception, but merely see where the throw occurred. You cannot force a certain order of propagation of exceptions, it is the same as the order of catch statements. `Qt5` simply does not seem to catch any exception in my tests. – user1095108 Apr 30 '14 at 12:56
0

One possible solution is to use the gdb's catch command:

(gdb) catch throw

If the circumstances in which the throw occurs are then reproduced, gdb will stop the execution of the debugee and one can display the stack trace with the bt command, thereby finding out the location of the throw.

user1095108
  • 14,119
  • 9
  • 58
  • 116