I am using QtQuick on Android.
I am trying to append a Javascript object with an array property to a ListModel
.
I use LocalStorage
to store this data.
The object I materialise from the database has this array property, and when I try and append that object to the ListModel
I get a SEGFAULT. If I do not include an array in my object, or in fact if the array is empty, then it will successfully append to the ListModel
and will not SEGFAULT.
When I materialise the object from the database, I do this:
var movie = {
id: row.id,
title: row.title,
genres: ['a', 'b', 'c']
}
I'm creating a Javascript object and copying properties from the LocalStorage
result-set object 'row'. For the sake of this issue, I just hard-code the array as you can see above. When this object is appended to the ListModel
it SEGFAULTs.
If I remove the genres attribute completely, or even leave it empty as in [], it will not SEGFAULT when appended:
var movie = {
id: row.id,
title: row.title,
genres: []
}
Here is the stack trace:
0 ListModel::set(int, QV4::Referenced<QV4::Object>, QV8Engine*) /home/linux/qt/Qt5.2.1/5.2.1/android_armv7/lib/libQt5Qml.so 0x7542b138
1 ListModel::append(QV4::Referenced<QV4::Object>, QV8Engine*) /home/linux/qt/Qt5.2.1/5.2.1/android_armv7/lib/libQt5Qml.so 0x7542b40a
2 ListModel::set(int, QV4::Referenced<QV4::Object>, QV8Engine*) /home/linux/qt/Qt5.2.1/5.2.1/android_armv7/lib/libQt5Qml.so 0x7542b26c
3 ListModel::append(QV4::Referenced<QV4::Object>, QV8Engine*) /home/linux/qt/Qt5.2.1/5.2.1/android_armv7/lib/libQt5Qml.so 0x7542b40a
4 QQmlListModel::append(QQmlV4Function*) /home/linux/qt/Qt5.2.1/5.2.1/android_armv7/lib/libQt5Qml.so 0x7542d21c
5 QQmlListModel::qt_metacall(QMetaObject::Call, int, void**) /home/linux/qt/Qt5.2.1/5.2.1/android_armv7/lib/libQt5Qml.so 0x754347ea
6 QMetaObject::metacall(QObject*, QMetaObject::Call, int, void**) /home/linux/qt/Qt5.2.1/5.2.1/android_armv7/lib/libQt5Core.so 0x75054416
7 QV4::QObjectMethod::callInternal(QV4::CallData*) /home/linux/qt/Qt5.2.1/5.2.1/android_armv7/lib/libQt5Qml.so 0x753ac7c4
8 QV4::FunctionObject::call(QV4::CallData*) /home/linux/qt/Qt5.2.1/5.2.1/android_armv7/lib/libQt5Qml.so 0x7537ed5e
9 QV4::__qmljs_call_property(QV4::ExecutionContext*, QV4::Referenced<QV4::String>, QV4::CallDataRef) /home/linux/qt/Qt5.2.1/5.2.1/android_armv7/lib/libQt5Qml.so 0x75380962
10 ?? 0x7727c2e8
11 ?? 0x7727c2e8
After building Qt with full debug symbols and single-stepping, the crash is here:
void ListModel::set(int elementIndex, QV4::ObjectRef object, QV8Engine *eng)
{
ListElement *e = elements[elementIndex];
QV4::ExecutionEngine *v4 = object->engine(); <= SEGFAULT
When stepping through the code it seems when it encounters the Javascript array value for the genres property, the ListModel
is attempting to create a sub-model and then it fails. This is called as a result of this piece of code also in the ListModel::set
function:
} else if (propertyValue->asArrayObject()) {
a = propertyValue;
const ListLayout::Role &r = m_layout->getRoleOrCreate(propertyName, ListLayout::Role::List);
if (r.type == ListLayout::Role::List) {
ListModel *subModel = new ListModel(r.subLayout, 0, -1);
int arrayLength = a->arrayLength();
for (int j=0 ; j < arrayLength ; ++j) {
o = a->getIndexed(j);
subModel->append(o, eng); <= This leads to the nested 'set' call above that crashes
}
So why is this failing?