oKcerG / SortFilterProxyModel

A nicely exposed QSortFilterProxyModel for QML
MIT License
301 stars 102 forks source link

Segfault when calling get() #74

Open mitchcurtis opened 4 years ago

mitchcurtis commented 4 years ago

This is probably not a very useful report since I can't attach a minimal example, but thought I'd create it anyway in case it is useful:

            ListView {
                id: craftingRecipesListView
                objectName: root.objectName + "RecipesListView"
                leftMargin: 8
                rightMargin: 8
                topMargin: 8
                bottomMargin: 8
                currentIndex: count > 0 ? 0 : -1

                Layout.preferredWidth: 300
                Layout.fillHeight: true

                onCurrentIndexChanged: print("currentIndex", currentIndex)

                readonly property string currentItemName: model.get(model.mapFromSource(currentIndex), "itemName")

                ItemViewBackground {
                    objectName: parent.objectName + "BackgroundRect"
                    anchors.fill: parent
                    z: -1
                }

                CraftingModel {
                    id: craftingSourceModel
                    game: root.game
                    // The model loads its data once each time a crafter is set,
                    // and therefore assumes that the game will be paused (i.e. items
                    // cannot be added and hence canCraft can't change), so safeguard that assumption
                    // by clearing the model's data when we get hidden and the game unpauses.
                    crafter: root.visible ? root.crafter : null
                }

                model: SortFilterProxyModel {
                    sourceModel: craftingSourceModel
                    filters: AnyOf {
                        ValueFilter {
                            roleName: "itemName"
                            value: filterTextField.text
                            enabled: filterTextField.text.length > 0
                        }
                        ExpressionFilter {
                            // itemName is exposed like a delegate in a view, according to the docs for ExpressionFilter
                            expression: craftingSystem.ingredientsContain(itemName, filterTextField.text)
                            enabled: filterTextField.text.length > 0
                        }
                    }
                }
                // ...
AddressSanitizer:DEADLYSIGNAL
=================================================================
==27688==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000000 (pc 0x000116c88a21 bp 0x7ffee07119c0 sp 0x7ffee0711980 T0)
==27688==The signal is caused by a READ memory access.
==27688==Hint: address points to the zero page.
    #0 0x116c88a20 in qqsfpm::QQmlSortFilterProxyModel::sourceData(QModelIndex const&, int) const qqmlsortfilterproxymodel.cpp:238
    #1 0x116c88adf in qqsfpm::QQmlSortFilterProxyModel::data(QModelIndex const&, int) const qqmlsortfilterproxymodel.cpp:243
    #2 0x116c890c3 in qqsfpm::QQmlSortFilterProxyModel::get(int, QString const&) const qqmlsortfilterproxymodel.cpp:286
    #3 0x116c6f8d5 in qqsfpm::QQmlSortFilterProxyModel::qt_static_metacall(QObject*, QMetaObject::Call, int, void**) moc_qqmlsortfilterproxymodel.cpp:250
    #4 0x116c70444 in qqsfpm::QQmlSortFilterProxyModel::qt_metacall(QMetaObject::Call, int, void**) moc_qqmlsortfilterproxymodel.cpp:395
    #5 0x110b3632c in QMetaObject::metacall(QObject*, QMetaObject::Call, int, void**) qmetaobject.cpp:316
    #6 0x115637203 in QQmlObjectOrGadget::metacall(QMetaObject::Call, int, void**) const qqmlobjectorgadget.cpp:51
    #7 0x114f96bec in CallMethod(QQmlObjectOrGadget const&, int, int, int, int*, QV4::ExecutionEngine*, QV4::CallData*, QMetaObject::Call) qv4qobjectwrapper.cpp:1300
    #8 0x114f883cf in CallPrecise(QQmlObjectOrGadget const&, QQmlPropertyData const&, QV4::ExecutionEngine*, QV4::CallData*, QMetaObject::Call) qv4qobjectwrapper.cpp:1565
    #9 0x114f88df0 in CallOverloaded(QQmlObjectOrGadget const&, QQmlPropertyData const&, QV4::ExecutionEngine*, QV4::CallData*, QQmlPropertyCache const*, QMetaObject::Call) qv4qobjectwrapper.cpp:1641
    #10 0x114f8703f in QV4::QObjectMethod::callInternal(QV4::Value const*, QV4::Value const*, int) const qv4qobjectwrapper.cpp:2129
    #11 0x114f861d2 in QV4::QObjectMethod::virtualCall(QV4::FunctionObject const*, QV4::Value const*, QV4::Value const*, int) qv4qobjectwrapper.cpp:2064
    #12 0x114ccc9c5 in QV4::FunctionObject::call(QV4::Value const*, QV4::Value const*, int) const qv4functionobject_p.h:202
    #13 0x115050c96 in QV4::Moth::VME::interpret(QV4::CppStackFrame*, QV4::ExecutionEngine*, char const*) qv4vme_moth.cpp:754
    #14 0x1150418da in QV4::Moth::VME::exec(QV4::CppStackFrame*, QV4::ExecutionEngine*) qv4vme_moth.cpp:463
    #15 0x114e310e1 in QV4::Function::call(QV4::Value const*, QV4::Value const*, int, QV4::ExecutionContext const*) qv4function.cpp:69
    #16 0x1156a12ec in QQmlJavaScriptExpression::evaluate(QV4::CallData*, bool*) qqmljavascriptexpression.cpp:211
    #17 0x1156be1b6 in QQmlBinding::evaluate(bool*) qqmlbinding.cpp:218
    #18 0x1156c74c8 in QQmlNonbindingBinding::doUpdate(QQmlJavaScriptExpression::DeleteWatcher const&, QFlags<QQmlPropertyData::WriteFlag>, QV4::Scope&) qqmlbinding.cpp:254
    #19 0x1156bd485 in QQmlBinding::update(QFlags<QQmlPropertyData::WriteFlag>) qqmlbinding.cpp:194
    #20 0x1156c126d in QQmlBinding::setEnabled(bool, QFlags<QQmlPropertyData::WriteFlag>) qqmlbinding.cpp:566
    #21 0x1156c1b8b in non-virtual thunk to QQmlBinding::setEnabled(bool, QFlags<QQmlPropertyData::WriteFlag>) qqmlbinding.cpp
    #22 0x1154b8554 in QQmlData::flushPendingBindingImpl(QQmlPropertyIndex) qqmlengine.cpp:909
    #23 0x114f71bce in QQmlData::flushPendingBinding(QObject*, QQmlPropertyIndex) qqmldata_p.h:421
    #24 0x114f71477 in QV4::QObjectWrapper::getProperty(QV4::ExecutionEngine*, QObject*, QQmlPropertyData*) qv4qobjectwrapper.cpp:236
    #25 0x114f8312b in unsigned long long QV4::QObjectWrapper::lookupGetterImpl<QV4::QObjectWrapper::lookupGetter(QV4::Lookup*, QV4::ExecutionEngine*, QV4::Value const&)::$_2>(QV4::Lookup*, QV4::ExecutionEngine*, QV4::Value const&, bool, QV4::QObjectWrapper::lookupGetter(QV4::Lookup*, QV4::ExecutionEngine*, QV4::Value const&)::$_2) qv4qobjectwrapper_p.h:262
    #26 0x114f82b62 in QV4::QObjectWrapper::lookupGetter(QV4::Lookup*, QV4::ExecutionEngine*, QV4::Value const&) qv4qobjectwrapper.cpp:894
    #27 0x114f827d6 in QV4::QObjectWrapper::virtualResolveLookupGetter(QV4::Object const*, QV4::ExecutionEngine*, QV4::Lookup*) qv4qobjectwrapper.cpp:882
    #28 0x114d8738a in QV4::Object::resolveLookupGetter(QV4::ExecutionEngine*, QV4::Lookup*) const qv4object_p.h:379
    #29 0x114d87314 in QV4::Lookup::resolveGetter(QV4::ExecutionEngine*, QV4::Object const*) qv4lookup.cpp:72
    #30 0x114d8a78c in QV4::Lookup::getterGeneric(QV4::Lookup*, QV4::ExecutionEngine*, QV4::Value const&) qv4lookup.cpp:143
    #31 0x11504b6c7 in QV4::Moth::VME::interpret(QV4::CppStackFrame*, QV4::ExecutionEngine*, char const*) qv4vme_moth.cpp:638
    #32 0x1150418da in QV4::Moth::VME::exec(QV4::CppStackFrame*, QV4::ExecutionEngine*) qv4vme_moth.cpp:463
    #33 0x114e310e1 in QV4::Function::call(QV4::Value const*, QV4::Value const*, int, QV4::ExecutionContext const*) qv4function.cpp:69
    #34 0x1156a12ec in QQmlJavaScriptExpression::evaluate(QV4::CallData*, bool*) qqmljavascriptexpression.cpp:211
    #35 0x1156be1b6 in QQmlBinding::evaluate(bool*) qqmlbinding.cpp:218
    #36 0x1156c74c8 in QQmlNonbindingBinding::doUpdate(QQmlJavaScriptExpression::DeleteWatcher const&, QFlags<QQmlPropertyData::WriteFlag>, QV4::Scope&) qqmlbinding.cpp:254
    #37 0x1156bd485 in QQmlBinding::update(QFlags<QQmlPropertyData::WriteFlag>) qqmlbinding.cpp:194
    #38 0x1156c126d in QQmlBinding::setEnabled(bool, QFlags<QQmlPropertyData::WriteFlag>) qqmlbinding.cpp:566
    #39 0x1156c1b8b in non-virtual thunk to QQmlBinding::setEnabled(bool, QFlags<QQmlPropertyData::WriteFlag>) qqmlbinding.cpp
    #40 0x1154b8554 in QQmlData::flushPendingBindingImpl(QQmlPropertyIndex) qqmlengine.cpp:909
    #41 0x114f71bce in QQmlData::flushPendingBinding(QObject*, QQmlPropertyIndex) qqmldata_p.h:421
    #42 0x114f71477 in QV4::QObjectWrapper::getProperty(QV4::ExecutionEngine*, QObject*, QQmlPropertyData*) qv4qobjectwrapper.cpp:236
    #43 0x114f75bb7 in QV4::QObjectWrapper::getQmlProperty(QV4::ExecutionEngine*, QQmlContextData*, QObject*, QV4::String*, QV4::QObjectWrapper::RevisionMode, bool*, QQmlPropertyData**) qv4qobjectwrapper.cpp:388
    #44 0x114ee22d3 in QV4::QQmlContextWrapper::getPropertyAndBase(QV4::QQmlContextWrapper const*, QV4::PropertyKey, QV4::Value const*, bool*, QV4::Value*, QV4::Lookup*) qv4qmlcontext.cpp:316
    #45 0x114ee752a in QV4::QQmlContextWrapper::resolveQmlContextPropertyLookupGetter(QV4::Lookup*, QV4::ExecutionEngine*, QV4::Value*) qv4qmlcontext.cpp:481
    #46 0x115049601 in QV4::Moth::VME::interpret(QV4::CppStackFrame*, QV4::ExecutionEngine*, char const*) qv4vme_moth.cpp:585
    #47 0x1150418da in QV4::Moth::VME::exec(QV4::CppStackFrame*, QV4::ExecutionEngine*) qv4vme_moth.cpp:463
    #48 0x114e310e1 in QV4::Function::call(QV4::Value const*, QV4::Value const*, int, QV4::ExecutionContext const*) qv4function.cpp:69
    #49 0x1156a12ec in QQmlJavaScriptExpression::evaluate(QV4::CallData*, bool*) qqmljavascriptexpression.cpp:211
    #50 0x1156be1b6 in QQmlBinding::evaluate(bool*) qqmlbinding.cpp:218
    #51 0x1156c74c8 in QQmlNonbindingBinding::doUpdate(QQmlJavaScriptExpression::DeleteWatcher const&, QFlags<QQmlPropertyData::WriteFlag>, QV4::Scope&) qqmlbinding.cpp:254
    #52 0x1156bd485 in QQmlBinding::update(QFlags<QQmlPropertyData::WriteFlag>) qqmlbinding.cpp:194
    #53 0x1156c126d in QQmlBinding::setEnabled(bool, QFlags<QQmlPropertyData::WriteFlag>) qqmlbinding.cpp:566
    #54 0x1156c1b8b in non-virtual thunk to QQmlBinding::setEnabled(bool, QFlags<QQmlPropertyData::WriteFlag>) qqmlbinding.cpp
    #55 0x11571ec41 in QQmlObjectCreator::finalize(QQmlInstantiationInterrupt&) qqmlobjectcreator.cpp:1389
    #56 0x11552a1f8 in QQmlIncubatorPrivate::incubate(QQmlInstantiationInterrupt&) qqmlincubator.cpp:364
    #57 0x115527f1d in QQmlEnginePrivate::incubate(QQmlIncubator&, QQmlContextData*) qqmlincubator.cpp:89
    #58 0x115517cca in QQmlComponent::create(QQmlIncubator&, QQmlContext*, QQmlContext*) qqmlcomponent.cpp:1179
    #59 0x1184b794f in QQuickLoaderPrivate::_q_sourceLoaded() qquickloader.cpp:742
    #60 0x1184b5edd in QQuickLoaderPrivate::load() qquickloader.cpp:616
    #61 0x1184b5a1a in QQuickLoader::loadFromSourceComponent() qquickloader.cpp:513
    #62 0x1184b51a8 in QQuickLoader::setActive(bool) qquickloader.cpp:351
mitchcurtis commented 4 years ago

Checking currentIndex seems to avoid the problem:

readonly property string currentItemName: currentIndex !== -1 ? model.get(model.mapFromSource(currentIndex), "itemName") : ""