Details
-
Bug
-
Resolution: Done
-
P2: Important
-
5.9.1
-
c57681bc376d1d912d23b044c48932fa8f7816d7 (qt/qtdeclarative/5.12)
Description
I have the following callstack
Qt5QuickRTILd.dll!QHash<QQuickPixmapKey,QQuickPixmapData * __ptr64>::remove(const QQuickPixmapKey & akey) Line 790 C+ Qt5QuickRTILd.dll!QQuickPixmapData::removeFromCache() Line 1164 C Qt5QuickRTILd.dll!QQuickPixmapData::release() Line 1143 C Qt5QuickRTILd.dll!QQuickPixmapStore::~QQuickPixmapStore() Line 949 C+
Code is:
// unreference all (leaked) pixmaps for (auto *pixmap : qAsConst(m_cache)) { int currRefCount = pixmap->refCount; if (currRefCount) { #ifndef QT_NO_DEBUG leakedPixmaps++; #endif while (currRefCount > 0) { pixmap->release(); // this is Qt5QuickRTILd.dll!QQuickPixmapStore::~QQuickPixmapStore() Line 949 C++ currRefCount--; } } }
I think it is not allowed to remove the element of a QHash, where your iterator points to. This only happens if there is a pixmapdata with pixmapStatus != QQuickPixmap::Ready.
In fact I get a crash afterwards.
Qt5CoreRTILd.dll!QHashData::nextNode(QHashData::Node * node) Line 614 C+ Qt5QuickRTILd.dll!QHash<QQuickPixmapKey,QQuickPixmapData * __ptr64>::const_iterator::operator() Line 394 C Qt5QuickRTILd.dll!QQuickPixmapStore::~QQuickPixmapStore() Line 941 C+Exception thrown: read access violation.
d was 0xFFFFFFFFFFFFFFFF.
This happens in a unittest, where a async Quickimage is instantiated and shut down in a sequence.
IMHO this would fix the problem:
// unreference all (leaked) pixmaps for (auto *pixmap : qAsConst(m_cache)) { int currRefCount = pixmap->refCount; if (currRefCount) { #ifndef QT_NO_DEBUG leakedPixmaps++; #endif pixmap->inCache = false; // FIX while (currRefCount > 0) { pixmap->release(); currRefCount--; } } }
Attachments
For Gerrit Dashboard: QTBUG-65077 | ||||||
---|---|---|---|---|---|---|
# | Subject | Branch | Project | Status | CR | V |
248693,3 | qquickpixmapcache: Fix invalidation of m_cache while iterating it | 5.12 | qt/qtdeclarative | Status: MERGED | +2 | 0 |