Re: [Interest] Double free in QItemDelegate editor
On 9/4/20 3:56 PM, Jérôme Godbout wrote: Shouldn't the FileDialog belong to the Window and not to the editor? Try without parent or parent to the top window on your dialog you can make it modal if you need to lock down the window. That would prevent the editor destruction to wrongly destroy the Dialog. Thanks for the suggestion. I tried this, and it allowed the file dialog to open without crashing. Unfortunately, the crash still happens when the dialog has closed, because opening the dialog still caused the editor to be destroyed, but the (destroyed) editor is still trying to set its own text when the dialog exits. What really needs to happen is the editor needs to not be destroyed when the dialog opens. Preferably, it shouldn't even become hidden. Kyle ___ Interest mailing list Interest@qt-project.org https://lists.qt-project.org/listinfo/interest
Re: [Interest] Double free in QItemDelegate editor
Shouldn't the FileDialog belong to the Window and not to the editor? Try without parent or parent to the top window on your dialog you can make it modal if you need to lock down the window. That would prevent the editor destruction to wrongly destroy the Dialog. -Original Message- From: Interest On Behalf Of Kyle Edwards via Interest Sent: September 4, 2020 3:20 PM To: interest@qt-project.org Subject: Re: [Interest] Double free in QItemDelegate editor On 9/4/20 2:40 PM, Kyle Edwards wrote: > After some more investigation, I've learned more about the nature of > the problem. > > The createEditor() override returns a button which, when clicked, > opens a file dialog (through QFileDialog::getOpenFileName() - this > will be important in a bit). The opening of this dialog causes the > editor to lose focus, which result in QAbstractItemDelegate emitting > its closeEditor() signal, which in turn destroys the editor. The > destroying of the editor also attempts to delete the file dialog, > since it's a child of the editor. However, the file dialog was > allocated on the stack by QFileDialog::getOpenFileName(). So, > attempting to delete the stack-allocated dialog results in a crash. > > So I guess the question is, how do I prevent QAbstractItemDelegate > from emitting closeEditor() when the file dialog opens? Either that or > prevent closeEditor() from actually closing the editor... I see > something in QAbstractItemView::closeEditor() about an editor being > "persistent", does that have anything to do with this? I now have a minimum working test case: // BEGIN #include #include #include #include #include #include #include #include #include classTestEdit: publicQLineEdit { Q_OBJECT public: TestEdit(QWidget*parent= nullptr); voidresizeEvent(QResizeEvent*e) override; public slots: voidchooseFile(); private: QToolButton* toolButton; }; TestEdit::TestEdit(QWidget*parent) : QLineEdit(parent) { this->toolButton= newQToolButton(this); this->toolButton->setText("..."); QObject::connect(this->toolButton, SIGNAL(clicked(bool)), this, SLOT(chooseFile())); } voidTestEdit::resizeEvent(QResizeEvent*e) { // make the tool button fit on the right side inth= e->size().height(); // move the line edit to make room for the tool button this->setContentsMargins(0, 0, h, 0); // put the tool button in its place this->toolButton->resize(h, h); this->toolButton->move(this->width() - h, 0); } voidTestEdit::chooseFile() { autopath= QFileDialog::getOpenFileName(this, "title", QString(), QString(), nullptr, QFileDialog::DontResolveSymlinks); if(!path.isEmpty()) { this->setText(path); } } classTestItemDelegate: publicQItemDelegate { Q_OBJECT public: QWidget*createEditor(QWidget*parent, constQStyleOptionViewItem&option, constQModelIndex&index) constoverride; }; QWidget*TestItemDelegate::createEditor(QWidget*parent, constQStyleOptionViewItem&option, constQModelIndex&index) const { returnnewTestEdit(parent); } intmain(intargc, char**argv) { QApplicationapp(argc, argv); QWidgetwindow; QTreeViewview(&window); auto* model= newQStandardItemModel; view.setModel(model); model->insertRow(0); model->insertColumn(0); model->setData(model->index(0, 0), "Hello"); view.setItemDelegate(newTestItemDelegate); window.show(); returnapp.exec(); } #include"qttest.moc" // END Run the program, double click the "Hello" item, a line editor will appear, click the button on the right to open the dialog, and then the invalid delete happens. Kyle ___ Interest mailing list Interest@qt-project.org https://lists.qt-project.org/listinfo/interest ___ Interest mailing list Interest@qt-project.org https://lists.qt-project.org/listinfo/interest
Re: [Interest] Double free in QItemDelegate editor
On 9/4/20 3:20 PM, Kyle Edwards wrote: I now have a minimum working test case: Err, looks like that got mis-formatted. Let me try again... // BEGIN #include #include #include #include #include #include #include #include #include class TestEdit : public QLineEdit { Q_OBJECT public: TestEdit(QWidget* parent = nullptr); void resizeEvent(QResizeEvent* e) override; public slots: void chooseFile(); private: QToolButton* toolButton; }; TestEdit::TestEdit(QWidget* parent) : QLineEdit(parent) { this->toolButton = new QToolButton(this); this->toolButton->setText("..."); QObject::connect(this->toolButton, SIGNAL(clicked(bool)), this, SLOT(chooseFile())); } void TestEdit::resizeEvent(QResizeEvent* e) { // make the tool button fit on the right side int h = e->size().height(); // move the line edit to make room for the tool button this->setContentsMargins(0, 0, h, 0); // put the tool button in its place this->toolButton->resize(h, h); this->toolButton->move(this->width() - h, 0); } void TestEdit::chooseFile() { auto path = QFileDialog::getOpenFileName(this, "title", QString(), QString(), nullptr, QFileDialog::DontResolveSymlinks); if (!path.isEmpty()) { this->setText(path); } } class TestItemDelegate : public QItemDelegate { Q_OBJECT public: QWidget* createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const override; }; QWidget* TestItemDelegate::createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const { return new TestEdit(parent); } int main(int argc, char** argv) { QApplication app(argc, argv); QWidget window; QTreeView view(&window); auto* model = new QStandardItemModel; view.setModel(model); model->insertRow(0); model->insertColumn(0); model->setData(model->index(0, 0), "Hello"); view.setItemDelegate(new TestItemDelegate); window.show(); return app.exec(); } #include "qttest.moc" // END ___ Interest mailing list Interest@qt-project.org https://lists.qt-project.org/listinfo/interest
Re: [Interest] Double free in QItemDelegate editor
On 9/4/20 2:40 PM, Kyle Edwards wrote: After some more investigation, I've learned more about the nature of the problem. The createEditor() override returns a button which, when clicked, opens a file dialog (through QFileDialog::getOpenFileName() - this will be important in a bit). The opening of this dialog causes the editor to lose focus, which result in QAbstractItemDelegate emitting its closeEditor() signal, which in turn destroys the editor. The destroying of the editor also attempts to delete the file dialog, since it's a child of the editor. However, the file dialog was allocated on the stack by QFileDialog::getOpenFileName(). So, attempting to delete the stack-allocated dialog results in a crash. So I guess the question is, how do I prevent QAbstractItemDelegate from emitting closeEditor() when the file dialog opens? Either that or prevent closeEditor() from actually closing the editor... I see something in QAbstractItemView::closeEditor() about an editor being "persistent", does that have anything to do with this? I now have a minimum working test case: // BEGIN #include #include #include #include #include #include #include #include #include classTestEdit: publicQLineEdit { Q_OBJECT public: TestEdit(QWidget*parent= nullptr); voidresizeEvent(QResizeEvent*e) override; public slots: voidchooseFile(); private: QToolButton* toolButton; }; TestEdit::TestEdit(QWidget*parent) : QLineEdit(parent) { this->toolButton= newQToolButton(this); this->toolButton->setText("..."); QObject::connect(this->toolButton, SIGNAL(clicked(bool)), this, SLOT(chooseFile())); } voidTestEdit::resizeEvent(QResizeEvent*e) { // make the tool button fit on the right side inth= e->size().height(); // move the line edit to make room for the tool button this->setContentsMargins(0, 0, h, 0); // put the tool button in its place this->toolButton->resize(h, h); this->toolButton->move(this->width() - h, 0); } voidTestEdit::chooseFile() { autopath= QFileDialog::getOpenFileName(this, "title", QString(), QString(), nullptr, QFileDialog::DontResolveSymlinks); if(!path.isEmpty()) { this->setText(path); } } classTestItemDelegate: publicQItemDelegate { Q_OBJECT public: QWidget*createEditor(QWidget*parent, constQStyleOptionViewItem&option, constQModelIndex&index) constoverride; }; QWidget*TestItemDelegate::createEditor(QWidget*parent, constQStyleOptionViewItem&option, constQModelIndex&index) const { returnnewTestEdit(parent); } intmain(intargc, char**argv) { QApplicationapp(argc, argv); QWidgetwindow; QTreeViewview(&window); auto* model= newQStandardItemModel; view.setModel(model); model->insertRow(0); model->insertColumn(0); model->setData(model->index(0, 0), "Hello"); view.setItemDelegate(newTestItemDelegate); window.show(); returnapp.exec(); } #include"qttest.moc" // END Run the program, double click the "Hello" item, a line editor will appear, click the button on the right to open the dialog, and then the invalid delete happens. Kyle ___ Interest mailing list Interest@qt-project.org https://lists.qt-project.org/listinfo/interest
Re: [Interest] Double free in QItemDelegate editor
On 9/4/20 12:06 PM, Kyle Edwards wrote: Interestingly, the stack trace shows that the widget's destructor is being called within one of its own methods. Whether it's the same widget or just the same class but a different instance, I'm not sure (ASAN's stack trace doesn't print this information.) After some more investigation, I've learned more about the nature of the problem. The createEditor() override returns a button which, when clicked, opens a file dialog (through QFileDialog::getOpenFileName() - this will be important in a bit). The opening of this dialog causes the editor to lose focus, which result in QAbstractItemDelegate emitting its closeEditor() signal, which in turn destroys the editor. The destroying of the editor also attempts to delete the file dialog, since it's a child of the editor. However, the file dialog was allocated on the stack by QFileDialog::getOpenFileName(). So, attempting to delete the stack-allocated dialog results in a crash. So I guess the question is, how do I prevent QAbstractItemDelegate from emitting closeEditor() when the file dialog opens? Either that or prevent closeEditor() from actually closing the editor... I see something in QAbstractItemView::closeEditor() about an editor being "persistent", does that have anything to do with this? Kyle ___ Interest mailing list Interest@qt-project.org https://lists.qt-project.org/listinfo/interest
Re: [Interest] Double free in QItemDelegate editor
On 9/3/20 5:49 PM, Giuseppe D'Angelo via Interest wrote: Do you have a minimal testcase? What does valgrind / ASAN say? No minimal test case yet. ASAN says the widget's destructor is calling QObjectPrivate::deleteChildren(), which then says "attempting free on address which was not malloc()ed: 0x..." Looking through the code, I don't see anything right away that could have been added as a child of this widget which was stack-allocated. Interestingly, the stack trace shows that the widget's destructor is being called within one of its own methods. Whether it's the same widget or just the same class but a different instance, I'm not sure (ASAN's stack trace doesn't print this information.) I'll take a closer look. Kyle ___ Interest mailing list Interest@qt-project.org https://lists.qt-project.org/listinfo/interest
Re: [Interest] Double free in QItemDelegate editor
Il 03/09/20 22:51, Kyle Edwards via Interest ha scritto: My project (CMake GUI) has a class which extends QItemDelegate and overrides QItemDelegate::createEditor(). However, the editor that gets returned by this method gets double-freed, and I'm not sure exactly why. (I did notice that QItemDelegate::destroyEditor() calls the editor's QObject::deleteLater() by default - does the editor already get deleted when its parent gets deleted?) Do you have a minimal testcase? What does valgrind / ASAN say? Thanks, -- Giuseppe D'Angelo | giuseppe.dang...@kdab.com | Senior Software Engineer KDAB (France) S.A.S., a KDAB Group company Tel. France +33 (0)4 90 84 08 53, http://www.kdab.com KDAB - The Qt, C++ and OpenGL Experts smime.p7s Description: Firma crittografica S/MIME ___ Interest mailing list Interest@qt-project.org https://lists.qt-project.org/listinfo/interest