Bug report #16771

Crash when closing a project with layers in edition

Added by Hugo Mercier almost 3 years ago. Updated almost 3 years ago.

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

Revision 37052db3
Added by C M almost 3 years ago

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 almost 3 years ago

When I try to reproduce the crash, the call of QgsProject::clear() will:

  1. Clear all layers into tree, that will request effective layer deletion,
  2. 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 almost 3 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 almost 3 years ago

  • % Done changed from 0 to 100
  • Status changed from Open to Closed

Also available in: Atom PDF