Crashing when using QJSValue call



  • I am getting crash within my javascript function quite frequently when i use invoke the QJSValue's call function.

    I have a thread that is running calling a QMetaObject invokeMethod as a QueueConnection rather than DirectConnection to ensure that the method will be called in the main ui thread. This method that is invoke will then subsequently trigger the QJSValue javascript function. The javascript function modifies some of the UI element within the QML. When there are no modification to the UI elements, i notice that there is no crash.

    Is there any gotcha that i should take note of?

    Running on debug versions of QT getting crashes here

    https://code.woboq.org/qt5/qtdeclarative/src/qml/jsruntime/qv4scopedvalue_p.h.html#122

    Something is trashing the stack?



  • This post is deleted!

  • Lifetime Qt Champion

    Hi,

    You should share the code you use. From your description, it seems you are doing something pretty unusual.



  • This is a modified code from Chapter 6-plugins

    PieChartWorker class

    PieChartWorker::PieChartWorker(QObject *parent):
        QThread(parent)
    {
    }
    
    void PieChartWorker::run()
    {
        QString text;
        while(1) {
        QString textb = text.sprintf("The answer to the meaning of life is %i", std::rand()%100);
    
            QMetaObject::invokeMethod(this,
                                      "responseInternal",
                                      Qt::QueuedConnection,
                                      Q_ARG(QString, QString::fromLocal8Bit("hello")),
                    Q_ARG(QByteArray, textb.toLocal8Bit()));
            QThread::msleep(50);
        }
    }
    
    void PieChartWorker::responseInternal(const QString question, const QByteArray& answer)
    {
        if (callback.isCallable()) {
            QJSValueList args;
            args << question;
            args << QString::fromLocal8Bit(answer);
            callback.call(args);
        }
    }
    
    void PieChartWorker::registerCallback(const QJSValue callback)
    {
        this->callback = callback;
        start();
    }
    
    

    PieChart class

    PieChart::PieChart(QQuickItem *parent)
        : QQuickItem(parent)
    {
    
        PieChartWorker* worker = new PieChartWorker();
        worker->moveToThread(&m_thread);
    
        connect(&m_thread, &QThread::finished, worker, &QObject::deleteLater);
    
        connect(this, &PieChart::registerCallback, worker, &PieChartWorker::registerCallback);
        m_thread.start();
    }
    
    

    app.qml

    import QtQuick 2.0
    import Charts 1.0
    
    Item {
        width: 300; height: 200
        Text {
            id: label
            text: "hello"
            x:100; y:100
            color: 'black'
        }
        PieChart {
            anchors.centerIn: parent
            width: 100; height: 100
    
            Component.onCompleted: {
                registerCallback(updateResult)
            }
    
            function updateResult(question, answer) {
                console.log(question)
                console.log(answer)
                label.text = answer
            }
        }
    }
    
    

    I notice that the UI is also not updating in this simplified case.



  • WorkScript



  • I have made some additional changes, and the UI is updating, however it is crashing after about 12hrs running on a raspberry pi.

    1 ??
    2 QV4::Object::call qv4object_p.h 372 0x765d5a8c
    3 QJSValue::call qjsvalue.cpp 670 0x765d5a8c
    4 ?? 0x70352fb8

    Now the code emits a signal to be picked up by the main PieChart object which will trigger the JS script.

    void PieChartWorker::responseInternal(const QString question, const QByteArray& answer)
    {
    #if 1
        emit response(question, answer, callback);
    #else
        if (callback.isCallable()) {
            QJSValueList args;
            args << question;
            args << QString::fromLocal8Bit(answer);
            callback.call(args);
        }
    #endif
    }
    
    PieChart::PieChart(QQuickItem *parent)
        : QQuickItem(parent)
    {
    
        PieChartWorker* worker = new PieChartWorker();
        worker->moveToThread(&m_thread);
    
        connect(&m_thread, &QThread::finished, worker, &QObject::deleteLater);
    
        connect(this, &PieChart::registerCallback, worker, &PieChartWorker::registerCallback);
        connect(worker, &PieChartWorker::response, this, &PieChart::response);
        m_thread.start();
    }
    
    void PieChart::response(const QString question, const QByteArray& answer, QJSValue callback)
    {
        if (callback.isCallable()) {
            QJSValueList args;
            args << question;
            args << QString::fromLocal8Bit(answer);
            callback.call(args);
        }
    }
    
    

  • Lifetime Qt Champion

    Did you check whether your application has a leak ?



  • @SGaist said in Crashing when using QJSValue call:

    Did you check whether your application has a leak ?

    Yes, i have tested it for leaks. Does not seem to be the case.

    Is QJSValue.call to be used externally?


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.