Unsolved `QGuiApplication::focusWindow()` can point to deallocated memory causing read access violations.
-
@AnyOldName3 said in `QGuiApplication::focusWindow()` can point to deallocated memory causing read access violations.:
I could provide a log of what the application spits out when it's full of tracepoints in interesting locations if that's wanted, which I imagine might help.
This would be nice, also a backtrace is always useful.
-
Here's the log: https://gitlab.com/snippets/1846991
The XML tracepoint descriptions are here: https://gitlab.com/snippets/1846986
I'll describe the tracepoints in a more human-readable way, too. Some of them include the call stack, but not line numbers for some reason known only to Microsoft.
qguiapplication.cpp
line 2282: Says whenQGuiApplicationPrivate::processActivatedEvent
is run, including the event pointer, the previous focus and the new focus.qwindow.cpp
line 1863: Says whenQWindowPrivate::destroy
exits early as the platform window is null.qwindowswindow.cpp
lines 1300 and 1301: Says when these lines are run to demonstrate that it's theDestroyWindow(m_data.hwnd)
creating the refocus events.qwindowsysteminterface.cpp
line 83: Says when a window system event is received of typeActivatedWindow
, and includes the event pointer (so you can pair these up with when they're processed later on).- Data breakpoint on
0x00007FFF612CAC10
: This address is whereQGuiApplicationPrivate::focus_window
resides, but annoyingly it's displayed as an address rather than a variable name. This tracepoint says when the focus window changes.
The actual crash occurs with this backtrace, although it's not especially interesting and is described in the first post -
QWidget::isActiveWindow()
tried to castQGuiApplication::focusWindow()
to aQWidgetWindow
after the window in question had already been deleted. -
I looked a bit at the code and at the trace. I couldn't spot anything out of the ordinary. However it seemed to me very unlikely that this refocus event you talk about is an issue in that particular sequence, as the refocusing doesn't actually spin the event loop; I'm just not quite convinced (doesn't mean necessarily it isn't a bug).
An odd issue, indeed. -
So you're thinking that maybe the problem is that the event loop is being run after things have started closing and it's not supposed to do that?
Anyhow, in case it helps, I made an equivalent trace but without the issue. I did this by clicking into another application's window and back before closing my application.
https://gitlab.com/snippets/1848606
Hopefully, there's some critical difference between the two that makes everything clear.
EDIT: I ran both through a diff tool, and the interesting differences seemed to start around line 1340.
-
The snippet is not accessible.
-
Oops... It should be fixed now.
-
I looked again. I don't know. My best guess is that some UI object (i.e. QWindow/QWidget) outlives the application object.
But to be completely blunt, I had hard time getting my bearings straight, that code is some mess - STL, boost, Qt and more amalgamated together in something very hard to read. -
I've checked, and the problem occurs while the QApplication is still around. There's even a check in the QApplication destructor that tells you if there are still widgets alive, so I'd have noticed if that was the issue. Do you have any other ideas?
-
Well... The technique is not the fastest but one thing you can do is comment everything out to start with an empty main window and then gradually add back pieces of your application until it breaks. That should help point which part might be responsible.
-
It's very timing-sensitive, so even subtly changing parts of the code that are completely unrelated can make it go away. That means I can't get a reliable negative test, so can't tell if adding something back caused the bug or just triggered it to reveal itself again.
-
I ran into the same problem and the issue occurs when closing the last Window (e.g. a dialog) and the dialog is destroyed. When creating a new dialog or widget the next time, the pointer returned by QGuiApplication::focusWindow() is a dangling pointer since it points to an already destroyed object.
The following code works around the issue and triggers an update of the pointer returned by QGuiApplication::focusWindow() after having closed the last Window by sending a FocusOut event:QObject::connect(qobject_cast<QGuiApplication*>(QGuiApplication::instance()), &QGuiApplication::lastWindowClosed, []() { QEvent event(QEvent::FocusOut); QCoreApplication::instance()->sendEvent(QCoreApplication::instance(), &event); QCoreApplication::instance()->processEvents(); });
The Qt version which I used was 5.11.1.
-
@mr-bachmann said in `QGuiApplication::focusWindow()` can point to deallocated memory causing read access violations.:
I ran into the same problem and the issue occurs when closing the last Window (e.g. a dialog) and the dialog is destroyed. When creating a new dialog or widget the next time, the pointer returned by QGuiApplication::focusWindow() is a dangling pointer since it points to an already destroyed object.
Thanks for investigating. Do you have a minimal example that reproduces this? (I can see in the Qt code where the problem lies:
https://code.woboq.org/qt5/qtbase/src/gui/kernel/qguiapplication.cpp.html#_ZN22QGuiApplicationPrivate20emitLastWindowClosedEv should clear the global variable or send theFocusOut
, but it'd be good to file this as a bug report).