-
Bug
-
Resolution: Done
-
P2: Important
-
5.9.1
-
c57681bc376d1d912d23b044c48932fa8f7816d7 (qt/qtdeclarative/5.12)
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--;
}
}
}