[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