[Interest] Crash in QAbstractEventDispatcher::filterNativeEvent when trying to show a QMessageBox
Thiago Macieira
thiago.macieira at intel.com
Thu Apr 14 23:15:52 CEST 2022
On Thursday, 14 April 2022 12:02:06 PDT Henry Skoglund wrote:
> if I look at the debugger data and in the QThreadData * dump, I see that
> the looplevel is 1 but if this is the GUI thread shouldn't it be 2
> considering we've passed through the exec() call in QDialog? I mean
> since a Qt GUI app usually starts with an exec() call which changes the
> looplevel from 0 to 1 for the lifetime of the app.
> Is that why you're suspecting the crash occurs becase we're still in the
> worker thread?
Hello Henry
You can't trust that data dump. The very first pointer in it is suspicious:
> - d 0x0000020000030600
That doesn't look like a valid pointer to me. However, I confess I don't know
for sure because that's a Windows pointer and I don't know the memory layout
on Windows as well as I do on Linux. Points in favour of it being valid are:
- debugger was able to tell that the QAbstractEventDispatcherPrivate was
actually a QEventDispatcherWin32Private object
- the handle 0x00000000003c087e appears multiple times
- the "size" fields in all objects shown are suitably low numbers
But then we see this:
> + *filter *0x00000200048cefc0 {d=*0xdfdfdfdfdfdfdfdf* {...} }
That's definitely not a valid pointer, for two reasons, even if you ignore the
extremely unlikely chance it would be the repeated pattern of 0xdf. First,
it's unaligned; second, for x86-64, it would be non-canonical which is not
permitted. What his tells me is that even if the "filter" pointer was valid,
it was pointing to garbage. Therefore, when the code places this virtual
function call:
if (filter->nativeEventFilter(eventType, message, result))
It should crash. And it did.
Looking at the code, we see this variable came from:
for (int i = 0; i < d->eventFilters.size(); ++i) {
QAbstractNativeEventFilter *filter = d->eventFilters.at(i);
In the previous object, we saw the size member for eventFilters was a suitable
value of 1, the data for that QList must have been totally invalid. Most
likely, this is caused by a race with another thread updating the filter list,
either inserting or removing an element and leading to a memory reallocation.
--
Thiago Macieira - thiago.macieira (AT) intel.com
Software Architect - Intel DPG Cloud Engineering
More information about the Interest
mailing list