We have a small program written in Qt on windows, we use minidump to help us catch client side crash.
Our goal is to at least see the call stack when it crashes.
...
SetUnhandledExceptionFilter(unhandled_handler); // write minidump in unhandled_handler
...
The problem is it doesn't always create minidump after a crash, sometimes the error log shows:
Warning: 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.
Does qt catch the exception and stop my app creating minidump?
There are also times we get useless minidump result, it's Call Stack is:
[Frames may be missing, no binary loaded for KERNELBASE.dll]
KERNELBASE.dll!00007ffd05bd4fd9() Unknown
With output
Unhandled exception at 0x00007FFD05BD4FD9 in SofterClear_1_22_0_220822_141118_061915.dmp: Microsoft C++ exception: std::
According to this :
Throwing an exception from a slot invoked by Qt's signal-slot connection mechanism is considered undefined behaviour, unless it is handled within the slot
I have tried to override QApplication::notify as
bool AlignApplication::notify(QObject * receiver, QEvent * event)
{
bool done = true;
try {
done = QApplication:
}
catch (const std::exception& ex) {
throw ex; // I have also tried to create minidump here, but it's empty and useless.
}
catch (...) {
throw "unknown error";
}
return done;
But it doesn't work.
Is it possible to create minidump with full call stack after an exception happen in Qt slot ?
Just to make things a bit more clear, this is a typical implementation of an overridden
QApplication::notify:What if you rethrow? Well, guess:
notifyis an event handler, so you're very likely to get that warning which paradoxically suggests to overridenotify...Now, about doing something else in the catch block, let's first understand where the throw occurred. We kind of know that: in the parent's
notify, so in the middle of an event delivery, and very likely in the event handler of the receiving object.So, a simple thing I would try, would be to put in the catch block a line like this
just to figure out what kind of object has thrown while handling what kind of event.
Whatever else should be done in the asynchronous Qt style, i.e. posting an event, that will be dispatched later (anyway, after
notifyreturns). Say you wanted to quit the application:and return
trueorfalseright after.Now to your questions:
No, you can catch everything as usual, but if you want to catch exceptions thrown from an event handler you have to override that `notify' method as above.
Well, yes for sure if the slot is invoked directly (e.g. connected using
Qt::DirectConnection). You can emit the calling signal in a try block and catch whatever is thrown by the slot:On the other hand, if the event loop is involved in the slot invocation (e.g. connected using
Qt::QueuedConnection), I would answer yes again, and you have two options here:notify, as above.But, in the second case, you say you don't get a full call stack and I really can't say what it is but I'm pretty sure you can't blame Qt for not getting one. Anyway, at least, you can figure out what happened, e.g. what kind of event handler threw in which kind of object.