Open ali1234 opened 5 years ago
Here is a more complete backtrace:
#0 0x00007f990fd1420c in QVariant::QVariant(QVariant const&) () at /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
#1 0x000055a459a4e8ee in QMapData<QString, QVariant>::createNode(QString const&, QVariant const&, QMapNode<QString, QVariant>*, bool) (this=0x55a45b2733d0, k=..., v=..., parent=0x0, left=false)
at /usr/include/x86_64-linux-gnu/qt5/QtCore/qmap.h:230
#2 0x000055a459a4eb9c in QMapNode<QString, QVariant>::copy(QMapData<QString, QVariant>*) const (this=0x55a45af0ed60, d=0x55a45b2733d0) at /usr/include/x86_64-linux-gnu/qt5/QtCore/qmap.h:258
#3 0x000055a459a4ec40 in QMapNode<QString, QVariant>::copy(QMapData<QString, QVariant>*) const (this=0x55a45af1dc00, d=0x55a45b2733d0) at /usr/include/x86_64-linux-gnu/qt5/QtCore/qmap.h:267
#4 0x000055a459a4ec40 in QMapNode<QString, QVariant>::copy(QMapData<QString, QVariant>*) const (this=0x55a45af0f120, d=0x55a45b2733d0) at /usr/include/x86_64-linux-gnu/qt5/QtCore/qmap.h:267
#5 0x000055a459a4ebe5 in QMapNode<QString, QVariant>::copy(QMapData<QString, QVariant>*) const (this=0x55a45af0ede0, d=0x55a45b2733d0) at /usr/include/x86_64-linux-gnu/qt5/QtCore/qmap.h:261
#6 0x000055a459a55ed5 in QMap<QString, QVariant>::detach_helper() (this=0x7fffb21df440) at /usr/include/x86_64-linux-gnu/qt5/QtCore/qmap.h:998
#7 0x000055a459a5497d in QMap<QString, QVariant>::detach() (this=0x7fffb21df440) at /usr/include/x86_64-linux-gnu/qt5/QtCore/qmap.h:364
#8 0x000055a459a53c12 in QMap<QString, QVariant>::operator[](QString const&) (this=0x7fffb21df440, akey=...) at /usr/include/x86_64-linux-gnu/qt5/QtCore/qmap.h:663
#9 0x000055a459a57d77 in QSDiffRunnerAlgo::compare(QList<QVariant> const&, QList<QVariant> const&) (this=0x7fffb21df3f0, from=..., to=...) at ../lib/qsyncable/qsdiffrunneralgo.cpp:254
#10 0x000055a459a4dee7 in QSDiffRunner::compare(QList<QVariant> const&, QList<QVariant> const&) (this=0x7fffb21df4c0, from=..., to=...) at ../lib/qsyncable/qsdiffrunner.cpp:62
#11 0x000055a459a5c6f3 in QSJsonListModel::sync() (this=0x55a45b02f650) at ../lib/qsyncable/qsjsonlistmodel.cpp:187
#12 0x000055a459a5c5a9 in QSJsonListModel::setSource(QList<QVariant> const&) (this=0x55a45b02f650, source=...) at ../lib/qsyncable/qsjsonlistmodel.cpp:128
#13 0x000055a459aec541 in QSJsonListModel::qt_static_metacall(QObject*, QMetaObject::Call, int, void**) (_o=0x55a45b02f650, _c=QMetaObject::WriteProperty, _id=1, _a=0x7fffb21df6d0) at moc_qsjsonlistmodel.cpp:138
#14 0x000055a459aec705 in QSJsonListModel::qt_metacall(QMetaObject::Call, int, void**) (this=0x55a45b02f650, _c=QMetaObject::WriteProperty, _id=1, _a=0x7fffb21df6d0) at moc_qsjsonlistmodel.cpp:188
#15 0x00007f991098f78e in QQmlVMEMetaObject::metaCall(QObject*, QMetaObject::Call, int, void**) () at /usr/lib/x86_64-linux-gnu/libQt5Qml.so.5
#16 0x00007f99109a6242 in () at /usr/lib/x86_64-linux-gnu/libQt5Qml.so.5
#17 0x00007f99109a3d04 in QQmlPropertyPrivate::write(QObject*, QQmlPropertyData const&, QVariant const&, QQmlContextData*, QFlags<QQmlPropertyData::WriteFlag>) () at /usr/lib/x86_64-linux-gnu/libQt5Qml.so.5
#18 0x00007f991096d8d9 in QV4::QObjectWrapper::setProperty(QV4::ExecutionEngine*, QObject*, QQmlPropertyData*, QV4::Value const&) () at /usr/lib/x86_64-linux-gnu/libQt5Qml.so.5
#19 0x00007f9911ca2540 in ()
#20 0x0000000000000020 in ()
#21 0x00032000000000c8 in ()
#22 0x0000000000000000 in ()
I managed to capture the error and reduce it to the minimal case. This will hang QSyncable every time:
import QtQuick 2.2
import QSyncable 1.0
Rectangle {
JsonListModel {
id: something
keyField: "i"
}
Component.onCompleted: {
console.log('x');
something.source = JSON.parse('[{"i":"a"},{"i":"b"},{"i":"b"}]');
console.log('y');
something.source = JSON.parse('[{"i":"b"}]');
console.log('z');
}
}
Outputs the following and then hangs forever:
qml: x
qml: y
QSDiffRunner.compare() - Duplicated or missing key. ' "b" '
I realise that the duplicate key is an error but this is what the API server I have to deal with does. I think QSyncable should not hang forever on bad input.
Sometimes my program prints this. It happens very rarely but when it does happen the program freezes and uses 100% CPU forever. It seems to be getting suck inside a loop in the diff runner algorithm. I was able to obtain a backrace:
This is most likely caused by a transient error on the remote server. In any case, I think the algorithm should never get stuck regardless of what input is sent to it.