Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. Crash when reading a loader status

Crash when reading a loader status

Scheduled Pinned Locked Moved Solved QML and Qt Quick
4 Posts 2 Posters 866 Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • SeDiS Offline
    SeDiS Offline
    SeDi
    wrote on last edited by SeDi
    #1

    Hi,
    I am having crashs at a part of code, where I'd not expect them to be possible - when reading from an existing property of an existing QML object.

    This is not a startup issue, it occurs when using the app, so the Loader must be constructed (not necessarily the loaderItem, of course).
    I have been working with m_choiceOfFour quite a bit before the crash, so that seems to be perfectly valid. The problem seems to be load-related. It occurs more frequently on mobile than on desktop. It occurs more frequently when switching some costly animations on.

    How can this crash occur? I wouldn't think it could.
    I seem to either lack understanding of a basic conceptual thing here or stare upon an obvious error that I just don't see.

    This is the c++ code where the crash happens:

        auto loader0 = qvariant_cast<QQuickItem*>(m_choiceOfFour->property("eq0Loader"));
        auto loader1 = qvariant_cast<QQuickItem*>(m_choiceOfFour->property("eq1Loader"));
        //... 
    
        qDebug()<<"loaders: ";
        qDebug()<<"loader0: "<<loader0;
        if (loader0) {
            qDebug()<<loader0->property("status");   // <- crash happens here 
        }
        qDebug()<<"loader1: "<<loader1;
        if (loader1) {
            qDebug()<<loader1->property("status");   // <- or here 
        }
        //... 
    

    The Loaders belong to several Buttons in a qml file ChoiceOfFour.qml:

    Column {
        id: choiceColumn
        objectName: "choiceOfFour"
    
        property var eq0Loader:  button0.loader 
        property var eq1Loader:  button1.loader
        //...
    
        ChoiceButton {
            id: button0
            //...
        }
        ChoiceButton {
            id: button1
    /…
    

    Each ChoiceButton.qml contains a loader:

    Button {
        id: button
        property alias loader: eqLoader
        visible: eqLoader.sourceComponent !== null
        //...
        Loader {
            asynchronous: false
            id: eqLoader
            onVisibleChanged: {
                if (!visible) {
                    sourceComponent = null
                }
            }
        }
    }
    

    A typical stacktrace would be:

    1   QQmlComponent::status                  qqmlcomponent.cpp      417  0xf16e6ea  
    2   QQuickLoader::status                   qquickloader.cpp       798  0x1a9e8fa2 
    3   QQuickLoader::qt_static_metacall       moc_qquickloader_p.cpp 247  0x1a9eaf15 
    4   QQuickLoader::qt_metacall              moc_qquickloader_p.cpp 310  0x1a9eb05a 
    5   QMetaObject::metacall                  qmetaobject.cpp        301  0x6bafe04d 
    6   QMetaProperty::read                    qmetaobject.cpp        3105 0x6bb045a2 
    7   QObject::property                      qobject.cpp            3952 0x6bb1b2bc 
    8   QmlGenerator::createFourChoices        qmlgenerator.cpp       412  0x40f510  <---- my file  
    9   Controller::displayOneMoreStep         controller.cpp         88   0x411a1b   <---- my file
    10  Controller::qt_static_metacall         moc_controller.cpp     178  0x41d2dc   <---- (my file)
    11  QMetaObject::activate                  qobject.cpp            3771 0x6bb1bfc9 
    12  QMetaObject::activate                  qobject.cpp            3633 0x6bb1c25d 
    13  QSingleShotTimer::timeout              qtimer.moc             125  0x6bb2484b 
    14  QSingleShotTimer::timerEvent           qtimer.cpp             321  0x6bb2496a 
    15  QObject::event                         qobject.cpp            1232 0x6bb1c600 
    16  QCoreApplicationPrivate::notify_helper qcoreapplication.cpp   1197 0x6baf4cfb 
    17  doNotify                               qcoreapplication.cpp   1138 0x6baf4d71 
    18  QCoreApplication::notify               qcoreapplication.cpp   1124 0x6baf4eaf 
    19  QGuiApplication::notify                qguiapplication.cpp    1770 0x17d67ec  
    20  QCoreApplication::notifyInternal2      qcoreapplication.cpp   1048 0x6baf4e01 
    ... <More>                                                                        
    

    The actual crash being in QQmlComponent::status:

            417 [1]	in qml\qqmlcomponent.cpp
    0xf16e6ea  <+0x000c>        8b 4a 08        mov    0x8(%edx),%ecx
    0xf16e6ed  <+0x000f>        39 4a 0c        cmp    %ecx,0xc(%edx)
    0xf16e6f0  <+0x0012>        75 2f           jne    0xf16e721 <QQmlComponent::status() const+67>
    

    Any ideas?

    J.HilkJ 1 Reply Last reply
    0
    • SeDiS SeDi

      Hi,
      I am having crashs at a part of code, where I'd not expect them to be possible - when reading from an existing property of an existing QML object.

      This is not a startup issue, it occurs when using the app, so the Loader must be constructed (not necessarily the loaderItem, of course).
      I have been working with m_choiceOfFour quite a bit before the crash, so that seems to be perfectly valid. The problem seems to be load-related. It occurs more frequently on mobile than on desktop. It occurs more frequently when switching some costly animations on.

      How can this crash occur? I wouldn't think it could.
      I seem to either lack understanding of a basic conceptual thing here or stare upon an obvious error that I just don't see.

      This is the c++ code where the crash happens:

          auto loader0 = qvariant_cast<QQuickItem*>(m_choiceOfFour->property("eq0Loader"));
          auto loader1 = qvariant_cast<QQuickItem*>(m_choiceOfFour->property("eq1Loader"));
          //... 
      
          qDebug()<<"loaders: ";
          qDebug()<<"loader0: "<<loader0;
          if (loader0) {
              qDebug()<<loader0->property("status");   // <- crash happens here 
          }
          qDebug()<<"loader1: "<<loader1;
          if (loader1) {
              qDebug()<<loader1->property("status");   // <- or here 
          }
          //... 
      

      The Loaders belong to several Buttons in a qml file ChoiceOfFour.qml:

      Column {
          id: choiceColumn
          objectName: "choiceOfFour"
      
          property var eq0Loader:  button0.loader 
          property var eq1Loader:  button1.loader
          //...
      
          ChoiceButton {
              id: button0
              //...
          }
          ChoiceButton {
              id: button1
      /…
      

      Each ChoiceButton.qml contains a loader:

      Button {
          id: button
          property alias loader: eqLoader
          visible: eqLoader.sourceComponent !== null
          //...
          Loader {
              asynchronous: false
              id: eqLoader
              onVisibleChanged: {
                  if (!visible) {
                      sourceComponent = null
                  }
              }
          }
      }
      

      A typical stacktrace would be:

      1   QQmlComponent::status                  qqmlcomponent.cpp      417  0xf16e6ea  
      2   QQuickLoader::status                   qquickloader.cpp       798  0x1a9e8fa2 
      3   QQuickLoader::qt_static_metacall       moc_qquickloader_p.cpp 247  0x1a9eaf15 
      4   QQuickLoader::qt_metacall              moc_qquickloader_p.cpp 310  0x1a9eb05a 
      5   QMetaObject::metacall                  qmetaobject.cpp        301  0x6bafe04d 
      6   QMetaProperty::read                    qmetaobject.cpp        3105 0x6bb045a2 
      7   QObject::property                      qobject.cpp            3952 0x6bb1b2bc 
      8   QmlGenerator::createFourChoices        qmlgenerator.cpp       412  0x40f510  <---- my file  
      9   Controller::displayOneMoreStep         controller.cpp         88   0x411a1b   <---- my file
      10  Controller::qt_static_metacall         moc_controller.cpp     178  0x41d2dc   <---- (my file)
      11  QMetaObject::activate                  qobject.cpp            3771 0x6bb1bfc9 
      12  QMetaObject::activate                  qobject.cpp            3633 0x6bb1c25d 
      13  QSingleShotTimer::timeout              qtimer.moc             125  0x6bb2484b 
      14  QSingleShotTimer::timerEvent           qtimer.cpp             321  0x6bb2496a 
      15  QObject::event                         qobject.cpp            1232 0x6bb1c600 
      16  QCoreApplicationPrivate::notify_helper qcoreapplication.cpp   1197 0x6baf4cfb 
      17  doNotify                               qcoreapplication.cpp   1138 0x6baf4d71 
      18  QCoreApplication::notify               qcoreapplication.cpp   1124 0x6baf4eaf 
      19  QGuiApplication::notify                qguiapplication.cpp    1770 0x17d67ec  
      20  QCoreApplication::notifyInternal2      qcoreapplication.cpp   1048 0x6baf4e01 
      ... <More>                                                                        
      

      The actual crash being in QQmlComponent::status:

              417 [1]	in qml\qqmlcomponent.cpp
      0xf16e6ea  <+0x000c>        8b 4a 08        mov    0x8(%edx),%ecx
      0xf16e6ed  <+0x000f>        39 4a 0c        cmp    %ecx,0xc(%edx)
      0xf16e6f0  <+0x0012>        75 2f           jne    0xf16e721 <QQmlComponent::status() const+67>
      

      Any ideas?

      J.HilkJ Offline
      J.HilkJ Offline
      J.Hilk
      Moderators
      wrote on last edited by
      #2

      @SeDi
      QML and it's inner workings are not really my forte.

      But I know that your standart QML pages do not guarantee the existance of the objects for the whole duration of the app existance.

      So my guess is, your page/file gets unloaded or the gc frees the memory and your cpp side does not get notfied of this change. This than makes the pointer you (potentially !?) store invalid and your program crashes.


      Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


      Q: What's that?
      A: It's blue light.
      Q: What does it do?
      A: It turns blue.

      SeDiS 2 Replies Last reply
      2
      • J.HilkJ J.Hilk

        @SeDi
        QML and it's inner workings are not really my forte.

        But I know that your standart QML pages do not guarantee the existance of the objects for the whole duration of the app existance.

        So my guess is, your page/file gets unloaded or the gc frees the memory and your cpp side does not get notfied of this change. This than makes the pointer you (potentially !?) store invalid and your program crashes.

        SeDiS Offline
        SeDiS Offline
        SeDi
        wrote on last edited by
        #3

        @J.Hilk Thank you for your answer! I would understand that, if I'd have ChoiceOfFour.qml or ChoiceButton.qml in a loader or if I'd close a Dialog where they live in. But ChoiceOfFour.qml lives in the ApplicationWindow and is never tampered with. The four ChoiceButtons (containing the loaders) live inside it and are also not tampered with, other than being set invisible at times. I just don't see any garbage collection wanting to clean them up. On the other hand, I am filling those loaders with complex components (constructed in c++), where I carefully set ownership to JavaScript on each component:

            QQmlComponent* component = new QQmlComponent(m_engine, QUrl(QStringLiteral("qrc:/ElementVariable.qml")));
            m_engine->setObjectOwnership(component, QQmlEngine::JavaScriptOwnership);
        
            loader->setProperty("sourceComponent", QVariant::fromValue<QQmlComponent*>(component));
            QQuickItem* loaderItem = qvariant_cast<QQuickItem*>(loader->property("item"));
            loaderItem->setProperty("text", v->name());
            m_engine->setObjectOwnership(loaderItem, QQmlEngine::JavaScriptOwnership);
        

        I don't see, where this could be causing a crash on reading(!) a property of the loader itself, though.

        1 Reply Last reply
        0
        • J.HilkJ J.Hilk

          @SeDi
          QML and it's inner workings are not really my forte.

          But I know that your standart QML pages do not guarantee the existance of the objects for the whole duration of the app existance.

          So my guess is, your page/file gets unloaded or the gc frees the memory and your cpp side does not get notfied of this change. This than makes the pointer you (potentially !?) store invalid and your program crashes.

          SeDiS Offline
          SeDiS Offline
          SeDi
          wrote on last edited by SeDi
          #4

          @J.Hilk You have been right after all. What first seemed to be a problem with animation has definitely been a problem of JavaScript deleting objects it shouldn't, at times where I'd not expected it to. I've since taken ownership of almost all objects to cpp and carefully check which one I have to ->deleteLater(). The bug is gone. Thank you!

          1 Reply Last reply
          1

          • Login

          • Login or register to search.
          • First post
            Last post
          0
          • Categories
          • Recent
          • Tags
          • Popular
          • Users
          • Groups
          • Search
          • Get Qt Extensions
          • Unsolved