Bug report #14505
Updated by Giovanni Manghi almost 7 years ago
I'm developing a QT application which used QGIS 2.12 as the GIS platform. And during the developing, i compilered QGIS(git clone with tag final-2_12_3) with debug info on my local machine for debugging purpose. And also i used debug version of QT 4.8.6 underhood for the same reason. When i try to load the sample data raster/SR_50M_alaska_nad.tif from the official site, i got the following error in the console:
ASSERT: "last >= first" in file kernel/qabstractitemmodel.cpp, line 2413
The program has unexpectedly finished.
and on mac OS X 10.10.5 the crash report are as follow:
Thread 0 Crashed:: Dispatch queue: com.apple.main-thread
0 libsystem_kernel.dylib 0x00007fff8cd24286 __pthread_kill + 10
1 libsystem_c.dylib 0x00007fff8fcaf9ab abort + 129
2 QtCore_debug 0x00000001086e569f qt_message_output(QtMsgType, char const*) + 255 (qglobal.cpp:2364)
3 QtCore_debug 0x00000001086e5a7a qt_message(QtMsgType, char const*, __va_list_tag*) + 426 (qglobal.cpp:2405)
4 QtCore_debug 0x00000001086e4f7f qFatal(char const*, ...) + 367 (qglobal.cpp:2588)
5 QtCore_debug 0x00000001086e502f qt_assert(char const*, char const*, int) + 47 (qglobal.cpp:2055)
6 QtCore_debug 0x00000001088743c4 QAbstractItemModel::beginInsertRows(QModelIndex const&, int, int) + 116 (qabstractitemmodel.cpp:2413)
7 org.qgis.qgis2_core 0x0000000106defbd9 QgsLayerTreeModel::addLegendToLayer(QgsLayerTreeLayer*) + 1481
8 org.qgis.qgis2_core 0x0000000106df0f4d QgsLayerTreeModel::connectToLayer(QgsLayerTreeLayer*) + 269
9 org.qgis.qgis2_core 0x0000000106df0bf8 QgsLayerTreeModel::nodeAddedChildren(QgsLayerTreeNode*, int, int) + 312
10 org.qgis.qgis2_core 0x000000010736f2ac QgsLayerTreeModel::qt_static_metacall(QObject*, QMetaObject::Call, int, void**) + 236
11 QtCore_debug 0x00000001088ad9d4 QMetaObject::activate(QObject*, QMetaObject const*, int, void**) + 2180 (qobject.cpp:3567)
12 org.qgis.qgis2_core 0x000000010736fead QgsLayerTreeNode::addedChildren(QgsLayerTreeNode*, int, int) + 109
13 org.qgis.qgis2_core 0x0000000106e0343f QgsLayerTreeNode::insertChildrenPrivate(int, QList<QgsLayerTreeNode*>) + 1327
14 org.qgis.qgis2_core 0x0000000106de54de QgsLayerTreeGroup::insertChildNodes(int, QList<QgsLayerTreeNode*> const&) + 174
15 org.qgis.qgis2_core 0x0000000106e04631 QgsLayerTreeRegistryBridge::layersAdded(QList<QgsMapLayer*> const&) + 1009
16 org.qgis.qgis2_core 0x0000000107370402 QgsLayerTreeRegistryBridge::qt_static_metacall(QObject*, QMetaObject::Call, int, void**) + 258
17 QtCore_debug 0x00000001088ad9d4 QMetaObject::activate(QObject*, QMetaObject const*, int, void**) + 2180 (qobject.cpp:3567)
18 org.qgis.qgis2_core 0x000000010735c552 QgsMapLayerRegistry::legendLayersAdded(QList<QgsMapLayer*>) + 66
19 org.qgis.qgis2_core 0x0000000106fd1898 QgsMapLayerRegistry::addMapLayers(QList<QgsMapLayer*> const&, bool, bool) + 904
20 libgui.1.dylib 0x0000000106c5b5d4 my_appliction::addRasterLayer(QgsRasterLayer*) + 212
21 libgui.1.dylib 0x0000000106c5aed4 my_appliction::addRasterLayerPrivate(QString const&, QString const&, QString const&, bool, bool) + 1044
22 libgui.1.dylib 0x0000000106c5a4d9 my_appliction::addRasterLayers(QStringList const&, bool) + 761
23 libgui.1.dylib 0x0000000106c5a190 my_appliction::addRasterLayer() + 208
24 libgui.1.dylib 0x0000000106c61cdb my_appliction::qt_static_metacall(QObject*, QMetaObject::Call, int, void**) + 443 (moc_mpsmainwindow.cpp:108)
25 QtCore_debug 0x00000001088ad9d4 QMetaObject::activate(QObject*, QMetaObject const*, int, void**) + 2180 (qobject.cpp:3567)
26 QtGui_debug 0x0000000108e1b30b QAction::triggered(bool) + 75 (moc_qaction.cpp:277)
27 QtGui_debug 0x0000000108e1b112 QAction::activate(QAction::ActionEvent) + 402 (qaction.cpp:1259)
28 QtGui_debug 0x0000000108d8bf87 QAction::trigger() + 23 (qaction.h:218)
29 QtGui_debug 0x00000001094ff183 QToolButton::nextCheckState() + 83 (qtoolbutton.cpp:1153)
30 QtGui_debug 0x00000001093b36c4 QAbstractButtonPrivate::click() + 260 (qabstractbutton.cpp:530)
31 QtGui_debug 0x00000001093b4c5c QAbstractButton::mouseReleaseEvent(QMouseEvent*) + 220 (qabstractbutton.cpp:1124)
32 QtGui_debug 0x00000001094fea44 QToolButton::mouseReleaseEvent(QMouseEvent*) + 52 (qtoolbutton.cpp:724)
33 QtGui_debug 0x0000000108eaf5ac QWidget::event(QEvent*) + 524 (qwidget.cpp:8390)
34 QtGui_debug 0x00000001093b4a7e QAbstractButton::event(QEvent*) + 446 (qabstractbutton.cpp:1082)
35 QtGui_debug 0x00000001094ff219 QToolButton::event(QEvent*) + 137 (qtoolbutton.cpp:1168)
36 QtGui_debug 0x0000000108e29f2c QApplicationPrivate::notify_helper(QObject*, QEvent*) + 396 (qapplication.cpp:4565)
37 QtGui_debug 0x0000000108e2d32a QApplication::notify(QObject*, QEvent*) + 4874 (qapplication.cpp:4108)
38 org.qgis.qgis2_core 0x0000000106e4fa44 QgsApplication::notify(QObject*, QEvent*) + 148
39 QtCore_debug 0x0000000108885784 QCoreApplication::notifyInternal(QObject*, QEvent*) + 180 (qcoreapplication.cpp:953)
40 QtGui_debug 0x0000000108d5e0df QCoreApplication::sendSpontaneousEvent(QObject*, QEvent*) + 95 (qcoreapplication.h:234)
41 QtGui_debug 0x0000000108e2afc1 QApplicationPrivate::sendMouseEvent(QWidget*, QMouseEvent*, QWidget*, QWidget*, QWidget**, QPointer<QWidget>&, bool) + 1281 (qapplication.cpp:3171)
42 QtGui_debug 0x0000000108d9206a qt_mac_handleMouseEvent(NSEvent*, QEvent::Type, Qt::MouseButton, QWidget*, bool) + 1338 (qt_cocoa_helpers_mac.mm:1269)
43 QtGui_debug 0x0000000108d7cd25 -[QCocoaView mouseUp:] + 69 (qcocoaview_mac.mm:564)
44 com.apple.AppKit 0x00007fff8e536e37 -[NSWindow _reallySendEvent:isDelayedEvent:] + 648
45 com.apple.AppKit 0x00007fff8dec9c86 -[NSWindow sendEvent:] + 470
46 QtGui_debug 0x0000000108d84642 -[QCocoaWindow sendEvent:] + 178 (qcocoasharedwindowmethods_mac_p.h:184)
47 com.apple.AppKit 0x00007fff8dec6212 -[NSApplication sendEvent:] + 2504
48 QtGui_debug 0x0000000108d8c505 -[QNSApplication sendEvent:] + 101 (qcocoaapplication_mac.mm:187)
49 com.apple.AppKit 0x00007fff8ddefb68 -[NSApplication run] + 711
50 QtGui_debug 0x0000000108d9bdf8 QEventDispatcherMac::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) + 1064 (qeventdispatcher_mac.mm:615)
51 QtCore_debug 0x0000000108880ce6 QEventLoop::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) + 166 (qeventloop.cpp:149)
52 QtCore_debug 0x0000000108880eed QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) + 493 (qeventloop.cpp:204)
53 QtCore_debug 0x0000000108885f53 QCoreApplication::exec() + 307 (qcoreapplication.cpp:1225)
54 QtGui_debug 0x0000000108e2c016 QApplication::exec() + 22 (qapplication.cpp:3823)
55 com.yourcompany.my_app 0x0000000106c4880c main + 140 (main.cpp:9)
56 com.yourcompany.my_app 0x0000000106c48774 start + 52
I done some debugging, the reason came out obvious: In the file QGIS/src/core/layertree/qgslayertreemodel.cpp, at line 1117
void QgsLayerTreeModel::addLegendToLayer( QgsLayerTreeLayer* nodeL ) {
//...
if ( ! isEmbedded ) beginInsertRows( node2index( nodeL ), 0, count - 1 );
//...
}
The var "count" have a value of 0. And there is a Assert sentance in function void QAbstractItemModel::beginInsertRows(const QModelIndex &parent, int first, int last) of class QAbstractItemModel in QT core moduel which do not allowed such situation.
And indeed, the release version of QGIS had the same problem - the value of var 'count' is 0 when loading raster file SR_50M_alaska_nad.tif. So why the official release verison of QGIS does not have a crash like my application here? According to my investigation, because it used the release version of QT 4.8.6 as well, which will replace the ASSERT sentance to no-ops during its building process. And i think(not verified) the rest of code after ASSERT in function beginInsertRows are carried out with any issue even the var 'last' with a value of -1.
I don't know this count var should have value of 0 from the business view, but it definitely possible in programming. As much i like to, but i can't fix it by just adding some guarding condition, leave that to the expert.
ASSERT: "last >= first" in file kernel/qabstractitemmodel.cpp, line 2413
The program has unexpectedly finished.
and on mac OS X 10.10.5 the crash report are as follow:
Thread 0 Crashed:: Dispatch queue: com.apple.main-thread
0 libsystem_kernel.dylib 0x00007fff8cd24286 __pthread_kill + 10
1 libsystem_c.dylib 0x00007fff8fcaf9ab abort + 129
2 QtCore_debug 0x00000001086e569f qt_message_output(QtMsgType, char const*) + 255 (qglobal.cpp:2364)
3 QtCore_debug 0x00000001086e5a7a qt_message(QtMsgType, char const*, __va_list_tag*) + 426 (qglobal.cpp:2405)
4 QtCore_debug 0x00000001086e4f7f qFatal(char const*, ...) + 367 (qglobal.cpp:2588)
5 QtCore_debug 0x00000001086e502f qt_assert(char const*, char const*, int) + 47 (qglobal.cpp:2055)
6 QtCore_debug 0x00000001088743c4 QAbstractItemModel::beginInsertRows(QModelIndex const&, int, int) + 116 (qabstractitemmodel.cpp:2413)
7 org.qgis.qgis2_core 0x0000000106defbd9 QgsLayerTreeModel::addLegendToLayer(QgsLayerTreeLayer*) + 1481
8 org.qgis.qgis2_core 0x0000000106df0f4d QgsLayerTreeModel::connectToLayer(QgsLayerTreeLayer*) + 269
9 org.qgis.qgis2_core 0x0000000106df0bf8 QgsLayerTreeModel::nodeAddedChildren(QgsLayerTreeNode*, int, int) + 312
10 org.qgis.qgis2_core 0x000000010736f2ac QgsLayerTreeModel::qt_static_metacall(QObject*, QMetaObject::Call, int, void**) + 236
11 QtCore_debug 0x00000001088ad9d4 QMetaObject::activate(QObject*, QMetaObject const*, int, void**) + 2180 (qobject.cpp:3567)
12 org.qgis.qgis2_core 0x000000010736fead QgsLayerTreeNode::addedChildren(QgsLayerTreeNode*, int, int) + 109
13 org.qgis.qgis2_core 0x0000000106e0343f QgsLayerTreeNode::insertChildrenPrivate(int, QList<QgsLayerTreeNode*>) + 1327
14 org.qgis.qgis2_core 0x0000000106de54de QgsLayerTreeGroup::insertChildNodes(int, QList<QgsLayerTreeNode*> const&) + 174
15 org.qgis.qgis2_core 0x0000000106e04631 QgsLayerTreeRegistryBridge::layersAdded(QList<QgsMapLayer*> const&) + 1009
16 org.qgis.qgis2_core 0x0000000107370402 QgsLayerTreeRegistryBridge::qt_static_metacall(QObject*, QMetaObject::Call, int, void**) + 258
17 QtCore_debug 0x00000001088ad9d4 QMetaObject::activate(QObject*, QMetaObject const*, int, void**) + 2180 (qobject.cpp:3567)
18 org.qgis.qgis2_core 0x000000010735c552 QgsMapLayerRegistry::legendLayersAdded(QList<QgsMapLayer*>) + 66
19 org.qgis.qgis2_core 0x0000000106fd1898 QgsMapLayerRegistry::addMapLayers(QList<QgsMapLayer*> const&, bool, bool) + 904
20 libgui.1.dylib 0x0000000106c5b5d4 my_appliction::addRasterLayer(QgsRasterLayer*) + 212
21 libgui.1.dylib 0x0000000106c5aed4 my_appliction::addRasterLayerPrivate(QString const&, QString const&, QString const&, bool, bool) + 1044
22 libgui.1.dylib 0x0000000106c5a4d9 my_appliction::addRasterLayers(QStringList const&, bool) + 761
23 libgui.1.dylib 0x0000000106c5a190 my_appliction::addRasterLayer() + 208
24 libgui.1.dylib 0x0000000106c61cdb my_appliction::qt_static_metacall(QObject*, QMetaObject::Call, int, void**) + 443 (moc_mpsmainwindow.cpp:108)
25 QtCore_debug 0x00000001088ad9d4 QMetaObject::activate(QObject*, QMetaObject const*, int, void**) + 2180 (qobject.cpp:3567)
26 QtGui_debug 0x0000000108e1b30b QAction::triggered(bool) + 75 (moc_qaction.cpp:277)
27 QtGui_debug 0x0000000108e1b112 QAction::activate(QAction::ActionEvent) + 402 (qaction.cpp:1259)
28 QtGui_debug 0x0000000108d8bf87 QAction::trigger() + 23 (qaction.h:218)
29 QtGui_debug 0x00000001094ff183 QToolButton::nextCheckState() + 83 (qtoolbutton.cpp:1153)
30 QtGui_debug 0x00000001093b36c4 QAbstractButtonPrivate::click() + 260 (qabstractbutton.cpp:530)
31 QtGui_debug 0x00000001093b4c5c QAbstractButton::mouseReleaseEvent(QMouseEvent*) + 220 (qabstractbutton.cpp:1124)
32 QtGui_debug 0x00000001094fea44 QToolButton::mouseReleaseEvent(QMouseEvent*) + 52 (qtoolbutton.cpp:724)
33 QtGui_debug 0x0000000108eaf5ac QWidget::event(QEvent*) + 524 (qwidget.cpp:8390)
34 QtGui_debug 0x00000001093b4a7e QAbstractButton::event(QEvent*) + 446 (qabstractbutton.cpp:1082)
35 QtGui_debug 0x00000001094ff219 QToolButton::event(QEvent*) + 137 (qtoolbutton.cpp:1168)
36 QtGui_debug 0x0000000108e29f2c QApplicationPrivate::notify_helper(QObject*, QEvent*) + 396 (qapplication.cpp:4565)
37 QtGui_debug 0x0000000108e2d32a QApplication::notify(QObject*, QEvent*) + 4874 (qapplication.cpp:4108)
38 org.qgis.qgis2_core 0x0000000106e4fa44 QgsApplication::notify(QObject*, QEvent*) + 148
39 QtCore_debug 0x0000000108885784 QCoreApplication::notifyInternal(QObject*, QEvent*) + 180 (qcoreapplication.cpp:953)
40 QtGui_debug 0x0000000108d5e0df QCoreApplication::sendSpontaneousEvent(QObject*, QEvent*) + 95 (qcoreapplication.h:234)
41 QtGui_debug 0x0000000108e2afc1 QApplicationPrivate::sendMouseEvent(QWidget*, QMouseEvent*, QWidget*, QWidget*, QWidget**, QPointer<QWidget>&, bool) + 1281 (qapplication.cpp:3171)
42 QtGui_debug 0x0000000108d9206a qt_mac_handleMouseEvent(NSEvent*, QEvent::Type, Qt::MouseButton, QWidget*, bool) + 1338 (qt_cocoa_helpers_mac.mm:1269)
43 QtGui_debug 0x0000000108d7cd25 -[QCocoaView mouseUp:] + 69 (qcocoaview_mac.mm:564)
44 com.apple.AppKit 0x00007fff8e536e37 -[NSWindow _reallySendEvent:isDelayedEvent:] + 648
45 com.apple.AppKit 0x00007fff8dec9c86 -[NSWindow sendEvent:] + 470
46 QtGui_debug 0x0000000108d84642 -[QCocoaWindow sendEvent:] + 178 (qcocoasharedwindowmethods_mac_p.h:184)
47 com.apple.AppKit 0x00007fff8dec6212 -[NSApplication sendEvent:] + 2504
48 QtGui_debug 0x0000000108d8c505 -[QNSApplication sendEvent:] + 101 (qcocoaapplication_mac.mm:187)
49 com.apple.AppKit 0x00007fff8ddefb68 -[NSApplication run] + 711
50 QtGui_debug 0x0000000108d9bdf8 QEventDispatcherMac::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) + 1064 (qeventdispatcher_mac.mm:615)
51 QtCore_debug 0x0000000108880ce6 QEventLoop::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) + 166 (qeventloop.cpp:149)
52 QtCore_debug 0x0000000108880eed QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) + 493 (qeventloop.cpp:204)
53 QtCore_debug 0x0000000108885f53 QCoreApplication::exec() + 307 (qcoreapplication.cpp:1225)
54 QtGui_debug 0x0000000108e2c016 QApplication::exec() + 22 (qapplication.cpp:3823)
55 com.yourcompany.my_app 0x0000000106c4880c main + 140 (main.cpp:9)
56 com.yourcompany.my_app 0x0000000106c48774 start + 52
I done some debugging, the reason came out obvious: In the file QGIS/src/core/layertree/qgslayertreemodel.cpp, at line 1117
void QgsLayerTreeModel::addLegendToLayer( QgsLayerTreeLayer* nodeL ) {
//...
if ( ! isEmbedded ) beginInsertRows( node2index( nodeL ), 0, count - 1 );
//...
}
The var "count" have a value of 0. And there is a Assert sentance in function void QAbstractItemModel::beginInsertRows(const QModelIndex &parent, int first, int last) of class QAbstractItemModel in QT core moduel which do not allowed such situation.
And indeed, the release version of QGIS had the same problem - the value of var 'count' is 0 when loading raster file SR_50M_alaska_nad.tif. So why the official release verison of QGIS does not have a crash like my application here? According to my investigation, because it used the release version of QT 4.8.6 as well, which will replace the ASSERT sentance to no-ops during its building process. And i think(not verified) the rest of code after ASSERT in function beginInsertRows are carried out with any issue even the var 'last' with a value of -1.
I don't know this count var should have value of 0 from the business view, but it definitely possible in programming. As much i like to, but i can't fix it by just adding some guarding condition, leave that to the expert.