Uploaded image for project: 'Qt'
  1. Qt
  2. QTBUG-76254

Crash in QQmlDelegateModel::_q_itemsInserted

    XMLWordPrintable

Details

    • ab933b1c92ec4f39ce280fdf956a4c4a746cf4d9 (qt/qtdeclarative/5.12)

    Description

      I've recently had lots of crashes in _q_itemsInserted with stack traces like this:

       0  Qt5Core.dll + 0x4169ec
          eip = 0x672a69ec   esp = 0x00f1c290   ebp = 0x14785d68   ebx = 0x0000001a
          esi = 0x00000018   edi = 0x00000001   eax = 0x0000001b   ecx = 0x230513a8
          edx = 0x671bd2ec   efl = 0x00010206
          Found by: given as instruction pointer in context
       1  Qt5Qml.dll!QQmlDelegateModel::_q_itemsInserted(int,int) [qqmldelegatemodel.cpp : 1346 + 0xb]
          eip = 0x657f7091   esp = 0x00f1c294   ebp = 0x14785d68
          Found by: stack scanning
       2  Qt5Qml.dll!QQmlDelegateModel::_q_rowsInserted(QModelIndex const &,int,int) [qqmldelegatemodel.cpp : 1657 + 0x14]
          eip = 0x657f7852   esp = 0x00f1c2b8   ebp = 0x14785d68
          Found by: call frame info
       3  Qt5Qml.dll!QQmlDelegateModel::qt_static_metacall(QObject *,QMetaObject::Call,int,void * *) [moc_qqmldelegatemodel_p.cpp : 198 + 0x1a]
          eip = 0x657f46fa   esp = 0x00f1c2c8   ebp = 0x14785d68
          Found by: call frame info
       4  Qt5Qml.dll!QQmlDelegateModel::qt_metacall(QMetaObject::Call,int,void * *) [moc_qqmldelegatemodel_p.cpp : 334 + 0x9]
          eip = 0x657ff4e5   esp = 0x00f1c2fc   ebp = 0x14785d68
          Found by: call frame info
       5  Qt5Core.dll!QMetaObject::metacall(QObject *,QMetaObject::Call,int,void * *) [qmetaobject.cpp : 303 + 0x5]
          eip = 0x67005848   esp = 0x00f1c320   ebp = 0x00f1c418
          Found by: call frame info
       6  Qt5Core.dll!QMetaObject::activate(QObject *,int,int,void * *) [qobject.cpp : 3806 + 0x14]
          eip = 0x6701cadf   esp = 0x00f1c330   ebp = 0x00f1c418
          Found by: call frame info
       7  Qt5Core.dll!QAbstractItemModel::endInsertRows() [qabstractitemmodel.cpp : 2748 + 0x52]
          eip = 0x66fcab28   esp = 0x00f1c3d8   ebp = 0x00000000
          Found by: call frame info with scanning
       8  Qt5Core.dll!QSortFilterProxyModelPrivate::insert_source_items(QVector<int> &,QVector<int> &,QVector<int> const &,QModelIndex const &,Qt::Orientation,bool) [qsortfilterproxymodel.cpp : 902 + 0x12]
          eip = 0x66fe70c9   esp = 0x00f1c434   ebp = 0x00000000
          Found by: call frame info
       9  Qt5Core.dll!QSortFilterProxyModelPrivate::source_items_inserted(QModelIndex const &,int,int,Qt::Orientation) [qsortfilterproxymodel.cpp : 1013 + 0x15]
          eip = 0x66feb0c8   esp = 0x00f1c48c   ebp = 0x00f1c688
          Found by: stack scanning
      10  ntdll.dll + 0x45d3e
          eip = 0x76ef5d3e   esp = 0x00f1c530   ebp = 0x00f1c6a4
          Found by: call frame info with scanning
      11  0xf1c688
          eip = 0x00f1c688   esp = 0x00f1c6ac   ebp = 0x00000000
          Found by: previous frame's frame pointer
      12  Qt5Core.dll!QSortFilterProxyModelPrivate::insert_source_items(QVector<int> &,QVector<int> &,QVector<int> const &,QModelIndex const &,Qt::Orientation,bool) [qsortfilterproxymodel.cpp : 902 + 0x12]
          eip = 0x66fe70c9   esp = 0x00f1c6c0   ebp = 0x00000000
          Found by: stack scanning
      13  Qt5Core.dll!QSortFilterProxyModelPrivate::source_items_inserted(QModelIndex const &,int,int,Qt::Orientation) [qsortfilterproxymodel.cpp : 1013 + 0x15]
          eip = 0x66feb0c8   esp = 0x00f1c718   ebp = 0x00f1c914
          Found by: stack scanning
      14  Qt5Core.dll!QVector<QVector<QPersistentModelIndexData *> >::reallocData(int,int,QFlags<QArrayData::AllocationOption>) [qvector.h : 625 + 0x13]
          eip = 0x66fcdd55   esp = 0x00f1c7f0   ebp = 0x00f1c914
          Found by: call frame info with scanning
      

      The reason is use after free of an item that is still hanging around in the loop's cache copy.

      Updating the model index like it's done in the loop can also effect the view's layout so destruction of items can happen during the iteration. I've traced the destructor calls to verify this, the item that causes the crash was actually destroyed prior to its use in the loop.

      5df747fc5300f9c7e1da0fb86bab68209c921c9c introduced a fix for the insert situation. The same fix can be applied here: Check if the item is still in the actual cache before accessing it.

      I'll submit a patch on gerrit for review later.

      Attachments

        For Gerrit Dashboard: QTBUG-76254
        # Subject Branch Project Status CR V

        Activity

          People

            njeisecke Nils Jeisecke
            njeisecke Nils Jeisecke
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved:

              Gerrit Reviews

                There are no open Gerrit changes