Details
-
Bug
-
Resolution: Fixed
-
P3: Somewhat important
-
6.5.2
-
-
7fac2fac9 (dev), d909a8ed6 (6.6), 2dfa02b46 (tqtc/lts-6.5)
-
G&UI Finishing 2023
Description
Background
We use Qt Windows embedded into native windows, both being run as standalone applications as well as in plug-ins. To accomplish this, the QApplication::exec() is not performed, but being relied on the integration into a potentially foreign (-> plug-in use case) native event loop.
Observations
If the QObject::deleteLater functionality is used outside of event processing (QWindow::event) and not from an external helper thread, the objects which are marked down for release are never released, and causing memory leaks in all our Qt based products.
Reproduction
This scenario is easily reproducible by setting up a minimal Qt standalone application, and
- Replacing the call to QApplication::exec() with the native counterpart (e.g. NSApplicationMain under macOS)
- Creating some QObjects and immediate calling deleteLater on them while still being in the main() function
- Watch deletion state on app shutdown
Notes
We spent some time researching this and seem to have found the particular piece of code, which does not (according to our current knowledge) handle the external event loop use case properly:
https://github.com/qt/qtbase/blob/6.5.2/src/corelib/kernel/qcoreapplication.cpp#L1852-L1859
It looks like, as if we run into the use case where eventLevel and loopLevel both are zero, and the event is put into a queue which is in our case never cleared, because our event has been posted, and therefor event_type has been set to zero as well.
Unanswered
For us it would be first of all absolutely necessary to understand, how the integration of the foreign event loop needs to be setup on our side in application code (if something like this exists), for it to be treated internally as as a valid event loop, to be able to have these deferred deletions processed automatically (and reliably), which is absolutely crucial for us, so that we can avoid very ugly workarounds, and having to process these events manually and figure out at which time this could even be possible, which we assume is better being left to be handled by the Qt event system.
Attachments
For Gerrit Dashboard: QTBUG-117975 | ||||||
---|---|---|---|---|---|---|
# | Subject | Branch | Project | Status | CR | V |
525446,6 | Document how to process deferred deletes in a plugin-scenario | dev | qt/qtbase | Status: MERGED | +2 | 0 |
526658,3 | Document how to process deferred deletes in a plugin-scenario | 6.7 | qt/qtbase | Status: ABANDONED | 0 | 0 |
530849,2 | Document how to process deferred deletes in a plugin-scenario | 6.6 | qt/qtbase | Status: MERGED | +2 | 0 |
530909,2 | Document how to process deferred deletes in a plugin-scenario | tqtc/lts-6.5 | qt/tqtc-qtbase | Status: MERGED | +2 | 0 |