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

Crash related to QProperty bindings

    XMLWordPrintable

Details

    • Windows
    • Windows

    Description

      Our application uses QProperty objects, which greately reduces the complexity of code compared to signal/slot approach. Unfortunately we ran into an issues when using them in a quite complex application. The following (crashing) snippet demonstrates our usage:

       

      class MyObject
      {
      public:
          virtual ~MyObject() = default;
          std::array<QProperty<QString>,2> a; // Note app does not crash when array contains only a single property (!??)
      };
      
      class MyObjectContainer : public MyObject
      {
      public:
          QProperty<int> count;
          std::vector<std::shared_ptr<MyObject>> lamellas;
          void add()
          {
              QScopedPropertyUpdateGroup g; // Commenting this line would produce slightly different crash.
              count = count + 1;
              lamellas.push_back(std::make_shared<MyObject>());
          }
      };
      
      QProperty<std::vector<std::shared_ptr<MyObject>>> objects;
      QProperty<bool> p;
      
      p.setBinding([&]() {
          // Dummy computation to demonstrate we work with related QProperties
          auto touch = [](MyObject& l) {
              for (auto &prop : l.a) {
                  Q_UNUSED(prop.value())
              }
          };    
          // Iterate through objects
          for (auto l : objects.value()) {        
              // If the object is a container, iterate through its children
              if (auto arr = std::dynamic_pointer_cast<MyObjectContainer>(l)) {
                  touch(*arr);
                  for (int i = 0; i < arr->count.value(); i++) {
                      auto l = arr->lamellas[i];
                      touch(*l);
                  }
              }
              else {
                  touch(*l);
              }
          }    
          // Dummy return
          return true;
      });
      
      auto object = std::make_shared<MyObject>();
      auto container = std::make_shared<MyObjectContainer>();
      
      objects = { object, container };
      
      // Following line crashes
      container->add();

      objects list represents a tree of objects in a real-life application, while property p can represent a value which is computed by traversing the tree.

      The crash is mysteriously dependent on the number of dependent QProperties in the binding of 'p'. If only few are dependent (size of MyObject::a is 1), the very last line does not crash. When it is 2 or more, app crashes in code related to the dynamic list of dependent QPropertyObserver classes.

      App crashes in both 6.7.3 and 6.9.0 versions.

      Few screenshots of "Q_UNREACHABLE was reached" below:

       

       

       

       

       

      Attachments

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

        Activity

          People

            fabiankosmale Fabian Kosmale
            jan.planer Jan Planer
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

              Created:
              Updated:

              Gerrit Reviews

                There are no open Gerrit changes