SUMMARY After import of a large Rose MDL file with very many diagrams, Umbrello crashed on exit. In Settings -> Configure Umbrello -> General Settings "Miscellaneous", "Use tabbed diagrams" had been active. STEPS TO REPRODUCE 1. Start Umbrello, ensure that "Use tabbed diagrams" is activated. 2. Load a model with very many diagrams (in my case resulting form a Rose model import - but may also happen in other usage scenarios) 3. Click around, select different diagrams, perhaps rearrange some diagram objects 4. Select File -> Quit or press the mainwindow "X" corner symbol 5. On dialog "The current file has been modified. Do you want to save it?" press Discard. OBSERVED RESULT Segfault with following backtrace: #4 in std::__atomic_base<int>::operator++() (this=0x7f379ab77901 <typeinfo name for QFutureWatcherBase+17>) at /usr/include/c++/10/bits/atomic_base.h:326 #5 in QAtomicOps<int>::ref<int>(std::atomic<int>&) (_q_value=...) at /usr/include/qt5/QtCore/qatomic_cxx11.h:283 #6 in QBasicAtomicInteger<int>::ref() (this=0x7f379ab77901 <typeinfo name for QFutureWatcherBase+17>) at /usr/include/qt5/QtCore/qbasicatomic.h:118 #7 in QtPrivate::RefCount::ref() (this=0x7f379ab77901 <typeinfo name for QFutureWatcherBase+17>) at /usr/include/qt5/QtCore/qrefcount.h:61 #8 in QString::QString(QString const&) (this=0x7ffc93c3e568, other=...) at /usr/include/qt5/QtCore/qstring.h:1094 #9 in UMLScene::documentation() const (this=0x7f3790028f20) at /u/umbrello/umlscene.cpp:359 #10 in DocWindow::isModified() (this=0x203c700) at /u/umbrello/docwindow.cpp:353 #11 in DocWindow::updateDocumentation(bool, bool) (this=0x203c700, clear=true, startup=false) at /u/umbrello/docwindow.cpp:278 #12 in DocWindow::showDocumentation(UMLScene*, bool) (this=0x203c700, scene=0xd6da320, overwrite=false) at /u/umbrello/docwindow.cpp:185 #13 in UMLDoc::changeCurrentView(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >) (this=0x1a23be0, id="49A5573701AF") at /u/umbrello/umldoc.cpp:1790 #14 in UMLApp::slotTabChanged(int) (this=0x18fec30, index=0) at /u/umbrello/uml.cpp:3199 #15 in UMLApp::qt_static_metacall(QObject*, QMetaObject::Call, int, void**) (_o=0x18fec30, _c=QMetaObject::InvokeMetaMethod, _id=81, _a=0x7ffc93c3e910) at /u/build/umbrello/libumbrello_autogen/EWIEGA46WW/moc_uml.cpp:560 #16 in doActivate<false>(QObject*, int, void**) (sender=0x1f48d80, signal_index=7, argv=argv@entry=0x7ffc93c3e910) at ../../include/QtCore/../../src/corelib/kernel/qobjectdefs_impl.h:395 #17 in QMetaObject::activate(QObject*, QMetaObject const*, int, void**) (sender=<optimized out>, m=m@entry=0x7f379bbd68c0 <QTabWidget::staticMetaObject>, local_signal_index=local_signal_index@entry=0, argv=argv@entry=0x7ffc93c3e910) at kernel/qobject.cpp:3946 #18 in QTabWidget::currentChanged(int) (this=<optimized out>, _t1=<optimized out>) at .moc/moc_qtabwidget.cpp:326 #19 in doActivate<false>(QObject*, int, void**) (sender=0x1f51020, signal_index=7, argv=argv@entry=0x7ffc93c3ea30) at ../../include/QtCore/../../src/corelib/kernel/qobjectdefs_impl.h:395 #20 in QMetaObject::activate(QObject*, QMetaObject const*, int, void**) (sender=sender@entry=0x1f51020, m=m@entry=0x7f379bbd5320 <QTabBar::staticMetaObject>, local_signal_index=local_signal_index@entry=0, argv=argv@entry=0x7ffc93c3ea30) at kernel/qobject.cpp:3946 #21 in QTabBar::currentChanged(int) (this=this@entry=0x1f51020, _t1=<optimized out>, _t1@entry=0) at .moc/moc_qtabbar.cpp:338 #22 in QTabBar::setCurrentIndex(int) (this=this@entry=0x1f51020, index=index@entry=0) at widgets/qtabbar.cpp:1450 #23 in QTabBar::removeTab(int) (this=0x1f51020, index=<optimized out>, index@entry=0) at widgets/qtabbar.cpp:1094 #24 in QTabWidgetPrivate::_q_removeTab(int) (index=0, this=<optimized out>) at widgets/qtabwidget.cpp:802 #25 QTabWidget::qt_static_metacall(QObject*, QMetaObject::Call, int, void**) (_o=<optimized out>, _c=<optimized out>, _id=<optimized out>, _a=<optimized out>) at .moc/moc_qtabwidget.cpp:178 #26 0x00007f379aac78a0 in doActivate<false>(QObject*, int, void**) (sender=0x1f50b40, signal_index=8, argv=argv@entry=0x7ffc93c3ec10) at ../../include/QtCore/../../src/corelib/kernel/qobjectdefs_impl.h:395 #27 in QMetaObject::activate(QObject*, QMetaObject const*, int, void**) (sender=<optimized out>, m=m@entry=0x7f379bbd4d00 <QStackedWidget::staticMetaObject>, local_signal_index=local_signal_index@entry=1, argv=argv@entry=0x7ffc93c3ec10) at kernel/qobject.cpp:3946 #28 in QStackedWidget::widgetRemoved(int) (this=<optimized out>, _t1=<optimized out>) at .moc/moc_qstackedwidget.cpp:226 #29 in doActivate<false>(QObject*, int, void**) (sender=0x1f50a50, signal_index=3, argv=argv@entry=0x7ffc93c3ed30) at ../../include/QtCore/../../src/corelib/kernel/qobjectdefs_impl.h:395 #30 in QMetaObject::activate(QObject*, QMetaObject const*, int, void**) (sender=sender@entry=0x1f50a50, m=m@entry=0x7f379bbc5360 <QStackedLayout::staticMetaObject>, local_signal_index=local_signal_index@entry=0, argv=argv@entry=0x7ffc93c3ed30) at kernel/qobject.cpp:3946 #31 in QStackedLayout::widgetRemoved(int) (this=this@entry=0x1f50a50, _t1=<optimized out>, _t1@entry=0) at .moc/moc_qstackedlayout.cpp:220 #32 in QStackedLayout::takeAt(int) (this=0x1f50a50, index=0) at kernel/qstackedlayout.cpp:280 #33 in removeWidgetRecursively(QLayoutItem*, QObject*) (li=<optimized out>, w=0xd71e8c0) at kernel/qlayout.cpp:573 #34 in QLayout::widgetEvent(QEvent*) (this=<optimized out>, e=e@entry=0x7ffc93c3ee90) at ../../include/QtCore/../../src/corelib/kernel/qcoreevent.h:354 #35 in QApplicationPrivate::notify_helper(QObject*, QEvent*) (this=<optimized out>, receiver=0x1f50b40, e=0x7ffc93c3ee90) at kernel/qapplication.cpp:3621 #36 in QCoreApplication::notifyInternal2(QObject*, QEvent*) (receiver=0x1f50b40, event=0x7ffc93c3ee90) at ../../include/QtCore/5.15.2/QtCore/private/../../../../../src/corelib/thread/qthread_p.h:325 #37 in QObjectPrivate::setParent_helper(QObject*) (this=0xd701ec0, o=0x0) at kernel/qobject.cpp:2149 #38 in QObject::~QObject() (this=<optimized out>, __in_chrg=<optimized out>) at kernel/qobject.cpp:1093 #39 in UMLView::~UMLView() (this=0xd71e8c0, __in_chrg=<optimized out>) at /u/umbrello/umlview.cpp:48 #40 in UMLView::~UMLView() (this=0xd71e8c0, __in_chrg=<optimized out>) at /u/umbrello/umlview.cpp:51 #41 in qDeleteAll<QList<QPointer<UMLView> >::const_iterator>(QList<QPointer<UMLView> >::const_iterator, QList<QPointer<UMLView> >::const_iterator) (begin=..., end=...) at /usr/include/qt5/QtCore/qalgorithms.h:320 #42 in qDeleteAll<QList<QPointer<UMLView> > >(QList<QPointer<UMLView> > const&) (c=...) at /usr/include/qt5/QtCore/qalgorithms.h:328 #43 in UMLFolder::~UMLFolder() (this=0xd6d9cc0, __in_chrg=<optimized out>) at /u/umbrello/uml1model/folder.cpp:52 #44 in UMLFolder::~UMLFolder() (this=0xd6d9cc0, __in_chrg=<optimized out>) at /u/umbrello/uml1model/folder.cpp:54 #45 in UMLPackage::removeAllObjects() (this=0xbc3abc0) at /u/umbrello/uml1model/package.cpp:259 #46 in UMLPackage::removeAllObjects() (this=0x91ac220) at /u/umbrello/uml1model/package.cpp:257 #47 in UMLPackage::removeAllObjects() (this=0x91a6150) at /u/umbrello/uml1model/package.cpp:257 #48 in UMLPackage::removeAllObjects() (this=0x21b81a0) at /u/umbrello/uml1model/package.cpp:257 #49 in UMLPackage::removeAllObjects() (this=0x1c6db50) at /u/umbrello/uml1model/package.cpp:257 #50 in UMLDoc::removeAllObjects() (this=0x1a23be0) at /u/umbrello/umldoc.cpp:2931 #51 in UMLDoc::closeDocument() (this=0x1a23be0) at /u/umbrello/umldoc.cpp:432 #52 in UMLDoc::saveModified() (this=0x1a23be0) at /u/umbrello/umldoc.cpp:386 #53 in UMLApp::queryClose() (this=0x18fec30) at /u/umbrello/uml.cpp:1235 #54 in KMainWindow::closeEvent(QCloseEvent*) () at /usr/lib64/libKF5XmlGui.so.5 EXPECTED RESULT Don't crash. SOFTWARE/OS VERSIONS Umbrello: git master @ 526bd5ac Linux/KDE Plasma: openSuSE Tumbleweed 20201129 KDE Plasma Version: 5.20.3 KDE Frameworks Version: 5.76.0 Qt Version: 5.15.2
Git commit 9d9800c31411b0c8b0cf253c0dfddc62fbaa7d2d by Oliver Kellogg. Committed on 12/12/2020 at 23:51. Pushed by okellogg into branch 'master'. Fix for 'Crash on exit with tabbed diagrams enabled' umbrello/uml.cpp - In function slotTabChanged(int index) / slotTabChanged(QWidget* tab) do not call m_doc->changeCurrentView() is s_shuttingDown is true. Reason: Calling changeCurrentView accesses objects which have already been deconstructed. M +2 -2 umbrello/uml.cpp https://invent.kde.org/sdk/umbrello/commit/9d9800c31411b0c8b0cf253c0dfddc62fbaa7d2d
Git commit bd8b3b1c9f2ccbd54b7fb34d95db8e6d8d94df0b by Oliver Kellogg. Committed on 13/12/2020 at 16:30. Pushed by okellogg into branch 'master'. Followup to commit 9d9800c fix for crash on exit with tabbed diagrams There was a further crash on closing in the code path UMLApp::slotFileClose() => slotFileNew() => m_doc->newDocument() due to DiagramsModel::m_views not having been reset to empty. This caused access to stale UMLView objects already deconstructed. umbrello/models/diagramsmodel.{h,cpp} - New function removeAllDiagrams clears content of m_views. umbrello/uml.cpp - In function slotFileClose call diagramsModel()->removeAllDiagrams() on m_doc before calling slotFileNew(). M +10 -0 umbrello/models/diagramsmodel.cpp M +1 -0 umbrello/models/diagramsmodel.h M +2 -0 umbrello/uml.cpp https://invent.kde.org/sdk/umbrello/commit/bd8b3b1c9f2ccbd54b7fb34d95db8e6d8d94df0b