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

Crash on ListModel append when delegate is an external component

    XMLWordPrintable

Details

    Description

      When using an externally loaded QML component as a delegate, using ListModel append() repeatedly results in a crash. This is reliably reproducible as the attached example shows. Here is main-fails.qml from the attached project:

      import QtQuick 2.5
      
      Rectangle {
          id: root
      
          width: 600
          height: 400
      
          Component.onCompleted: {
              var component = Qt.createComponent("shape.qml")
              if (component.status === Component.Ready) {
                  shapeView.delegate = component
              }
      
              shapeTimer.start()
          }
      
          function addShape() {
              shapeModel.append({"x": Math.random() * 500, "y": Math.random() * 300, "rotation": Math.random() * 90})
              console.log('Just added ListElement ' + shapeModel.count)
          }
      
          ListModel {
              id: shapeModel
          }
      
          Repeater {
              id: shapeView
              anchors.fill: parent
              model: shapeModel
          }
      
          Timer {
              id: shapeTimer
              interval: 20
              repeat: true
              onTriggered: {
                  addShape()
              }
          }
      }
      

      The number of time append() needs to be called for a crash appears to be dependent on:

      • platform
      • complexity of component (the bigger the component the earlier the crash)

      For a particular platform and a particular component, it will always crash on the same iteration. e.g. when using attached QML main-fails.qml this will always fail when trying to add element 163 when I run this on my Mac.

      Other observations:

      1. Strangely if append() is called many times in rapid succession / from within the same function then there appears to be no limit to the number of appends within that batch. This does not stop it failing if the function is called again and the crash limit is already reached. My suspicion is that it has something to do with when the view is rendered, because a render cannot happen during a batch append()
      2. The problem never arises if the component is internal to the main QML file
      3. Calling ListModel clear() in between append() or blocks of append() makes no difference. i.e. it's not the size of the model that affects when a crash will happen; it's the number of times append() has been called.

      I have included 4 versions, 2 which work and 2 which fail. To invoke the different versions edit which QML file is loaded on main.cpp:10

      In all cases a 600x400 window is created and append() is invoked via a timer to add rectangles with random x, y & rotation.

      • main-works.qml uses an internal component and performs one append() per call to addShape()
      • main-fails.qml uses an identical external component and also performs one append() per call to addShape() - On my Mac this fails on trying to add ListElement 163 (see console log). You may reach a different number on a different machine. I have attached the crash report for this.
      • main-works-too.qml is like main-works.qml but calls append() 10000 times in a for loop within the addShape() function. (The timer loop is slower to account for slower execution of addShape().)
      • main-fails-too.qml is like main-fails.qml but calls append() 10000 times in a for loop. I have attached the crash report for this too. In this example it successfully calls append many more times than the usual crash limit in one go. However there isn't a render until the end of the for loop. If you change the loop to, say, call append() times within addShape() you'll find it still fails at the first call to addShape() after the crash limit has been reached.

      Attachments

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

        Activity

          People

            shausman Simon Hausmann
            paulmasri Paul
            Votes:
            3 Vote for this issue
            Watchers:
            8 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved:

              Gerrit Reviews

                There are no open Gerrit changes