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?
-
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 ?? 0x70352fb8Now 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); } }
-
Did you check whether your application has a leak ?