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

Unbounded recursion in QQuickGridLayoutBase::rearrange leading to stack exhaustion and 100% reproducible crash (segfault)



    • Type: Bug
    • Status: Closed
    • Priority: P1: Critical
    • Resolution: Done
    • Affects Version/s: 5.12.0
    • Fix Version/s: None
    • Component/s: Quick: Layouts
    • Labels:
    • Sprint:
      Bug Fixing Candidates


      Launch the following in qmlscene to reproduce the segfault:

      import QtQuick 2.12
      import QtQuick.Controls 2.12
      import QtQuick.Layouts 1.12
      Rectangle {
        height: 400
        width: 400
        Column {
          anchors.fill: parent
          QtObject {
            id: viewModel
            property string aa: 'somea'
            property string bb: 'long_long_crazy_87235982735_23857239682376923876923876-fuwhfhfw-names-AAAA-deeaois2019-03-03.and.more'
            //property string bb: 'someb'
            property string cc: 'somec'
            property string dd: 'somed'
            property string ee: 'somee'
            property string ff: 'somef'
          GridLayout {
            columns: 2
            anchors.left: parent.left
            anchors.right: parent.right
            Repeater {
              model: ["aa", "bb", "cc", "dd", "ee", "ff"]
              Label {
                Layout.row: index
                Layout.column: 0
                Layout.fillWidth: true
                Layout.fillHeight: true
                font.pixelSize: 20
                text: modelData + ":"
                wrapMode: Text.Wrap
            Repeater {
              model: [viewModel.aa, viewModel.bb, viewModel.cc, viewModel.dd, viewModel.ee, viewModel.ff]
              Label {
                Layout.row: index
                Layout.column: 1
                Layout.fillWidth: true
                Layout.fillHeight: true
                font.pixelSize: 20
                text: modelData
                wrapMode: Text.Wrap

      If you comment out the line with the string that contains "long_long_crazy_8723598...", and instead set that string property to "short_string", then qmlscene can launch this file without crashing.

      To gain some preliminary insight into this crash, launch qmlscene under gdb and set a breakpoint in QQuickGridLayoutBase::rearrange(QSizeF const&) of qquicklinearlayout.cpp:485

      Let gdb hit the breakpoint 25 times, and note the call stack. Then let gdb hit the breakpoint a total of 50 times, then 100, and continue to look at the call stack each time.

      The call stack deepens and deepens and deepens until the program crashes.

      This is what you will see repeated endlessly in the call stack:

      0  in QQuickGridLayoutBase::rearrange of qquicklinearlayout.cpp:485
      1  in QQuickLayout::geometryChanged of qquicklayout.cpp:814
      2  in QQuickItem::setImplicitSize of items/qquickitem.cpp:6926
      3  in QQuickGridLayoutBase::invalidate of qquicklinearlayout.cpp:398
      4  in QQuickGridLayoutBase::rearrange of qquicklinearlayout.cpp:488
      5  in QQuickLayout::geometryChanged of qquicklayout.cpp:814
      6  in QQuickItem::setImplicitSize of items/qquickitem.cpp:6926
      7  in QQuickGridLayoutBase::invalidate of qquicklinearlayout.cpp:398
      8  in QQuickGridLayoutBase::rearrange of qquicklinearlayout.cpp:488
      9  in QQuickLayout::geometryChanged of qquicklayout.cpp:814
      10 in QQuickItem::setImplicitSize of items/qquickitem.cpp:6926
      11 in QQuickGridLayoutBase::invalidate of qquicklinearlayout.cpp:398
      12 in QQuickGridLayoutBase::rearrange of qquicklinearlayout.cpp:488
      13 in QQuickLayout::geometryChanged of qquicklayout.cpp:814
      14 in QQuickItem::setImplicitSize of items/qquickitem.cpp:6926
      15 in QQuickGridLayoutBase::invalidate of qquicklinearlayout.cpp:398
      16 in QQuickGridLayoutBase::rearrange of qquicklinearlayout.cpp:488
      76 in QQuickGridLayoutBase::rearrange of qquicklinearlayout.cpp:488
      77 in QQuickLayout::geometryChanged of qquicklayout.cpp:814
      78 in QQuickItem::setWidth of items/qquickitem.cpp:6661
      79 in QQuickAnchorsPrivate::setItemWidth of items/qquickanchors.cpp:407
      80 in QQuickAnchorsPrivate::updateHorizontalAnchors of items/qquickanchors.cpp:757
      81 in QQuickAnchorsPrivate::itemGeometryChanged of items/qquickanchors.cpp:506
      82 in QQuickItem::geometryChanged of items/qquickitem.cpp:3798
      83 in QQuickItem::setSize of items/qquickitem.cpp:6982
      84 in QQuickAnchorsPrivate::setItemSize of items/qquickanchors.cpp:435
      85 in QQuickAnchorsPrivate::fillChanged of items/qquickanchors.cpp:212
      86 in QQuickAnchorsPrivate::update of items/qquickanchors.cpp:484
      87 in QQuickAnchorsPrivate::updateOnComplete of items/qquickanchors.cpp:474
      88 in QQuickItem::componentComplete of items/qquickitem.cpp:5054
      89 in QQuickBasePositioner::componentComplete of items/qquickpositioners.cpp:259
      90 in QQmlObjectCreator::finalize of qml/qqmlobjectcreator.cpp:1364
      91 in QQmlComponentPrivate::complete of qml/qqmlcomponent.cpp:923
      92 in QQmlComponentPrivate::completeCreate of qml/qqmlcomponent.cpp:959
      93 in QQmlComponent::completeCreate of qml/qqmlcomponent.cpp:951
      94 in QQmlComponent::create of qml/qqmlcomponent.cpp:785
      95 in main of main.cpp:620

      This bug is similar to QTBUG-40220, but in my case there is no "polish loop warning."  In my case there is no warning shown at all.

      The call stack shown above is essentially the same as in (already closed ticket) QTBUG-55051, but in QTBUG-55051 the user did not manage to provide a minimal reproducible example.

      The qml code that I list above might not be idiomatic or ideal.  However, a framework that exists to parse and render scripts and/or markup should not segfault when doing so, no matter how "bad" the scripts/markup are.  This would be like crashing a C++ compiler when you write incorrect C++, or crashing a python interpreter when you write unpythonic python.  (This paragraph was added because in other QTBUG tickets I have seen framework issues being apparently minimized by pointing out that someone wrote "poor" or "incorrect" qml.  I hope a crash will not be minimized, even if my qml is poor.)

      Having said that, I will glady accept advice on how to rewrite the above qml to avoid to the segfault!  (Thanks in advance.)

      I also hope the segfault can be fixed, even if only by replacing it with some output to stderr and a refusal to render the offending element(s).

      My knowledge of Qt Layout internals is too vague for me to offer a patch at this time.  However, I might try my hand at adding some test coverage in this area. (Tips toward that end appreciated!)






          Issue Links

          No reviews matched the request. Check your Options in the drop-down menu of this sections header.



              smd Jan Arve
              pestophagous Kelly Heller
              3 Vote for this issue
              7 Start watching this issue



                  Gerrit Reviews