Solved Crash in QML desktop application
-
Hi,
I'm working on a medium sized desktop application, where the UI is made with QML. At the leftside of the application, we have a toolbar with 4 buttons which determine in which layout you are working. Each layout has a different set of toolbars and a docking view(with docked windows inside and a 3d render window). When switching between the layouts, the toolbars change, the docking view changes (with different number of docked windows with different content) and the render window changes. Just to say that a lot changes when you switch between layouts. Once in a while, when switching between layouts, the application just crashes. I found a repeatable sequence of actions to make it crash, but I'm completely lost where to go from here. At the moment I change the layout, i set a context property to a new pointer which triggers all the updates and at one point somewhere deep in qt5qml.dll an assert is triggered. The complete call stack (from VS2013) looks as follows:
Qt5Cored.dll!qt_message_fatal(QtMsgType __formal, const QMessageLogContext & context, const QString & message) Line 1673 C++ Qt5Cored.dll!QMessageLogger::fatal(const char * msg, ...) Line 793 C++ Qt5Cored.dll!qt_assert(const char * assertion, const char * file, int line) Line 3064 C++ Qt5Qmld.dll!QQmlAbstractBinding::~QQmlAbstractBinding() Line 56 C++ Qt5Qmld.dll!QQmlBinding::~QQmlBinding() Line 144 C++ [External Code] Qt5Cored.dll!QMetaObject::cast(const QObject * obj) Line 366 C++ Qt5Cored.dll!QMetaObject::cast(QObject * obj) Line 356 C++ Qt5Qmld.dll!qobject_cast<QObject * __ptr64>(QObject * object) Line 517 C++ Qt5Qmld.dll!QtPrivate::QVariantValueHelper<QObject * __ptr64>::object(const QVariant & v) Line 710 C++ Qt5Qmld.dll!QtPrivate::ObjectInvoker<QtPrivate::QVariantValueHelper<QObject * __ptr64>,QVariant const & __ptr64,QObject * __ptr64>::invoke(const QVariant & a) Line 103 C++ Qt5Qmld.dll!qvariant_cast<QObject * __ptr64>(const QVariant & v) Line 836 C++ Qt5Qmld.dll!VDMObjectDelegateDataType::createItem(QQmlAdaptorModel & model, QQmlDelegateModelItemMetaType * metaType, QQmlEngine * __formal, int index) Line 761 C++ Qt5Qmld.dll!QQmlAdaptorModel::createItem(QQmlDelegateModelItemMetaType * metaType, QQmlEngine * engine, int index) Line 126 C++ Qt5Qmld.dll!QQmlDelegateModelPrivate::object(QQmlListCompositor::Group group, int index, bool asynchronous) Line 936 C++ Qt5Qmld.dll!QQmlDelegateModel::object(int index, bool asynchronous) Line 1023 C++ Qt5Quickd.dll!QQuickRepeaterPrivate::requestItems() Line 400 C++ Qt5Quickd.dll!QQuickRepeater::regenerate() Line 395 C++ Qt5Quickd.dll!QQuickRepeater::componentComplete() Line 348 C++ Qt5Qmld.dll!QQmlObjectCreator::finalize(QQmlInstantiationInterrupt & interrupt) Line 1218 C++ Qt5Qmld.dll!QQmlIncubatorPrivate::incubate(QQmlInstantiationInterrupt & i) Line 354 C++ Qt5Qmld.dll!QQmlEnginePrivate::incubate(QQmlIncubator & i, QQmlContextData * forContext) Line 95 C++ Qt5Qmld.dll!QQmlComponent::create(QQmlIncubator & incubator, QQmlContext * context, QQmlContext * forContext) Line 1067 C++ Qt5Quickd.dll!QQuickLoaderPrivate::_q_sourceLoaded() Line 723 C++ Qt5Quickd.dll!QQuickLoaderPrivate::load() Line 604 C++ Qt5Quickd.dll!QQuickLoader::componentComplete() Line 815 C++ Qt5Qmld.dll!QQmlObjectCreator::finalize(QQmlInstantiationInterrupt & interrupt) Line 1218 C++ Qt5Qmld.dll!QQmlIncubatorPrivate::incubate(QQmlInstantiationInterrupt & i) Line 354 C++ Qt5Qmld.dll!QQmlEnginePrivate::incubate(QQmlIncubator & i, QQmlContextData * forContext) Line 95 C++ Qt5Qmld.dll!QQmlDelegateModelItem::incubateObject(QQmlComponent * component, QQmlEngine * engine, QQmlContextData * context, QQmlContextData * forContext) Line 1930 C++ Qt5Qmld.dll!QQmlDelegateModelPrivate::object(QQmlListCompositor::Group group, int index, bool asynchronous) Line 990 C++ Qt5Qmld.dll!QQmlDelegateModel::object(int index, bool asynchronous) Line 1023 C++ Qt5Quickd.dll!QQuickRepeaterPrivate::requestItems() Line 400 C++ Qt5Quickd.dll!QQuickRepeater::regenerate() Line 395 C++ Qt5Quickd.dll!QQuickRepeater::setModel(const QVariant & m) Line 246 C++ Qt5Quickd.dll!QQuickRepeater::qt_static_metacall(QObject * _o, QMetaObject::Call _c, int _id, void * * _a) Line 223 C++ Qt5Quickd.dll!QQuickRepeater::qt_metacall(QMetaObject::Call _c, int _id, void * * _a) Line 269 C++ Qt5Cored.dll!QMetaObject::metacall(QObject * object, QMetaObject::Call cl, int idx, void * * argv) Line 302 C++ Qt5Qmld.dll!QQmlPropertyPrivate::write(QObject * object, const QQmlPropertyData & property, const QVariant & value, QQmlContextData * context, QFlags<enum QQmlPropertyPrivate::WriteFlag> flags) Line 1259 C++ Qt5Qmld.dll!QQmlPropertyPrivate::writeValueProperty(QObject * object, const QQmlPropertyData & core, const QVariant & value, QQmlContextData * context, QFlags<enum QQmlPropertyPrivate::WriteFlag> flags) Line 1183 C++ Qt5Qmld.dll!QQmlBinding::write(const QQmlPropertyData & core, const QV4::Value & result, bool isUndefined, QFlags<enum QQmlPropertyPrivate::WriteFlag> flags) Line 333 C++ Qt5Qmld.dll!QQmlBinding::update(QFlags<enum QQmlPropertyPrivate::WriteFlag> flags) Line 197 C++ Qt5Qmld.dll!QQmlBinding::expressionChanged() Line 405 C++ Qt5Qmld.dll!QQmlJavaScriptExpressionGuard_callback(QQmlNotifierEndpoint * e, void * * __formal) Line 431 C++ Qt5Qmld.dll!QQmlNotifier::emitNotify(QQmlNotifierEndpoint * endpoint, void * * a) Line 102 C++ Qt5Qmld.dll!QQmlData::signalEmitted(QAbstractDeclarativeData * __formal, QObject * object, int index, void * * a) Line 782 C++ Qt5Cored.dll!QMetaObject::activate(QObject * sender, int signalOffset, int local_signal_index, void * * argv) Line 3623 C++ Qt5Qmld.dll!QQmlVMEMetaObject::activate(QObject * object, int index, void * * args) Line 1206 C++ Qt5Qmld.dll!QQmlVMEMetaObject::writeVarProperty(int id, const QV4::Value & value) Line 964 C++ Qt5Qmld.dll!QQmlVMEMetaObject::setVMEProperty(int index, const QV4::Value & v) Line 1110 C++ Qt5Qmld.dll!QQmlBinding::write(const QQmlPropertyData & core, const QV4::Value & result, bool isUndefined, QFlags<enum QQmlPropertyPrivate::WriteFlag> flags) Line 304 C++ Qt5Qmld.dll!QQmlBinding::update(QFlags<enum QQmlPropertyPrivate::WriteFlag> flags) Line 197 C++ Qt5Qmld.dll!QQmlBinding::expressionChanged() Line 405 C++ Qt5Qmld.dll!QQmlJavaScriptExpressionGuard_callback(QQmlNotifierEndpoint * e, void * * __formal) Line 431 C++ Qt5Qmld.dll!QQmlNotifier::emitNotify(QQmlNotifierEndpoint * endpoint, void * * a) Line 102 C++ Qt5Qmld.dll!QQmlData::signalEmitted(QAbstractDeclarativeData * __formal, QObject * object, int index, void * * a) Line 782 C++ Qt5Cored.dll!QMetaObject::activate(QObject * sender, int signalOffset, int local_signal_index, void * * argv) Line 3623 C++ Qt5Qmld.dll!QQmlContext::setContextProperty(const QString & name, QObject * value) Line 361 C++ > MeshingMaster.exe!LayoutManager::changeLayout(const std::basic_string<char,std::char_traits<char>,std::allocator<char> > & layoutName) Line 96 C++ MeshingMaster.exe!ApplicationQMLContext::changeLayout(const QString & msg) Line 87 C++ MeshingMaster.exe!ApplicationQMLContext::qt_static_metacall(QObject * _o, QMetaObject::Call _c, int _id, void * * _a) Line 231 C++ MeshingMaster.exe!ApplicationQMLContext::qt_metacall(QMetaObject::Call _c, int _id, void * * _a) Line 408 C++ Qt5Cored.dll!QMetaObject::metacall(QObject * object, QMetaObject::Call cl, int idx, void * * argv) Line 302 C++ Qt5Qmld.dll!QQmlObjectOrGadget::metacall(QMetaObject::Call type, int index, void * * argv) Line 1542 C++ Qt5Qmld.dll!CallMethod(const QQmlObjectOrGadget & object, int index, int returnType, int argCount, int * argTypes, QV4::ExecutionEngine * engine, QV4::CallData * callArgs) Line 1129 C++ Qt5Qmld.dll!CallPrecise(const QQmlObjectOrGadget & object, const QQmlPropertyData & data, QV4::ExecutionEngine * engine, QV4::CallData * callArgs) Line 1378 C++ Qt5Qmld.dll!QV4::QObjectMethod::callInternal(QV4::CallData * callData) Line 1861 C++ Qt5Qmld.dll!QV4::QObjectMethod::call(const QV4::Managed * m, QV4::CallData * callData) Line 1801 C++ Qt5Qmld.dll!QV4::Object::call(QV4::CallData * d) Line 330 C++ Qt5Qmld.dll!QV4::Runtime::callProperty(QV4::ExecutionEngine * engine, int nameIndex, QV4::CallData * callData) Line 1030 C++ [External Code]
I know it's kinda long shot, but is there anybody who has an idea what could be the problem, or how I could find a starting point to look further. I already when through the call stack and checked some members to see if i could find a text or a class from my side, or a link to a qml file, but the only thing i see is internal qt code which I'm totally not familiar with.
Thanks for even looking at this!
Regards,Jan
-
I narrowed the problem down a little bit. In each layout we have something called a viewmanager. It's basically a tabview with a tab for each type of item in the scene which are important for that layout. The model for the tabView is a
Q_PROPERTY(QQmlListProperty<ViewManagerTabQMLInterface> tabsList READ getTabsList NOTIFY tabsListChanged);
the member QList is a
QList<ViewManagerTabQMLInterface*> _tabsList;
the implementation for getting the tabs is like this:
//-------------------------------------------------------------------------------------- /// Returns the tablist //-------------------------------------------------------------------------------------- QQmlListProperty<ViewManagerTabQMLInterface> ViewManagerQMLInterface::getTabsList() { return QQmlListProperty<ViewManagerTabQMLInterface>(this, 0, &appendTab, &tabCount, &tabAt, &tabClear); } //-------------------------------------------------------------------------------------- /// Appends a tab //-------------------------------------------------------------------------------------- void ViewManagerQMLInterface::appendTab(QQmlListProperty<ViewManagerTabQMLInterface>* list, ViewManagerTabQMLInterface* p) { ViewManagerQMLInterface* vm = qobject_cast<ViewManagerQMLInterface*>(list->object); if (vm && p) { vm->_tabsList.append(p); emit vm->tabsListChanged(); } } //-------------------------------------------------------------------------------------- /// Returns the number of tabs //-------------------------------------------------------------------------------------- int ViewManagerQMLInterface::tabCount(QQmlListProperty<ViewManagerTabQMLInterface>*list) { ViewManagerQMLInterface* vm = qobject_cast<ViewManagerQMLInterface*>(list->object); if (vm) return vm->_tabsList.count(); return 0; } //-------------------------------------------------------------------------------------- /// Returns the tab at the given index //-------------------------------------------------------------------------------------- ViewManagerTabQMLInterface* ViewManagerQMLInterface::tabAt(QQmlListProperty<ViewManagerTabQMLInterface>* list, int i) { ViewManagerQMLInterface* vm = qobject_cast<ViewManagerQMLInterface*>(list->object); if (vm) return vm->_tabsList.at(i); return 0; } //-------------------------------------------------------------------------------------- /// Clears all the tabse //-------------------------------------------------------------------------------------- void ViewManagerQMLInterface::tabClear(QQmlListProperty<ViewManagerTabQMLInterface> *list) { ViewManagerQMLInterface* vm = qobject_cast<ViewManagerQMLInterface*>(list->object); if (vm){ vm->_tabsList.clear(); emit vm->tabsListChanged(); } }
It seems like it has something to do with this. I found that the QQmlAdaptorModel is the model for the tabview...
It also seems that it tries to create the tabs from the tabmodel from the previous layout after the new layout became active....
Anyone can help me further?
Regards,Jan
-
I found the problem. I was giving one of the tabs, via qml to another class of mine. Qt deleted the tab because it took ownership of the pointer. I redesigned this and don't have the crash anymore