Qt-interest Archive, May 2008
"Qt has caught an exception thrown from an event handler"
Message 1 in thread
I've just had an exe dump core with this:
> Qt has caught an exception thrown from an event handler. Throwing
> exceptions from an event handler is not supported in Qt. You must
> reimplement QApplication::notify() and catch all exceptions there.
The exe did indeed throw an exception, but I'm not sure why
it's caused this crash. The backtrace is as follows:
> (gdb) bt
> #0 0xb728bbfa in QEventLoop::isRunning (this=0x8081ba8) at kernel/qeventloop.cpp:269
> #1 0xb728e5fc in QCoreApplication::postEvent (receiver=0x8081ba8, event=0x8081ec8) at kernel/qcoreapplication.cpp:844
> #2 0xb729a387 in QObject::deleteLater (this=0x8081ba8) at kernel/qobject.cpp:2117
> #3 0xb7388737 in QTcpServer::close (this=0xbff38db8) at qtcpserver.cpp:321
> #4 0xb7388840 in ~QTcpServer (this=0xbff38db8) at qtcpserver.cpp:214
> #5 0xb7eff3fd in ~HTTPListener (this=0xbff38db8) at /code/mdp_qt/src/lib/HTTPListener.cpp:40
> #6 0x0804e487 in main (argc=1, argv=0xbff38f74) at /code/mdp_qt/src/bin/mdp_agent.cpp:73
Does this suggest anything to someone more familiar
with Qt's internals ?
--
[ signature omitted ]
Message 2 in thread
Stephen Collyer wrote:
> I've just had an exe dump core with this:
>
> > Qt has caught an exception thrown from an event handler. Throwing
> > exceptions from an event handler is not supported in Qt. You must
> > reimplement QApplication::notify() and catch all exceptions there.
>
> The exe did indeed throw an exception, but I'm not sure why
> it's caused this crash. [...]
>
> Does this suggest anything to someone more familiar
> with Qt's internals ?
You cannot throw exceptions across signals and slots - so you'll have to
make sure your slots (and event handlers) catch all exceptions they are
able to throw.
Or you can follow the suggestion and reimplement QApplication::notify()
and globally catch exceptions there.
Cheers,
Peter
--
[ signature omitted ]
Message 3 in thread
Peter Prade wrote:
> Stephen Collyer wrote:
>> I've just had an exe dump core with this:
>>
>>> Qt has caught an exception thrown from an event handler. Throwing
>>> exceptions from an event handler is not supported in Qt. You must
>>> reimplement QApplication::notify() and catch all exceptions there.
>> The exe did indeed throw an exception, but I'm not sure why
>> it's caused this crash. [...]
>>
>> Does this suggest anything to someone more familiar
>> with Qt's internals ?
>
> You cannot throw exceptions across signals and slots
You mean that I can't throw an exception in a slot that
doesn't catch that exception ? Or does "throwing an
exception across a slot" have some more specialised meaning ?
> - so you'll have to
> make sure your slots (and event handlers) catch all exceptions they are
> able to throw.
Right. I intended to do this, but I've noticed that I
don't, in fact. That's easy to fix.
--
[ signature omitted ]
Message 4 in thread
Stephen Collyer wrote:
> >> Does this suggest anything to someone more familiar
> >> with Qt's internals ?
> > You cannot throw exceptions across signals and slots
>
> You mean that I can't throw an exception in a slot that
> doesn't catch that exception ? Or does "throwing an
> exception across a slot" have some more specialised meaning ?
Well, slots that are called using queued connections should not throw
exceptions. (or you will see this error)
Of course, if you don't use queued connections at all, you can ignore
this problem.
Cheers,
Peter
--
[ signature omitted ]
Message 5 in thread
Peter Prade wrote:
> Stephen Collyer wrote:
>>>> Does this suggest anything to someone more familiar
>>>> with Qt's internals ?
>>> You cannot throw exceptions across signals and slots
>> You mean that I can't throw an exception in a slot that
>> doesn't catch that exception ? Or does "throwing an
>> exception across a slot" have some more specialised meaning ?
>
> Well, slots that are called using queued connections should not throw
> exceptions. (or you will see this error)
> Of course, if you don't use queued connections at all, you can ignore
> this problem.
Well, I'm not using queued connections, and I can't ignore
this problem - it causes a core dump ! But I'll try catching
it in the slot anyway.
--
[ signature omitted ]
Message 6 in thread
On Tuesday 27 May 2008 15:25:43 Stephen Collyer wrote:
> I've just had an exe dump core with this:
> > Qt has caught an exception thrown from an event handler. Throwing
> > exceptions from an event handler is not supported in Qt. You must
> > reimplement QApplication::notify() and catch all exceptions there.
>
Happens when an exception ends up in the event loop.
To understand why the exception ends in the eventloop you just need to imagine
how the stack layout will be in your application. The easiest way to
visualize it is opening gdb and adding a breakpoint on the function you throw
in.
You'll see something like
#0 myFunction();
#1 someSlot();
#2 processEvents()
#3 exec()
#2 main()
in that order. Now if you throw an exception in #0 and dont catch it in #1 it
will fall down to #2 which is part of the Qt Library. Qt doesnt know what to
do with them, becouse they are your exceptions. You might argue that it
should just let it fall to #0 where you can handle it, but unfortunatly
Exceptions can't cross libraries.
--
[ signature omitted ]
Message 7 in thread
Arvid Ephraim Picciani wrote:
> On Tuesday 27 May 2008 15:25:43 Stephen Collyer wrote:
>> I've just had an exe dump core with this:
>>> Qt has caught an exception thrown from an event handler. Throwing
>>> exceptions from an event handler is not supported in Qt. You must
>>> reimplement QApplication::notify() and catch all exceptions there.
> Happens when an exception ends up in the event loop.
>
> To understand why the exception ends in the eventloop you just need to imagine
> how the stack layout will be in your application. The easiest way to
> visualize it is opening gdb and adding a breakpoint on the function you throw
> in.
>
> You'll see something like
>
> #0 myFunction();
> #1 someSlot();
> #2 processEvents()
> #3 exec()
> #2 main()
>
> in that order. Now if you throw an exception in #0 and dont catch it in #1 it
> will fall down to #2 which is part of the Qt Library. Qt doesnt know what to
> do with them, becouse they are your exceptions. You might argue that it
> should just let it fall to #0 where you can handle it, but unfortunatly
> Exceptions can't cross libraries.
Thanks. But I don't think this is in any way limited to
queued connections, it it ? This will happen with any
exception in any slot.
--
[ signature omitted ]
Message 8 in thread
On Thursday 29 May 2008 21:59:57 Stephen Collyer wrote:
> Thanks. But I don't think this is in any way limited to
> queued connections, it it ? This will happen with any
> exception in any slot.
no. direct connections work like a callback.
when you "emit someSignal()" you just call the callbacks inserted into the metaobject for "someSignal" and wait for them to return.
what you are experiencing maybe is that you throw and exception in a slot that has been called by a slot that has been called by a slot that has been called by a Qt internal. Ie QTcpSocket.