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 loading a QML for the second time
Forum Updated to NodeBB v4.3 + New Features

Crash when loading a QML for the second time

Scheduled Pinned Locked Moved Unsolved QML and Qt Quick
4 Posts 2 Posters 552 Views 1 Watching
  • 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.
  • O Offline
    O Offline
    occam25
    wrote on last edited by occam25
    #1

    Hi,
    I'm building a Qt application (Qt 5.15) and, in one dialog, I create a popup QML window to enter a wifi key. The first time it works as expected but, when I close the popup and click again in a SSID from the list to open it again, the application crashes with the warning:

    QQmlEngine::setContextForObject(): Object already has a QQmlContext

    It only crashes on Linux, on Windows it doesn't.

    This is the constructor of the dialog that loads the QML:

    WifiEnterKeyDialog::WifiEnterKeyDialog(QWidget *parent, QString ssid) :
        QDialog(parent),
        ui(new Ui::WifiEnterKeyDialog),
        ssid(ssid)
    {
        WifiEnterKeyDialog::parent = parent;
        ui->setupUi(this);
        this->setStyleSheet("background-color: white;");
        this->resize(850,420);
    
        this->setWindowFlag(Qt::FramelessWindowHint, true);
        this->setModal(true);
        this->setAttribute(Qt::WA_DeleteOnClose, true);
    
        // Ensure the previous QQuickWidget is properly cleaned up
        if (qw_keyboard) {
            qw_keyboard->rootContext()->setContextObject(nullptr);
            delete qw_keyboard;
        }
    
        qw_keyboard = new QQuickWidget(this);
    //    qw_keyboard->rootContext()->setContextObject(nullptr);
        qw_keyboard->setResizeMode(QQuickWidget::SizeRootObjectToView);
    //    qw_keyboard->rootContext()->engine()->clearComponentCache();
        qw_keyboard->rootContext()->setContextProperty("classEnterKeyDialog", this);
        qw_keyboard->setSource(QUrl(QStringLiteral("qrc:/inputkey2.qml")));
        qw_keyboard->setGeometry(0, 0, 850, 420);
    
    }
    

    This is how I create the dialog:

    void WifiDialog::onLwNetworkSelected(QListWidgetItem *current)
    {
        qDebug() << "SSID: " << current->text();
        wifi_enter_key = new WifiEnterKeyDialog(this, current->text());
        wifi_enter_key->show();
    }
    

    And this is the qml file:

    import QtQuick 2.15
    import QtQuick.VirtualKeyboard 1.0
    import QtQuick.Controls 2.15
    import QtQuick.Layouts 1.3
    
    Rectangle {
        id: rect
    
    
        ColumnLayout {
            id: columnLayout
            width: rect.width
    
            Button {
                id: exit_button
                Layout.alignment: Qt.AlignRight
                Layout.rightMargin: 3
                Layout.topMargin: 3
                Layout.minimumHeight: 10
                Layout.minimumWidth: 10
                icon.source: "qrc:/Resources/xmark-solid.png"
                background: Rectangle {color: "white"}
                onClicked: {
                    wifiKey.text = ""
                    classEnterKeyDialog.closeDialog()
                }
            }
    
            TextField {
                id: wifiKey
                Layout.alignment: Qt.AlignHCenter
                Layout.fillWidth: parent
                Layout.minimumHeight: 40
                Layout.leftMargin: 70
                Layout.rightMargin: 70
                placeholderText: qsTr("Introducir contraseña")
    
                font.family: "Roboto"
                font.pointSize: 20
                horizontalAlignment: Text.AlignHCenter
                verticalAlignment: Text.AlignVCenter
    
                background: Rectangle {
                    color: "white"
                    border.color: "black"
                }
    
                onTextChanged: {
                    classEnterKeyDialog.setKey(text);
                }
            }
    
            Button {
                id: connect_button
                Layout.alignment: Qt.AlignHCenter
                Layout.fillWidth: parent
                Layout.minimumHeight: 40
                Layout.leftMargin: 70
                Layout.rightMargin: 70
                Layout.topMargin: 00
                Layout.bottomMargin: 0
    
                contentItem: Text {
                    text: qsTr("Conectar")
                    font.family: "Roboto"
                    font.pointSize: 20
                    horizontalAlignment: Text.AlignHCenter
                    verticalAlignment: Text.AlignVCenter
                    elide: Text.ElideRight
                }
                background: Rectangle {color: "#8EC31B"}
                onClicked: {
                    classEnterKeyDialog.connect()
                    wifiKey.text = ""
                }
            }
    
            Label {
                id: dummyLabel
                Layout.alignment: Qt.AlignHCenter
                Layout.fillWidth: parent
                Layout.minimumHeight: 2480
                Layout.topMargin: 20
                background: Rectangle {
                    color: "red"
                }
            }
        }
    
        InputPanel {
            id: inputPanel
            y: Qt.inputMethod.visible ? parent.height - inputPanel.height : parent.height
            anchors.left: parent.left
            anchors.right: parent.right
        }
    }
    

    I don't understand what is happening and I haven't found any solution. I've tried to call to clearComponentCache() before set the contex property but the crash is still happening (only in Linux)

    I've been stuck with this several days. Any help will be appreciated!

    Thanks

    jeremy_kJ 1 Reply Last reply
    0
    • O occam25

      Hi,
      I'm building a Qt application (Qt 5.15) and, in one dialog, I create a popup QML window to enter a wifi key. The first time it works as expected but, when I close the popup and click again in a SSID from the list to open it again, the application crashes with the warning:

      QQmlEngine::setContextForObject(): Object already has a QQmlContext

      It only crashes on Linux, on Windows it doesn't.

      This is the constructor of the dialog that loads the QML:

      WifiEnterKeyDialog::WifiEnterKeyDialog(QWidget *parent, QString ssid) :
          QDialog(parent),
          ui(new Ui::WifiEnterKeyDialog),
          ssid(ssid)
      {
          WifiEnterKeyDialog::parent = parent;
          ui->setupUi(this);
          this->setStyleSheet("background-color: white;");
          this->resize(850,420);
      
          this->setWindowFlag(Qt::FramelessWindowHint, true);
          this->setModal(true);
          this->setAttribute(Qt::WA_DeleteOnClose, true);
      
          // Ensure the previous QQuickWidget is properly cleaned up
          if (qw_keyboard) {
              qw_keyboard->rootContext()->setContextObject(nullptr);
              delete qw_keyboard;
          }
      
          qw_keyboard = new QQuickWidget(this);
      //    qw_keyboard->rootContext()->setContextObject(nullptr);
          qw_keyboard->setResizeMode(QQuickWidget::SizeRootObjectToView);
      //    qw_keyboard->rootContext()->engine()->clearComponentCache();
          qw_keyboard->rootContext()->setContextProperty("classEnterKeyDialog", this);
          qw_keyboard->setSource(QUrl(QStringLiteral("qrc:/inputkey2.qml")));
          qw_keyboard->setGeometry(0, 0, 850, 420);
      
      }
      

      This is how I create the dialog:

      void WifiDialog::onLwNetworkSelected(QListWidgetItem *current)
      {
          qDebug() << "SSID: " << current->text();
          wifi_enter_key = new WifiEnterKeyDialog(this, current->text());
          wifi_enter_key->show();
      }
      

      And this is the qml file:

      import QtQuick 2.15
      import QtQuick.VirtualKeyboard 1.0
      import QtQuick.Controls 2.15
      import QtQuick.Layouts 1.3
      
      Rectangle {
          id: rect
      
      
          ColumnLayout {
              id: columnLayout
              width: rect.width
      
              Button {
                  id: exit_button
                  Layout.alignment: Qt.AlignRight
                  Layout.rightMargin: 3
                  Layout.topMargin: 3
                  Layout.minimumHeight: 10
                  Layout.minimumWidth: 10
                  icon.source: "qrc:/Resources/xmark-solid.png"
                  background: Rectangle {color: "white"}
                  onClicked: {
                      wifiKey.text = ""
                      classEnterKeyDialog.closeDialog()
                  }
              }
      
              TextField {
                  id: wifiKey
                  Layout.alignment: Qt.AlignHCenter
                  Layout.fillWidth: parent
                  Layout.minimumHeight: 40
                  Layout.leftMargin: 70
                  Layout.rightMargin: 70
                  placeholderText: qsTr("Introducir contraseña")
      
                  font.family: "Roboto"
                  font.pointSize: 20
                  horizontalAlignment: Text.AlignHCenter
                  verticalAlignment: Text.AlignVCenter
      
                  background: Rectangle {
                      color: "white"
                      border.color: "black"
                  }
      
                  onTextChanged: {
                      classEnterKeyDialog.setKey(text);
                  }
              }
      
              Button {
                  id: connect_button
                  Layout.alignment: Qt.AlignHCenter
                  Layout.fillWidth: parent
                  Layout.minimumHeight: 40
                  Layout.leftMargin: 70
                  Layout.rightMargin: 70
                  Layout.topMargin: 00
                  Layout.bottomMargin: 0
      
                  contentItem: Text {
                      text: qsTr("Conectar")
                      font.family: "Roboto"
                      font.pointSize: 20
                      horizontalAlignment: Text.AlignHCenter
                      verticalAlignment: Text.AlignVCenter
                      elide: Text.ElideRight
                  }
                  background: Rectangle {color: "#8EC31B"}
                  onClicked: {
                      classEnterKeyDialog.connect()
                      wifiKey.text = ""
                  }
              }
      
              Label {
                  id: dummyLabel
                  Layout.alignment: Qt.AlignHCenter
                  Layout.fillWidth: parent
                  Layout.minimumHeight: 2480
                  Layout.topMargin: 20
                  background: Rectangle {
                      color: "red"
                  }
              }
          }
      
          InputPanel {
              id: inputPanel
              y: Qt.inputMethod.visible ? parent.height - inputPanel.height : parent.height
              anchors.left: parent.left
              anchors.right: parent.right
          }
      }
      

      I don't understand what is happening and I haven't found any solution. I've tried to call to clearComponentCache() before set the contex property but the crash is still happening (only in Linux)

      I've been stuck with this several days. Any help will be appreciated!

      Thanks

      jeremy_kJ Offline
      jeremy_kJ Offline
      jeremy_k
      wrote on last edited by
      #2

      @occam25 said in Crash when loading a QML for the second time:

      Hi,

      Hi,

      I'm going to first of all propose what your namesake's (I'm presuming) legacy suggests: Remove everything unnecessary, ie not involved in triggering the problem. Whatever remains is probably responsible. If not, at least it reduces the size of the hay stack.

      I'm building a Qt application (Qt 5.15) and, in one dialog, I create a popup QML window to enter a wifi key. The first time it works as expected but, when I close the popup and click again in a SSID from the list to open it again, the application crashes with the warning:

      Have you tried running under a debugger, or examining a resulting core dump?

      This is the constructor of the dialog that loads the QML:

      WifiEnterKeyDialog::WifiEnterKeyDialog(QWidget *parent, QString ssid) :
          QDialog(parent),
          ui(new Ui::WifiEnterKeyDialog),
          ssid(ssid)
      {
      

      [...]

      // Ensure the previous QQuickWidget is properly cleaned up
      if (qw_keyboard) {
      

      Is qw_keyboard a member variable, global or thread_local, or something else? Is it explicitly initialized to nullptr or something else evaluating to false?

      This is how I create the dialog:

      void WifiDialog::onLwNetworkSelected(QListWidgetItem *current)
      {
          qDebug() << "SSID: " << current->text();
      

      An example of excess: for the sake of the razor, please trim the debug output and commented-out statements for forum use. Unless used in triggering the crash or discussion of the output, it's more overhead to read.

      And this is the qml file:

      More razor feed. If it's not important, cut it. Maybe some of this is important. I stopped reading when it got into margin sizing.

      I don't understand what is happening and I haven't found any solution. I've tried to call to clearComponentCache() before set the contex property but the crash is still happening (only in Linux)

      On one hand, congratulations on having a theory. Many people give up at "it doesn't work". On the other, why was this theory chosen? The component cache belongs to the QML engine. The QQuickWidget isn't being passed an engine, meaning that it creates its own. Similarly with the context property, each engine has it's own root.

      I've been stuck with this several days. Any help will be appreciated!

      Hopefully I'm coming across as direct rather than harsh. You've identified a problem, and done some work to isolate it. That's a big step. Let's refine it to a point.

      Asking a question about code? http://eel.is/iso-c++/testcase/

      O 1 Reply Last reply
      0
      • jeremy_kJ jeremy_k

        @occam25 said in Crash when loading a QML for the second time:

        Hi,

        Hi,

        I'm going to first of all propose what your namesake's (I'm presuming) legacy suggests: Remove everything unnecessary, ie not involved in triggering the problem. Whatever remains is probably responsible. If not, at least it reduces the size of the hay stack.

        I'm building a Qt application (Qt 5.15) and, in one dialog, I create a popup QML window to enter a wifi key. The first time it works as expected but, when I close the popup and click again in a SSID from the list to open it again, the application crashes with the warning:

        Have you tried running under a debugger, or examining a resulting core dump?

        This is the constructor of the dialog that loads the QML:

        WifiEnterKeyDialog::WifiEnterKeyDialog(QWidget *parent, QString ssid) :
            QDialog(parent),
            ui(new Ui::WifiEnterKeyDialog),
            ssid(ssid)
        {
        

        [...]

        // Ensure the previous QQuickWidget is properly cleaned up
        if (qw_keyboard) {
        

        Is qw_keyboard a member variable, global or thread_local, or something else? Is it explicitly initialized to nullptr or something else evaluating to false?

        This is how I create the dialog:

        void WifiDialog::onLwNetworkSelected(QListWidgetItem *current)
        {
            qDebug() << "SSID: " << current->text();
        

        An example of excess: for the sake of the razor, please trim the debug output and commented-out statements for forum use. Unless used in triggering the crash or discussion of the output, it's more overhead to read.

        And this is the qml file:

        More razor feed. If it's not important, cut it. Maybe some of this is important. I stopped reading when it got into margin sizing.

        I don't understand what is happening and I haven't found any solution. I've tried to call to clearComponentCache() before set the contex property but the crash is still happening (only in Linux)

        On one hand, congratulations on having a theory. Many people give up at "it doesn't work". On the other, why was this theory chosen? The component cache belongs to the QML engine. The QQuickWidget isn't being passed an engine, meaning that it creates its own. Similarly with the context property, each engine has it's own root.

        I've been stuck with this several days. Any help will be appreciated!

        Hopefully I'm coming across as direct rather than harsh. You've identified a problem, and done some work to isolate it. That's a big step. Let's refine it to a point.

        O Offline
        O Offline
        occam25
        wrote on last edited by
        #3

        @jeremy_k said in Crash when loading a QML for the second time:

        Have you tried running under a debugger, or examining a resulting core dump?

        I cross-compiled and run valgrind to try to find where the crash happens, this is the relevant output:

        ==934== Thread 1:
        ==934== Invalid read of size 8
        ==934==    at 0x5C8CC14: QJSValue QQmlEnginePrivate::singletonInstance<QJSValue>(QQmlType const&) (in /usr/lib/libQt5Qml.so.5.15.9)
        ==934==    by 0x5B8AC2B: QV4::QQmlContextWrapper::getPropertyAndBase(QV4::QQmlContextWrapper const*, QV4::PropertyKey, QV4::Value const*, bool*, QV4::Value*, QV4::Lookup*) (in /usr/lib/libQt5Qml.so.5.15.9)
        ==934==    by 0x5B8AF6F: QV4::QQmlContextWrapper::resolveQmlContextPropertyLookupGetter(QV4::Lookup*, QV4::ExecutionEngine*, QV4::Value*) (in /usr/lib/libQt5Qml.so.5.15.9)
        ==934==    by 0x5BCEF87: ??? (in /usr/lib/libQt5Qml.so.5.15.9)
        ==934==    by 0x5BD1E4B: ??? (in /usr/lib/libQt5Qml.so.5.15.9)
        ==934==    by 0x5B656F3: QV4::Function::call(QV4::Value const*, QV4::Value const*, int, QV4::ExecutionContext const*) (in /usr/lib/libQt5Qml.so.5.15.9)
        ==934==    by 0x5CFC0AB: QQmlJavaScriptExpression::evaluate(QV4::CallData*, bool*) (in /usr/lib/libQt5Qml.so.5.15.9)
        ==934==    by 0x5D03047: QQmlBinding::evaluate(bool*) (in /usr/lib/libQt5Qml.so.5.15.9)
        ==934==    by 0x5D070A3: ??? (in /usr/lib/libQt5Qml.so.5.15.9)
        ==934==    by 0x5D04F47: QQmlBinding::update(QFlags<QQmlPropertyData::WriteFlag>) (in /usr/lib/libQt5Qml.so.5.15.9)
        ==934==    by 0x5D12F93: QQmlObjectCreator::finalize(QQmlInstantiationInterrupt&) (in /usr/lib/libQt5Qml.so.5.15.9)
        ==934==    by 0x5C9B26F: QQmlComponentPrivate::complete(QQmlEnginePrivate*, QQmlComponentPrivate::ConstructionState*) (in /usr/lib/libQt5Qml.so.5.15.9)
        ==934==  Address 0xbaadad8 is 8 bytes inside a block of size 24 free'd
        ==934==    at 0x48688C8: operator delete(void*, unsigned long) (vg_replace_malloc.c:935)
        ==934==    by 0x5C8C5DB: QQmlEngine::~QQmlEngine() (in /usr/lib/libQt5Qml.so.5.15.9)
        ==934==    by 0x5C8C6D7: QQmlEngine::~QQmlEngine() (in /usr/lib/libQt5Qml.so.5.15.9)
        ==934==    by 0x6407D1B: QObjectPrivate::deleteChildren() (in /usr/lib/libQt5Core.so.5.15.9)
        ==934==    by 0x4ACD87B: QWidget::~QWidget() (in /usr/lib/libQt5Widgets.so.5.15.9)
        ==934==    by 0x48BA537: QQuickWidget::~QQuickWidget() (in /usr/lib/libQt5QuickWidgets.so.5.15.9)
        ==934==    by 0x1C692F: WifiEnterKeyDialog::~WifiEnterKeyDialog() (wifienterkeydialog.cpp:75)
        ==934==    by 0x1C6A57: WifiEnterKeyDialog::~WifiEnterKeyDialog() (wifienterkeydialog.cpp:78)
        ==934==    by 0x640A81F: QObject::event(QEvent*) (in /usr/lib/libQt5Core.so.5.15.9)
        ==934==    by 0x4A8C0EF: QApplicationPrivate::notify_helper(QObject*, QEvent*) (in /usr/lib/libQt5Widgets.so.5.15.9)
        ==934==    by 0x63D7B07: QCoreApplication::notifyInternal2(QObject*, QEvent*) (in /usr/lib/libQt5Core.so.5.15.9)
        ==934==    by 0x63DB12F: QCoreApplicationPrivate::sendPostedEvents(QObject*, int, QThreadData*) (in /usr/lib/libQt5Core.so.5.15.9)
        ==934==  Block was alloc'd at
        ==934==    at 0x4865CFC: operator new(unsigned long) (vg_replace_malloc.c:422)
        ==934==    by 0xBAC5D53: VirtualKeyboardInputContextPrivate::VirtualKeyboardInputContextPrivate() (in /usr/lib/plugins/platforminputcontexts/libVirtualKeyboard.so)
        ==934==    by 0xBAC6CBF: VirtualKeyboardInputContext::VirtualKeyboardInputContext() (in /usr/lib/plugins/platforminputcontexts/libVirtualKeyboard.so)
        ==934==    by 0xBAC6ECF: VirtualKeyboardInputContext::instance() (in /usr/lib/plugins/platforminputcontexts/libVirtualKeyboard.so)
        ==934==    by 0x5474A8B: QPlatformInputContextFactory::create(QString const&) (in /usr/lib/libQt5Gui.so.5.15.9)
        ==934==    by 0x5474D27: QPlatformInputContextFactory::create() (in /usr/lib/libQt5Gui.so.5.15.9)
        ==934==    by 0xB11AEFB: ??? (in /usr/lib/plugins/platforms/libqlinuxfb.so)
        ==934==    by 0x548A4AF: QGuiApplicationPrivate::eventDispatcherReady() (in /usr/lib/libQt5Gui.so.5.15.9)
        ==934==    by 0x63DF0FB: QCoreApplicationPrivate::init() (in /usr/lib/libQt5Core.so.5.15.9)
        ==934==    by 0x548D81B: QGuiApplicationPrivate::init() (in /usr/lib/libQt5Gui.so.5.15.9)
        ==934==    by 0x4A92047: QApplicationPrivate::init() (in /usr/lib/libQt5Widgets.so.5.15.9)
        ==934==    by 0x12DD0F: main (main.cpp:51)
        

        As you can see, when the WifiEnterKeyDialog is closed the first time, its destructor is called and the QQmlEngine is removed. Then, when the user selects a network again, a new WifiEnterKeyDialog is created and during the QML load/initialization, QQmlEnginePrivate is called and tries to access something that was previously deleted when the first WifiEnterKeyDialog instance was removed. Whatever wrong memory is accessed was allocated in the VirtualKeyboardInputContextPrivate constructor that is a free virtual keyboard implementation. Maybe there is a way to reload the virtualkeyboard to create the QQmlEngine again if it doesn’t exist anymore? I have very little experience with QML.

        Is qw_keyboard a member variable, global or thread_local, or something else? Is it explicitly initialized to nullptr or something else evaluating to false?

        It is a member variable initialized to NULL. This was added as part of the many things I tried to solve the issue, after looking at valgrind's output this is useless.

        An example of excess: for the sake of the razor, please trim the debug output and commented-out statements for forum use. Unless used in triggering the crash or discussion of the output, it's more overhead to read.

        And this is the qml file:

        More razor feed. If it's not important, cut it. Maybe some of this is important. I stopped reading when it got into margin sizing.

        Fair enough. I actually removed many other comments but missed that one. About the qml file.. since I'm new to QML I was unsure what parts were relevant or not, but I will take this into account in future post, I promise!

        On one hand, congratulations on having a theory. Many people give up at "it doesn't work". On the other, why was this theory chosen? The component cache belongs to the QML engine. The QQuickWidget isn't being passed an engine, meaning that it creates its own. Similarly with the context property, each engine has it's own root.

        I saw that the crash was happening when setting the qml source so I thought that it was related with having something fishy in the QML engine, that's why I tried to clean it.

        Hopefully I'm coming across as direct rather than harsh. You've identified a problem, and done some work to isolate it. That's a big step. Let's refine it to a point.

        I appreciate the direct approach! I'm new to Qt/QML and to this forum so, any input about how to do the things right is welcome.

        Thanks for the help

        jeremy_kJ 1 Reply Last reply
        0
        • O occam25

          @jeremy_k said in Crash when loading a QML for the second time:

          Have you tried running under a debugger, or examining a resulting core dump?

          I cross-compiled and run valgrind to try to find where the crash happens, this is the relevant output:

          ==934== Thread 1:
          ==934== Invalid read of size 8
          ==934==    at 0x5C8CC14: QJSValue QQmlEnginePrivate::singletonInstance<QJSValue>(QQmlType const&) (in /usr/lib/libQt5Qml.so.5.15.9)
          ==934==    by 0x5B8AC2B: QV4::QQmlContextWrapper::getPropertyAndBase(QV4::QQmlContextWrapper const*, QV4::PropertyKey, QV4::Value const*, bool*, QV4::Value*, QV4::Lookup*) (in /usr/lib/libQt5Qml.so.5.15.9)
          ==934==    by 0x5B8AF6F: QV4::QQmlContextWrapper::resolveQmlContextPropertyLookupGetter(QV4::Lookup*, QV4::ExecutionEngine*, QV4::Value*) (in /usr/lib/libQt5Qml.so.5.15.9)
          ==934==    by 0x5BCEF87: ??? (in /usr/lib/libQt5Qml.so.5.15.9)
          ==934==    by 0x5BD1E4B: ??? (in /usr/lib/libQt5Qml.so.5.15.9)
          ==934==    by 0x5B656F3: QV4::Function::call(QV4::Value const*, QV4::Value const*, int, QV4::ExecutionContext const*) (in /usr/lib/libQt5Qml.so.5.15.9)
          ==934==    by 0x5CFC0AB: QQmlJavaScriptExpression::evaluate(QV4::CallData*, bool*) (in /usr/lib/libQt5Qml.so.5.15.9)
          ==934==    by 0x5D03047: QQmlBinding::evaluate(bool*) (in /usr/lib/libQt5Qml.so.5.15.9)
          ==934==    by 0x5D070A3: ??? (in /usr/lib/libQt5Qml.so.5.15.9)
          ==934==    by 0x5D04F47: QQmlBinding::update(QFlags<QQmlPropertyData::WriteFlag>) (in /usr/lib/libQt5Qml.so.5.15.9)
          ==934==    by 0x5D12F93: QQmlObjectCreator::finalize(QQmlInstantiationInterrupt&) (in /usr/lib/libQt5Qml.so.5.15.9)
          ==934==    by 0x5C9B26F: QQmlComponentPrivate::complete(QQmlEnginePrivate*, QQmlComponentPrivate::ConstructionState*) (in /usr/lib/libQt5Qml.so.5.15.9)
          ==934==  Address 0xbaadad8 is 8 bytes inside a block of size 24 free'd
          ==934==    at 0x48688C8: operator delete(void*, unsigned long) (vg_replace_malloc.c:935)
          ==934==    by 0x5C8C5DB: QQmlEngine::~QQmlEngine() (in /usr/lib/libQt5Qml.so.5.15.9)
          ==934==    by 0x5C8C6D7: QQmlEngine::~QQmlEngine() (in /usr/lib/libQt5Qml.so.5.15.9)
          ==934==    by 0x6407D1B: QObjectPrivate::deleteChildren() (in /usr/lib/libQt5Core.so.5.15.9)
          ==934==    by 0x4ACD87B: QWidget::~QWidget() (in /usr/lib/libQt5Widgets.so.5.15.9)
          ==934==    by 0x48BA537: QQuickWidget::~QQuickWidget() (in /usr/lib/libQt5QuickWidgets.so.5.15.9)
          ==934==    by 0x1C692F: WifiEnterKeyDialog::~WifiEnterKeyDialog() (wifienterkeydialog.cpp:75)
          ==934==    by 0x1C6A57: WifiEnterKeyDialog::~WifiEnterKeyDialog() (wifienterkeydialog.cpp:78)
          ==934==    by 0x640A81F: QObject::event(QEvent*) (in /usr/lib/libQt5Core.so.5.15.9)
          ==934==    by 0x4A8C0EF: QApplicationPrivate::notify_helper(QObject*, QEvent*) (in /usr/lib/libQt5Widgets.so.5.15.9)
          ==934==    by 0x63D7B07: QCoreApplication::notifyInternal2(QObject*, QEvent*) (in /usr/lib/libQt5Core.so.5.15.9)
          ==934==    by 0x63DB12F: QCoreApplicationPrivate::sendPostedEvents(QObject*, int, QThreadData*) (in /usr/lib/libQt5Core.so.5.15.9)
          ==934==  Block was alloc'd at
          ==934==    at 0x4865CFC: operator new(unsigned long) (vg_replace_malloc.c:422)
          ==934==    by 0xBAC5D53: VirtualKeyboardInputContextPrivate::VirtualKeyboardInputContextPrivate() (in /usr/lib/plugins/platforminputcontexts/libVirtualKeyboard.so)
          ==934==    by 0xBAC6CBF: VirtualKeyboardInputContext::VirtualKeyboardInputContext() (in /usr/lib/plugins/platforminputcontexts/libVirtualKeyboard.so)
          ==934==    by 0xBAC6ECF: VirtualKeyboardInputContext::instance() (in /usr/lib/plugins/platforminputcontexts/libVirtualKeyboard.so)
          ==934==    by 0x5474A8B: QPlatformInputContextFactory::create(QString const&) (in /usr/lib/libQt5Gui.so.5.15.9)
          ==934==    by 0x5474D27: QPlatformInputContextFactory::create() (in /usr/lib/libQt5Gui.so.5.15.9)
          ==934==    by 0xB11AEFB: ??? (in /usr/lib/plugins/platforms/libqlinuxfb.so)
          ==934==    by 0x548A4AF: QGuiApplicationPrivate::eventDispatcherReady() (in /usr/lib/libQt5Gui.so.5.15.9)
          ==934==    by 0x63DF0FB: QCoreApplicationPrivate::init() (in /usr/lib/libQt5Core.so.5.15.9)
          ==934==    by 0x548D81B: QGuiApplicationPrivate::init() (in /usr/lib/libQt5Gui.so.5.15.9)
          ==934==    by 0x4A92047: QApplicationPrivate::init() (in /usr/lib/libQt5Widgets.so.5.15.9)
          ==934==    by 0x12DD0F: main (main.cpp:51)
          

          As you can see, when the WifiEnterKeyDialog is closed the first time, its destructor is called and the QQmlEngine is removed. Then, when the user selects a network again, a new WifiEnterKeyDialog is created and during the QML load/initialization, QQmlEnginePrivate is called and tries to access something that was previously deleted when the first WifiEnterKeyDialog instance was removed. Whatever wrong memory is accessed was allocated in the VirtualKeyboardInputContextPrivate constructor that is a free virtual keyboard implementation. Maybe there is a way to reload the virtualkeyboard to create the QQmlEngine again if it doesn’t exist anymore? I have very little experience with QML.

          Is qw_keyboard a member variable, global or thread_local, or something else? Is it explicitly initialized to nullptr or something else evaluating to false?

          It is a member variable initialized to NULL. This was added as part of the many things I tried to solve the issue, after looking at valgrind's output this is useless.

          An example of excess: for the sake of the razor, please trim the debug output and commented-out statements for forum use. Unless used in triggering the crash or discussion of the output, it's more overhead to read.

          And this is the qml file:

          More razor feed. If it's not important, cut it. Maybe some of this is important. I stopped reading when it got into margin sizing.

          Fair enough. I actually removed many other comments but missed that one. About the qml file.. since I'm new to QML I was unsure what parts were relevant or not, but I will take this into account in future post, I promise!

          On one hand, congratulations on having a theory. Many people give up at "it doesn't work". On the other, why was this theory chosen? The component cache belongs to the QML engine. The QQuickWidget isn't being passed an engine, meaning that it creates its own. Similarly with the context property, each engine has it's own root.

          I saw that the crash was happening when setting the qml source so I thought that it was related with having something fishy in the QML engine, that's why I tried to clean it.

          Hopefully I'm coming across as direct rather than harsh. You've identified a problem, and done some work to isolate it. That's a big step. Let's refine it to a point.

          I appreciate the direct approach! I'm new to Qt/QML and to this forum so, any input about how to do the things right is welcome.

          Thanks for the help

          jeremy_kJ Offline
          jeremy_kJ Offline
          jeremy_k
          wrote on last edited by
          #4

          @occam25 said in Crash when loading a QML for the second time:

          @jeremy_k said in Crash when loading a QML for the second time:

          ==934== Thread 1:
          ==934== Invalid read of size 8
          ==934==    at 0x5C8CC14: QJSValue QQmlEnginePrivate::singletonInstance<QJSValue>(QQmlType const&) (in /usr/lib/libQt5Qml.so.5.15.9)
          
          Is there an attempt to share a singleton instance between multiple engines? For QObject singletons, the instance can be owned by the engine or externally.  Objects owned by the engine are deleted on engine destruction, which could lead to a similar crash. I'm not sure how QJSValue singleton ownership works.
          
          
          > As you can see, when the WifiEnterKeyDialog is closed the first time, its destructor is called and the QQmlEngine is removed. Then, when the user selects a network again, a new WifiEnterKeyDialog is created and during the QML load/initialization, QQmlEnginePrivate is called and tries to access something that was previously deleted when the first WifiEnterKeyDialog instance was removed. Whatever wrong memory is accessed was allocated in the VirtualKeyboardInputContextPrivate constructor that is a free virtual keyboard implementation. Maybe there is a way to reload the virtualkeyboard to create the QQmlEngine again if it doesn’t exist anymore? I have very little experience with QML.
          
          How is the first engine created? Is reusing it an option?
          
          You've already clarified the qw_keyboard confusion below, but that's the sort of thing I would be looking for. Are there any pointers to objects shared with the first qml engine instance that are not reinitialized when shared with the second.
          
          > 
          > > Is qw_keyboard a member variable, global or thread_local, or something else? Is it explicitly initialized to nullptr or something else evaluating to `false`?
          > 
          > It is a member variable initialized to NULL. This was added as part of the many things I tried to solve the issue, after looking at valgrind's output this is useless.
          > 
          > > An example of excess: for the sake of the razor, please trim the debug output and commented-out statements for forum use. Unless used in triggering the crash or discussion of the output, it's more overhead to read.
          > > 
          > > > And this is the qml file:
          > > 
          > > More razor feed. If it's not important, cut it. Maybe some of this is important. I stopped reading when it got into margin sizing.
          > 
          > Fair enough. I actually removed many other comments but missed that one. About the qml file.. since I'm new to QML I was unsure what parts were relevant or not, but I will take this into account in future post, I promise! 
          
          You might benefit from rebuilding a test interface from the ground up with nothing but a TextField and InputPanel.

          Asking a question about code? http://eel.is/iso-c++/testcase/

          1 Reply Last reply
          0

          • Login

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