Fix double delete crash (QObject/KTextEdit)
THis fixes following crash scenario:
- Application shutdown triggers
setReadOnly()
onKTextEdit
- setReadOnly() which triggers
delete d->decorator
- QObject parent/child chain tries to access deleted
d->decorator
Here's the valgrind output
Invalid read of size 8
in QObjectPrivate::setParent_helper(QObject*) in /home/max/kde/qt5/lib/libQt5Core.so.5.15.6
1: QObjectPrivate::setParent_helper(QObject*) in /home/max/kde/qt5/lib/libQt5Core.so.5.15.6
2: QObject::~QObject() in /home/max/kde/qt5/lib/libQt5Core.so.5.15.6
3: Sonnet::Highlighter::~Highlighter() in /home/max/kde/usr/lib/libKF5SonnetUi.so.5.99.0
4: Sonnet::Highlighter::~Highlighter() in /home/max/kde/usr/lib/libKF5SonnetUi.so.5.99.0
5: QObjectPrivate::deleteChildren() in /home/max/kde/qt5/lib/libQt5Core.so.5.15.6
6: QObject::~QObject() in /home/max/kde/qt5/lib/libQt5Core.so.5.15.6
7: Sonnet::SpellCheckDecorator::~SpellCheckDecorator() in /home/max/kde/usr/lib/libKF5SonnetUi.so.5.99.0
8: KTextDecorator::~KTextDecorator() in /home/max/kde/usr/lib/libKF5TextWidgets.so.5.99.0
9: KTextDecorator::~KTextDecorator() in /home/max/kde/usr/lib/libKF5TextWidgets.so.5.99.0
10: KTextEdit::setReadOnly(bool) in /home/max/kde/usr/lib/libKF5TextWidgets.so.5.99.0
11: SubtitleComposer::CurrentLineWidget::setCurrentLine(SubtitleComposer::SubtitleLine*) in /home/max/projects/SubtitleComposer/build-SubtitleComposer-kdesrc-Debug/src/subtitlecomposer
12: SubtitleComposer::CurrentLineWidget::setSubtitle(SubtitleComposer::Subtitle*) in /home/max/projects/SubtitleComposer/build-SubtitleComposer-kdesrc-Debug/src/subtitlecomposer
13: SubtitleComposer::Application::init()::{lambda()#7}::operator()() const in /home/max/projects/SubtitleComposer/build-SubtitleComposer-kdesrc-Debug/src/subtitlecomposer
14: QtPrivate::FunctorCall<QtPrivate::IndexesList<>, QtPrivate::List<>, void, SubtitleComposer::Application::init()::{lambda()#7}>::call({lambda()#7}&, void**) in /home/max/projects/SubtitleComposer/build-SubtitleComposer-kdesrc-Debug/src/subtitlecomposer
15: void QtPrivate::Functor<SubtitleComposer::Application::init()::{lambda()#7}, 0>::call<QtPrivate::List<>, void>({lambda()#7}&, void*, {lambda()#7}&*) in /home/max/projects/SubtitleComposer/build-SubtitleComposer-kdesrc-Debug/src/subtitlecomposer
16: QtPrivate::QFunctorSlotObject<SubtitleComposer::Application::init()::{lambda()#7}, 0, QtPrivate::List<>, void>::impl(int, QtPrivate::QSlotObjectBase*, QObject*, void**, bool*) in /home/max/projects/SubtitleComposer/build-SubtitleComposer-kdesrc-Debug/src/subtitlecomposer
17: void doActivate<false>(QObject*, int, void**) in /home/max/kde/qt5/lib/libQt5Core.so.5.15.6
18: SubtitleComposer::Application::subtitleClosed() in /home/max/projects/SubtitleComposer/build-SubtitleComposer-kdesrc-Debug/src/subtitlecomposer
19: SubtitleComposer::Application::closeSubtitle() in /home/max/projects/SubtitleComposer/build-SubtitleComposer-kdesrc-Debug/src/subtitlecomposer
20: SubtitleComposer::MainWindow::queryClose() in /home/max/projects/SubtitleComposer/build-SubtitleComposer-kdesrc-Debug/src/subtitlecomposer
21: KMainWindow::closeEvent(QCloseEvent*) in /home/max/kde/usr/lib/libKF5XmlGui.so.5.99.0
22: QWidget::event(QEvent*) in /home/max/kde/qt5/lib/libQt5Widgets.so.5.15.6
23: KMainWindow::event(QEvent*) in /home/max/kde/usr/lib/libKF5XmlGui.so.5.99.0
24: KXmlGuiWindow::event(QEvent*) in /home/max/kde/usr/lib/libKF5XmlGui.so.5.99.0
25: QApplicationPrivate::notify_helper(QObject*, QEvent*) in /home/max/kde/qt5/lib/libQt5Widgets.so.5.15.6
Address 0x30ee7568 is 8 bytes inside a block of size 32 free'd
1: operator delete(void*, unsigned long) in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so
2: KTextEdit::setReadOnly(bool) in /home/max/kde/usr/lib/libKF5TextWidgets.so.5.99.0
3: SubtitleComposer::CurrentLineWidget::setCurrentLine(SubtitleComposer::SubtitleLine*) in /home/max/projects/SubtitleComposer/build-SubtitleComposer-kdesrc-Debug/src/subtitlecomposer
4: QtPrivate::FunctorCall<QtPrivate::IndexesList<0>, QtPrivate::List<SubtitleComposer::SubtitleLine*>, void, void (SubtitleComposer::CurrentLineWidget::*)(SubtitleComposer::SubtitleLine*)>::call(void (SubtitleComposer::CurrentLineWidget::*)(SubtitleComposer::SubtitleLine*), SubtitleComposer::CurrentLineWidget*, void**) in /home/max/projects/SubtitleComposer/build-SubtitleComposer-kdesrc-Debug/src/subtitlecomposer
5: void QtPrivate::FunctionPointer<void (SubtitleComposer::CurrentLineWidget::*)(SubtitleComposer::SubtitleLine*)>::call<QtPrivate::List<SubtitleComposer::SubtitleLine*>, void>(void (SubtitleComposer::CurrentLineWidget::*)(SubtitleComposer::SubtitleLine*), SubtitleComposer::CurrentLineWidget*, void**) in /home/max/projects/SubtitleComposer/build-SubtitleComposer-kdesrc-Debug/src/subtitlecomposer
6: QtPrivate::QSlotObject<void (SubtitleComposer::CurrentLineWidget::*)(SubtitleComposer::SubtitleLine*), QtPrivate::List<SubtitleComposer::SubtitleLine*>, void>::impl(int, QtPrivate::QSlotObjectBase*, QObject*, void**, bool*) in /home/max/projects/SubtitleComposer/build-SubtitleComposer-kdesrc-Debug/src/subtitlecomposer
7: void doActivate<false>(QObject*, int, void**) in /home/max/kde/qt5/lib/libQt5Core.so.5.15.6
8: SubtitleComposer::LinesWidget::currentLineChanged(SubtitleComposer::SubtitleLine*) in /home/max/projects/SubtitleComposer/build-SubtitleComposer-kdesrc-Debug/src/subtitlecomposer
9: SubtitleComposer::LinesWidget::onCurrentRowChanged() in /home/max/projects/SubtitleComposer/build-SubtitleComposer-kdesrc-Debug/src/subtitlecomposer
10: QtPrivate::FunctorCall<QtPrivate::IndexesList<>, QtPrivate::List<>, void, void (SubtitleComposer::LinesWidget::*)()>::call(void (SubtitleComposer::LinesWidget::*)(), SubtitleComposer::LinesWidget*, void**) in /home/max/projects/SubtitleComposer/build-SubtitleComposer-kdesrc-Debug/src/subtitlecomposer
11: void QtPrivate::FunctionPointer<void (SubtitleComposer::LinesWidget::*)()>::call<QtPrivate::List<>, void>(void (SubtitleComposer::LinesWidget::*)(), SubtitleComposer::LinesWidget*, void**) in /home/max/projects/SubtitleComposer/build-SubtitleComposer-kdesrc-Debug/src/subtitlecomposer
12: QtPrivate::QSlotObject<void (SubtitleComposer::LinesWidget::*)(), QtPrivate::List<>, void>::impl(int, QtPrivate::QSlotObjectBase*, QObject*, void**, bool*) in /home/max/projects/SubtitleComposer/build-SubtitleComposer-kdesrc-Debug/src/subtitlecomposer
13: void doActivate<false>(QObject*, int, void**) in /home/max/kde/qt5/lib/libQt5Core.so.5.15.6
14: QItemSelectionModel::currentRowChanged(QModelIndex const&, QModelIndex const&) in /home/max/kde/qt5/lib/libQt5Core.so.5.15.6
15: QItemSelectionModel::clearCurrentIndex() in /home/max/kde/qt5/lib/libQt5Core.so.5.15.6
16: SubtitleComposer::LinesSelectionModel::clear() in /home/max/projects/SubtitleComposer/build-SubtitleComposer-kdesrc-Debug/src/subtitlecomposer
17: SubtitleComposer::LinesModel::onModelReset() in /home/max/projects/SubtitleComposer/build-SubtitleComposer-kdesrc-Debug/src/subtitlecomposer
18: SubtitleComposer::LinesModel::processSelectionUpdate() in /home/max/projects/SubtitleComposer/build-SubtitleComposer-kdesrc-Debug/src/subtitlecomposer
19: saveSelection(int*, QList<std::pair<int, int> >*) in /home/max/projects/SubtitleComposer/build-SubtitleComposer-kdesrc-Debug/src/subtitlecomposer
20: SubtitleComposer::UndoStack::levelIncrease(int) in /home/max/projects/SubtitleComposer/build-SubtitleComposer-kdesrc-Debug/src/subtitlecomposer
21: SubtitleComposer::UndoStack::push(SubtitleComposer::UndoAction*) in /home/max/projects/SubtitleComposer/build-SubtitleComposer-kdesrc-Debug/src/subtitlecomposer
22: SubtitleComposer::Subtitle::processAction(SubtitleComposer::UndoAction*) const in /home/max/projects/SubtitleComposer/build-SubtitleComposer-kdesrc-Debug/src/subtitlecomposer
23: SubtitleComposer::SubtitleLine::processAction(SubtitleComposer::UndoAction*) in /home/max/projects/SubtitleComposer/build-SubtitleComposer-kdesrc-Debug/src/subtitlecomposer
24: SubtitleComposer::SubtitleLine::primaryDocumentChanged() in /home/max/projects/SubtitleComposer/build-SubtitleComposer-kdesrc-Debug/src/subtitlecomposer
25: QtPrivate::FunctorCall<QtPrivate::IndexesList<>, QtPrivate::List<>, void, void (SubtitleComposer::SubtitleLine::*)()>::call(void (SubtitleComposer::SubtitleLine::*)(), SubtitleComposer::SubtitleLine*, void**) in /home/max/projects/SubtitleComposer/build-SubtitleComposer-kdesrc-Debug/src/subtitlecomposer
Block was alloc'd at
1: operator new(unsigned long) in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so
2: KTextEdit::setHighlighter(Sonnet::Highlighter*) in /home/max/kde/usr/lib/libKF5TextWidgets.so.5.99.0
3: KTextEdit::createHighlighter() in /home/max/kde/usr/lib/libKF5TextWidgets.so.5.99.0
4: KTextEdit::setCheckSpellingEnabled(bool) in /home/max/kde/usr/lib/libKF5TextWidgets.so.5.99.0
5: SubtitleComposer::SimpleRichTextEdit::toggleAutoSpellChecking() in /home/max/projects/SubtitleComposer/build-SubtitleComposer-kdesrc-Debug/src/subtitlecomposer
6: QtPrivate::FunctorCall<QtPrivate::IndexesList<>, QtPrivate::List<>, void, void (SubtitleComposer::SimpleRichTextEdit::*)()>::call(void (SubtitleComposer::SimpleRichTextEdit::*)(), SubtitleComposer::SimpleRichTextEdit*, void**) in /home/max/projects/SubtitleComposer/build-SubtitleComposer-kdesrc-Debug/src/subtitlecomposer
7: void QtPrivate::FunctionPointer<void (SubtitleComposer::SimpleRichTextEdit::*)()>::call<QtPrivate::List<>, void>(void (SubtitleComposer::SimpleRichTextEdit::*)(), SubtitleComposer::SimpleRichTextEdit*, void**) in /home/max/projects/SubtitleComposer/build-SubtitleComposer-kdesrc-Debug/src/subtitlecomposer
8: QtPrivate::QSlotObject<void (SubtitleComposer::SimpleRichTextEdit::*)(), QtPrivate::List<>, void>::impl(int, QtPrivate::QSlotObjectBase*, QObject*, void**, bool*) in /home/max/projects/SubtitleComposer/build-SubtitleComposer-kdesrc-Debug/src/subtitlecomposer
9: void doActivate<false>(QObject*, int, void**) in /home/max/kde/qt5/lib/libQt5Core.so.5.15.6
10: QAction::triggered(bool) in /home/max/kde/qt5/lib/libQt5Widgets.so.5.15.6
11: QAction::activate(QAction::ActionEvent) in /home/max/kde/qt5/lib/libQt5Widgets.so.5.15.6
12: QMenuPrivate::activateCausedStack(QVector<QPointer<QWidget> > const&, QAction*, QAction::ActionEvent, bool) in /home/max/kde/qt5/lib/libQt5Widgets.so.5.15.6
13: QMenuPrivate::activateAction(QAction*, QAction::ActionEvent, bool) in /home/max/kde/qt5/lib/libQt5Widgets.so.5.15.6
14: QWidget::event(QEvent*) in /home/max/kde/qt5/lib/libQt5Widgets.so.5.15.6
15: QApplicationPrivate::notify_helper(QObject*, QEvent*) in /home/max/kde/qt5/lib/libQt5Widgets.so.5.15.6
16: QApplication::notify(QObject*, QEvent*) in /home/max/kde/qt5/lib/libQt5Widgets.so.5.15.6
17: QCoreApplication::notifyInternal2(QObject*, QEvent*) in /home/max/kde/qt5/lib/libQt5Core.so.5.15.6
18: QApplicationPrivate::sendMouseEvent(QWidget*, QMouseEvent*, QWidget*, QWidget*, QWidget**, QPointer<QWidget>&, bool, bool) in /home/max/kde/qt5/lib/libQt5Widgets.so.5.15.6
19: QWidgetWindow::handleMouseEvent(QMouseEvent*) in /home/max/kde/qt5/lib/libQt5Widgets.so.5.15.6
20: QWidgetWindow::event(QEvent*) in /home/max/kde/qt5/lib/libQt5Widgets.so.5.15.6
21: QApplicationPrivate::notify_helper(QObject*, QEvent*) in /home/max/kde/qt5/lib/libQt5Widgets.so.5.15.6
22: QCoreApplication::notifyInternal2(QObject*, QEvent*) in /home/max/kde/qt5/lib/libQt5Core.so.5.15.6
23: QGuiApplicationPrivate::processMouseEvent(QWindowSystemInterfacePrivate::MouseEvent*) in /home/max/kde/qt5/lib/libQt5Gui.so.5.15.6
24: QWindowSystemInterface::sendWindowSystemEvents(QFlags<QEventLoop::ProcessEventsFlag>) in /home/max/kde/qt5/lib/libQt5Gui.so.5.15.6
25: xcbSourceDispatch(_GSource*, int (*)(void*), void*) in /home/max/kde/qt5/lib/libQt5XcbQpa.so.5.15.6