Bug report #16771
Crash when closing a project with layers in edition
Status: | Closed | ||
---|---|---|---|
Priority: | Normal | ||
Assignee: | - | ||
Category: | GUI | ||
Affected QGIS version: | master | Regression?: | Yes |
Operating System: | Linux | Easy fix?: | No |
Pull Request or Patch supplied: | No | Resolution: | |
Crashes QGIS or corrupts data: | Yes | Copied to github as #: | 24670 |
Description
Steps to reproduce:
- new project
- create a memory layer
- toggle editing
- add a point
- click "new project"
- a dialog warns the project should be saved. Don't save
- a dialog warns a layer has been modified. Don't save
- the same dialog is shown a second time (?). Then it crashes
Seems to be related to QgsSnappingConfig from the backtrace:
#0 0x00007ffff4164fbe in QMetaObject::cast(QObject*) const () from /usr/lib/x86_64-linux-gnu/libQt5Core.so.5 #1 0x00007ffff53d520a in qobject_cast<QgsVectorLayer*> (object=0x2f295b0) at /usr/include/x86_64-linux-gnu/qt5/QtCore/qobject.h:518 #2 0x00007ffff574f805 in QgsSnappingConfig::removeLayers (this=0x9e1e38, layers=QList<QgsMapLayer *> = {...}) at /home/hme/src/QGIS/src/core/qgssnappingconfig.cpp:399 #3 0x00007ffff5727909 in QgsProject::onMapLayersRemoved (this=0x9e1e00, layers=QList<QgsMapLayer *> = {...}) at /home/hme/src/QGIS/src/core/qgsproject.cpp:1172 #4 0x00007ffff5735209 in QtPrivate::FunctorCall<QtPrivate::IndexesList<0>, QtPrivate::List<QList<QgsMapLayer*> const&>, void, void (QgsProject::*)(QList<QgsMapLayer*> const&)>::call (f= (void (QgsProject::*)(QgsProject * const, const QList<QgsMapLayer*> &)) 0x7ffff57278e2 <QgsProject::onMapLayersRemoved(QList<QgsMapLayer*> const&)>, o=0x9e1e00, arg=0x7fffffffb620) at /usr/include/x86_64-linux-gnu/qt5/QtCore/qobjectdefs_impl.h:501 #5 0x00007ffff5734ed7 in QtPrivate::FunctionPointer<void (QgsProject::*)(QList<QgsMapLayer*> const&)>::call<QtPrivate::List<QList<QgsMapLayer*> const&>, void> (f= (void (QgsProject::*)(QgsProject * const, const QList<QgsMapLayer*> &)) 0x7ffff57278e2 <QgsProject::onMapLayersRemoved(QList<QgsMapLayer*> const&)>, o=0x9e1e00, arg=0x7fffffffb620) at /usr/include/x86_64-linux-gnu/qt5/QtCore/qobjectdefs_impl.h:520 #6 0x00007ffff573441f in QtPrivate::QSlotObject<void (QgsProject::*)(QList<QgsMapLayer*> const&), QtPrivate::List<QList<QgsMapLayer*> const&>, void>::impl (which=1, this_=0x9e5740, r=0x9e1e00, a=0x7fffffffb620, ret=0x0) at /usr/include/x86_64-linux-gnu/qt5/QtCore/qobject_impl.h:143 #7 0x00007ffff418bbaf in QMetaObject::activate(QObject*, int, int, void**) () from /usr/lib/x86_64-linux-gnu/libQt5Core.so.5 #8 0x00007ffff5b511d0 in QgsProject::layersWillBeRemoved (this=0x9e1e00, _t1=QList<QgsMapLayer *> = {...}) at /home/hme/src/QGIS/build/src/core/moc_qgsproject.cpp:791 #9 0x00007ffff5735209 in QtPrivate::FunctorCall<QtPrivate::IndexesList<0>, QtPrivate::List<QList<QgsMapLayer*> const&>, void, void (QgsProject::*)(QList<QgsMapLayer*> const&)>::call (f= (void (QgsProject::*)(QgsProject * const, const QList<QgsMapLayer*> &)) 0x7ffff5b5117a <QgsProject::layersWillBeRemoved(QList<QgsMapLayer*> const&)>, o=0x9e1e00, arg=0x7fffffffb820) at /usr/include/x86_64-linux-gnu/qt5/QtCore/qobjectdefs_impl.h:501 #10 0x00007ffff5734ed7 in QtPrivate::FunctionPointer<void (QgsProject::*)(QList<QgsMapLayer*> const&)>::call<QtPrivate::List<QList<QgsMapLayer*> const&>, void> (f= (void (QgsProject::*)(QgsProject * const, const QList<QgsMapLayer*> &)) 0x7ffff5b5117a <QgsProject::layersWillBeRemoved(QList<QgsMapLayer*> const&)>, o=0x9e1e00, arg=0x7fffffffb820) at /usr/include/x86_64-linux-gnu/qt5/QtCore/qobjectdefs_impl.h:520 #11 0x00007ffff573441f in QtPrivate::QSlotObject<void (QgsProject::*)(QList<QgsMapLayer*> const&), QtPrivate::List<QList<QgsMapLayer*> const&>, void>::impl (which=1, this_=0x9e4670, r=0x9e1e00, a=0x7fffffffb820, ret=0x0) ---Type <return> to continue, or q <return> to quit--- at /usr/include/x86_64-linux-gnu/qt5/QtCore/qobject_impl.h:143 #12 0x00007ffff418bbaf in QMetaObject::activate(QObject*, int, int, void**) () from /usr/lib/x86_64-linux-gnu/libQt5Core.so.5 #13 0x00007ffff5b4beb0 in QgsMapLayerStore::layersWillBeRemoved (this=0x9e0b00, _t1=QList<QgsMapLayer *> = {...}) at /home/hme/src/QGIS/build/src/core/moc_qgsmaplayerstore.cpp:262 #14 0x00007ffff566dd39 in QgsMapLayerStore::removeMapLayers (this=0x9e0b00, layers=QList<QgsMapLayer *> = {...}) at /home/hme/src/QGIS/src/core/qgsmaplayerstore.cpp:124 #15 0x00007ffff566dae2 in QgsMapLayerStore::removeMapLayers (this=0x9e0b00, layerIds=QStringList<QString> = {...}) at /home/hme/src/QGIS/src/core/qgsmaplayerstore.cpp:99 #16 0x00007ffff566e477 in QgsMapLayerStore::removeAllMapLayers (this=0x9e0b00) at /home/hme/src/QGIS/src/core/qgsmaplayerstore.cpp:179 #17 0x00007ffff572f1b0 in QgsProject::removeAllMapLayers (this=0x9e1e00) at /home/hme/src/QGIS/src/core/qgsproject.cpp:2118 #18 0x00007ffff5721508 in QgsProject::clear (this=0x9e1e00) at /home/hme/src/QGIS/src/core/qgsproject.cpp:507 #19 0x00007ffff7186cc0 in QgisApp::closeProject (this=0xbc6040) at /home/hme/src/QGIS/src/app/qgisapp.cpp:10054 #20 0x00007ffff715e199 in QgisApp::fileNew (this=0xbc6040, promptToSaveFlag=true, forceBlank=false) at /home/hme/src/QGIS/src/app/qgisapp.cpp:4715 #21 0x00007ffff715d778 in QgisApp::fileNew (this=0xbc6040) at /home/hme/src/QGIS/src/app/qgisapp.cpp:4687 #22 0x00007ffff71361ad in QgisApp::<lambda()>::operator()(void) const (__closure=0x7fffffffbdc0) at /home/hme/src/QGIS/src/app/qgisapp.cpp:1761 #23 0x00007ffff71a03e1 in QtPrivate::FunctorCall<QtPrivate::IndexesList<>, QtPrivate::List<>, void, QgisApp::createActions()::<lambda()> >::call(QgisApp::<lambda()>, void **) (f=..., arg=0x7fffffffbf80) at /usr/include/x86_64-linux-gnu/qt5/QtCore/qobjectdefs_impl.h:495 #24 0x00007ffff719f86d in QtPrivate::Functor<QgisApp::createActions()::<lambda()>, 0>::call<QtPrivate::List<>, void>(QgisApp::<lambda()> &, void *, void **) (f=..., arg=0x7fffffffbf80) at /usr/include/x86_64-linux-gnu/qt5/QtCore/qobjectdefs_impl.h:552 #25 0x00007ffff719dacc in QtPrivate::QFunctorSlotObject<QgisApp::createActions()::<lambda()>, 0, QtPrivate::List<>, void>::impl(int, QtPrivate::QSlotObjectBase *, QObject *, void **, bool *) (which=1, this_=0xf9fb60, r=0xbc6040, a=0x7fffffffbf80, ret=0x0) at /usr/include/x86_64-linux-gnu/qt5/QtCore/qobject_impl.h:192 #26 0x00007ffff418bbaf in QMetaObject::activate(QObject*, int, int, void**) () from /usr/lib/x86_64-linux-gnu/libQt5Core.so.5 #27 0x00007ffff4a46412 in QAction::triggered(bool) () from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5 #28 0x00007ffff4a48898 in QAction::activate(QAction::ActionEvent) () from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5 #29 0x00007ffff4b4e560 in ?? () from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5 #30 0x00007ffff4b4e694 in QAbstractButton::mouseReleaseEvent(QMouseEvent*) () from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5 #31 0x00007ffff4c1314a in QToolButton::mouseReleaseEvent(QMouseEvent*) () from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5 ---Type <return> to continue, or q <return> to quit--- #32 0x00007ffff4a92f88 in QWidget::event(QEvent*) () from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5 #33 0x00007ffff4c13229 in QToolButton::event(QEvent*) () from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5 #34 0x00007ffff4a5005c in QApplicationPrivate::notify_helper(QObject*, QEvent*) () from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5 #35 0x00007ffff4a55c19 in QApplication::notify(QObject*, QEvent*) () from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5 #36 0x00007ffff553370f in QgsApplication::notify (this=0x7fffffffd8b0, receiver=0xc10ea0, event=0x7fffffffc530) at /home/hme/src/QGIS/src/core/qgsapplication.cpp:298 #37 0x00007ffff415d38b in QCoreApplication::notifyInternal(QObject*, QEvent*) () from /usr/lib/x86_64-linux-gnu/libQt5Core.so.5 #38 0x00007ffff4a54b32 in QApplicationPrivate::sendMouseEvent(QWidget*, QMouseEvent*, QWidget*, QWidget*, QWidget**, QPointer<QWidget>&, bool) () from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5 #39 0x00007ffff4aad57b in ?? () from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5 #40 0x00007ffff4aafb3b in ?? () from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5 #41 0x00007ffff4a5005c in QApplicationPrivate::notify_helper(QObject*, QEvent*) () from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5 #42 0x00007ffff4a55516 in QApplication::notify(QObject*, QEvent*) () from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5 #43 0x00007ffff553370f in QgsApplication::notify (this=0x7fffffffd8b0, receiver=0x2dddb90, event=0x7fffffffc9e0) at /home/hme/src/QGIS/src/core/qgsapplication.cpp:298 #44 0x00007ffff415d38b in QCoreApplication::notifyInternal(QObject*, QEvent*) () from /usr/lib/x86_64-linux-gnu/libQt5Core.so.5 #45 0x00007ffff449f4e1 in QGuiApplicationPrivate::processMouseEvent(QWindowSystemInterfacePrivate::MouseEvent*) () from /usr/lib/x86_64-linux-gnu/libQt5Gui.so.5 #46 0x00007ffff44a11a5 in QGuiApplicationPrivate::processWindowSystemEvent(QWindowSystemInterfacePrivate::WindowSystemEvent*) () from /usr/lib/x86_64-linux-gnu/libQt5Gui.so.5 #47 0x00007ffff4484f08 in QWindowSystemInterface::sendWindowSystemEvents(QFlags<QEventLoop::ProcessEventsFlag>) () from /usr/lib/x86_64-linux-gnu/libQt5Gui.so.5 #48 0x00007fffd63b6060 in ?? () from /usr/lib/x86_64-linux-gnu/libQt5XcbQpa.so.5 #49 0x00007fffecb1e197 in g_main_context_dispatch () from /lib/x86_64-linux-gnu/libglib-2.0.so.0 #50 0x00007fffecb1e3f0 in ?? () from /lib/x86_64-linux-gnu/libglib-2.0.so.0 #51 0x00007fffecb1e49c in g_main_context_iteration () from /lib/x86_64-linux-gnu/libglib-2.0.so.0 #52 0x00007ffff41b37cf in QEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) () from /usr/lib/x86_64-linux-gnu/libQt5Core.so.5 #53 0x00007ffff415ab4a in QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) () from /usr/lib/x86_64-linux-gnu/libQt5Core.so.5 #54 0x00007ffff4162bec in QCoreApplication::exec() () from /usr/lib/x86_64-linux-gnu/libQt5Core.so.5 #55 0x000000000040fd02 in main (argc=1, argv=0x7fffffffdcf8) at /home/hme/src/QGIS/src/app/main.cpp:1315
QGIS commit 51fde8e08fe
Associated revisions
Fix crash when closing a project with layers in edition (fixes #16771)
Delete layers from project & not through layers tree, avoiding
double deletion of layers.
History
#1 Updated by C M over 7 years ago
When I try to reproduce the crash, the call of QgsProject::clear()
will:
- Clear all layers into tree, that will request effective layer deletion,
- Clear all map layers, that have been previously destroyed.
First call will invoke a method that will request the same code of second call but in an asynchronous manner. So 2nd call is executed first & 1st call will be called after the 2nd has finished. This will explain why 2 dialogs are displayed. Cancelling the second dialog box will use an invalid pointer to deleted layer.
I have no crash if I remove the 2nd call - removeAllMapLayers()
- supposing that deleting all layers into tree will remove all map layers too. Is this correct ?
#2 Updated by Regis Haubourg about 7 years ago
PR here https://github.com/qgis/QGIS/pull/4911
Hugo and Clément, what's the status here?
#3 Updated by C M about 7 years ago
- % Done changed from 0 to 100
- Status changed from Open to Closed
Applied in changeset qgis|37052db39aca4824532d71dd182b8d2a9d634d05.