Qt6 Read Access Violation from QDockAreaLayout
-
File reading section is like below. I tried to put
const QString RCL_XML_ATT_INT_IDX = "idx"; const QString RCL_XML_ATT_INT_VALUE = "value"; QDomDocument* MauiUtil::XmlReadFile(const QString& roFileName) { QDomDocument* poDomDoc(NULL); try { if (!QFile::exists(roFileName)) { return NULL; } QFile oFile(roFileName); if(!oFile.open(QIODevice::ReadOnly)) { return NULL; } poDomDoc = new QDomDocument; QString oErrorMsg; if(!poDomDoc->setContent(&oFile,&oErrorMsg)) { delete poDomDoc; poDomDoc = NULL; qCritical("MauiUtil::XmlReadFile failed: %s",oErrorMsg.toLocal8Bit().constData()); return NULL; } oFile.close(); return poDomDoc; } catch (...) { qCritical("MauiUtil::XmlReadFile failed"); } if( poDomDoc ) { delete poDomDoc; poDomDoc = NULL; } return poDomDoc; } void MauiUtil::XmlAddIntToParent( QDomElement& roParentElement, const QString& roChildName, const QVector<int32>& roValues ) { int32 sl_size(roValues.size()); QDomDocument o_doc; for(int32 sl_idx(0);sl_idx<sl_size;++sl_idx) { QDomElement o_child_element(o_doc.createElement(roChildName)); if( o_child_element.isNull() ) { continue; } o_child_element.setAttribute(RCL_XML_ATT_INT_IDX,QString("%1").arg(sl_idx)); o_child_element.setAttribute(RCL_XML_ATT_INT_VALUE,QString("%1").arg(roValues.at(sl_idx))); roParentElement.appendChild(o_child_element); } } bool MauiUtil::XmlGetAttrValue( const QDomElement& roElement, const QString& roAttrName, QString& roAttrValue ) { roAttrValue = QString::fromUtf8(roElement.attribute(roAttrName).toLatin1()); if( roAttrValue.isNull() ) { return false; } return true; } void MauiUtil::XmlGetIntFromParent( const QDomElement& roParentElement, const QString& roChildName, QVector<int32>& roValuesResult ) { QString o_value_string; QString o_idx_string; QList<int32> o_idx_list; QList<int32> o_value_list; for(QDomElement o_child_element(roParentElement.firstChildElement(roChildName)); !o_child_element.isNull(); o_child_element = o_child_element.nextSiblingElement(roChildName) ) { if( MauiUtil::XmlGetAttrValue(o_child_element,RCL_XML_ATT_INT_IDX,o_idx_string) && MauiUtil::XmlGetAttrValue(o_child_element,RCL_XML_ATT_INT_VALUE,o_value_string) ) { o_idx_list.append(o_idx_string.toInt()); o_value_list.append(o_value_string.toInt()); } } int32 sl_idx_size(o_idx_list.size()); if( sl_idx_size>0 && sl_idx_size==o_value_list.size() ) { roValuesResult.resize(sl_idx_size); for(int32 sl_idx(0);sl_idx<sl_idx_size;++sl_idx ) { roValuesResult.replace(o_idx_list.at(sl_idx),o_value_list.at(sl_idx)); } } } void MauiUtil::SetTreeViewColumnWidth( QTreeView* poTreeView, QVector<int32>& roWidths ) { if( poTreeView && poTreeView->model() ) { QAbstractItemModel* po_model(poTreeView->model()); int32 sl_model_col_size(po_model->columnCount()); if( !roWidths.isEmpty() && sl_model_col_size==roWidths.size() ) { // make a copy of roWidths // changing one column emits appropriate signal, catching this // signal the array might changed outside when this function // is interrupted QVector<int32> o_widths_copy(roWidths); int32 sl_col_width; for( int32 sl_idx(0);sl_idx<sl_model_col_size;++sl_idx ) { //qDebug() << "col " << sl_idx << " set to width " << o_widths_copy.at(sl_idx); sl_col_width=o_widths_copy.at(sl_idx); if( sl_col_width<0 ) { ResizeColumnToContents(poTreeView, sl_idx); } else { poTreeView->setColumnWidth(sl_idx,sl_col_width); } } } else { // resize column to contents when no column width information is available // or when columns sizes are different //qDebug() << "resize all col to contents"; roWidths.resize(sl_model_col_size); for( int32 sl_idx(0);sl_idx<sl_model_col_size;++sl_idx ) { ResizeColumnToContents(poTreeView, sl_idx); roWidths.replace(sl_idx,poTreeView->columnWidth(sl_idx)); } } } } void MauiUtil::ResizeColumnToContents(QTreeView* poTreeView, int32 slColIdx) { poTreeView->resizeColumnToContents(slColIdx); int columnWidth = poTreeView->columnWidth(slColIdx); if( columnWidth < MinColumnSize ) { poTreeView->setColumnWidth(slColIdx, MinColumnSize); } if( columnWidth > MaxColumnSize ) { poTreeView->setColumnWidth(slColIdx, MaxColumnSize); } }
void C_MainView::ReadSettings() { if(m_poMainWindow.isNull()) { // nothing to restore for, when no window available return; } QDomElement oRootElement(GetSettings()); //qDebug() << "C_MainView::ReadSettings() " << oRootElement.nodeName(); if( oRootElement.isNull() ) { return; } QDomElement oWindow=oRootElement.firstChildElement(RCL_XML_ELEMENT_WINDOW); if( !oWindow.isNull() ) { QString oDataAttribute; if( MauiUtil::XmlGetAttrValue(oWindow,"geometry",oDataAttribute) ) { QByteArray oOrgDataGeometry; oOrgDataGeometry = QByteArray::fromHex(oDataAttribute.toLatin1()); if (!oOrgDataGeometry.isNull()) { m_poMainWindow->restoreGeometry(oOrgDataGeometry);/*lint !e534 (ignore return value)*/ } } if( MauiUtil::XmlGetAttrValue(oWindow,"state",oDataAttribute) ) { QByteArray oOrgDataState; oOrgDataState = QByteArray::fromHex(oDataAttribute.toLatin1()); if(!oOrgDataState.isNull()) { m_poMainWindow->restoreState(oOrgDataState);/*lint !e534 (ignore return value)*/ } } if( MauiUtil::XmlGetAttrValue(oWindow,"navigator",oDataAttribute) && m_poProjectNavigator ) { if( oDataAttribute=="invisible" ) { m_poProjectNavigator->close(); } else { m_poProjectNavigator->show(); } } } m_poMainWindow->setCentralWidget(m_poWorkingArea); }
-
By the way, I have found something
I manupulated the xml file via removing geometry="01d9d0cb00030000fffffffffffffff700000780000004060000046c000000b40000077f000003d300000000020000000780000000000000001d0000077f00000405" attribute. When I remove this, there is no crash. If I add it again, it crashes
<mainview> <window state="000000ff00000000fd00000003000000000000010000000237fc0200000001fb00000016006d00610069006e0076006900650077005f0070006e0100000042000002370000007100ffffff00000001fffffffffffffffffc0200000001fb00000016006d00610069006e0076006900650077005f007700610100000000ffffffff0000000000000000000000030000078000000152fc0100000002fb00000016006d00610069006e0076006900650077005f006300770100000000000001790000000000000000fb00000016006d00610069006e0076006900650077005f006400760100000000000007800000011200ffffff0000067b0000023700000004000000040000000800000008fc000000010000000200000001000000660043005f004d00610069006e0056006900650077003a003a0070006f005f006e00650077005f0074006f006f006c005f00620061007200530069006d006f006300720061006e0065002000530065006e0073006f00720020004d006f00640075006c006500730100000000ffffffff0000000000000000" geometry="01d9d0cb00030000fffffffffffffff700000780000004060000046c000000b40000077f000003d300000000020000000780000000000000001d0000077f00000405" navigator="visible"/> <language selected_action_name="english"/> </mainview>
-
Then don't restore the old window state from Qt5.
-
Bilal Canreplied to Christian Ehrlicher on 4 Jan 2024, 14:13 last edited by Bilal Can 1 Apr 2024, 14:13
@Christian-Ehrlicher do you know why it is a problem? Is there some behavior change in Qt6?
-
This can really be a bug. This is scenario:
- Delete geometry tag,
- Open app.exe
- Close app (geometry value is created in the xml)
- Open app.exe (geometry value created in 3rd step is used and successful)
- Maximize the window
- Close app (geometry value is created in the xml)
- Open app.exe => The same crash
-
And again - please provide a minimal, compilable example. Noone will look into your full-blown code and even if you report it to bugreports.qt.io noone will look into it until there is a minimal reproducer.
-
@Christian-Ehrlicher The only thing I can say is I am giving "01d9d0cb0003000000000000fffffff9000005ff00000337000001c0000000ac00000521000002eb000000000200000006000000000000000017000005ff00000337" this value m_poMainWindow->restoreGeometry(oOrgDataGeometry); and then I call m_poMainWindow->show();
this value is actually gathered from m_poMainWindow->saveGeometry()..toHex().constData();
the value I wrote above is the value gathered by this method when the user wanted to save the app settings. Currently I cannot support a minimal app but these are the problematic codes -
I have the exact same problem. After upgrading to Qt6, this standard "store/restore" thing started crashing on me.
-
@Martin-Cmar hi and welcome to devnet,
Please provide a minimal compilable example that shows this issue.
In the mean time, did you try to delete the current saved state and trigger a new cycle ?
-
@SGaist Hi, and thanks for welcome :)
Sadly I am in a similar situation as the other guy in the thread. We are working on a big project and providing a minimal sample is almost impossible at this moment. Though I understand that without it, it's hard to say what's wrong.
Yes, removing the old data and starting fresh solves the issue, but since many users run our software, it's not an ideal solution. However, increasing the version number, that is passed into this API effectively causes the same fresh start on their machines as well, so I guess this should be enough.
Either way though, it kinda proves the point that from Qt5 to Qt6, something got changed and loading the data from previous version leads to some memory corruption, so I still think this should be solved somehow officially.
-
@Martin-Cmar thanks for chiming in. Rather than reducing your application, can you trigger that from a dummy minimal application ?