https://bugs.kde.org/show_bug.cgi?id=381974

--- Comment #3 from Jiri Palecek <jpale...@web.de> ---
Hello

I tried to get to the bottom of this crash, because I encountered it several
times (about once a week-once a month). My system is Debian sid, Plasma 5.8.7
and Qt 5.7.1. The backtrace I got was:

Thread 1 (Thread 0xafa61200 (LWP 2190)):
#0  0xb77d8cf9 in __kernel_vsyscall ()
#1  0xb4d412fa in nanosleep () at ../sysdeps/unix/syscall-template.S:84
#2  0xb4d41225 in __sleep (seconds=0) at ../sysdeps/posix/sleep.c:55
#3  0xb77a1c3a in ?? () from /usr/lib/i386-linux-gnu/libKF5Crash.so.5
#4  0xb77a23e0 in ?? () from /usr/lib/i386-linux-gnu/libKF5Crash.so.5
#5  0xb77a2860 in KCrash::defaultCrashHandler(int) () from
/usr/lib/i386-linux-gnu/libKF5Crash.so.5
#6  <signal handler called>
#7  QSortFilterProxyModelPrivate::updateChildrenMapping
(this=this@entry=0x80c51650, source_parent=...,
parent_mapping=parent_mapping@entry=0x81a6f338, start=<optimized out>,
end=<optimized out>, delta_item_count=<optimized out>, remove=true,
orient=Qt::Vertical)
    at itemmodels/qsortfilterproxymodel.cpp:975
#8  0xb51ecd3f in QSortFilterProxyModelPrivate::source_items_removed
(orient=Qt::Vertical, end=<optimized out>, start=0, source_parent=...,
this=0x80c51650) at itemmodels/qsortfilterproxymodel.cpp:917
---Type <return> to continue, or q <return> to quit---
#9  QSortFilterProxyModelPrivate::_q_sourceRowsRemoved (this=0x80c51650,
source_parent=..., start=0, end=<optimized out>) at
itemmodels/qsortfilterproxymodel.cpp:1424
#10 0xb51f4b8d in QSortFilterProxyModel::qt_static_metacall (_o=0x80c4af78,
_c=QMetaObject::InvokeMetaMethod, _id=14, _a=0xbfc79d1c) at
.moc/moc_qsortfilterproxymodel.cpp:211
#11 0xb5257fdb in QMetaObject::activate (sender=<optimized out>,
signalOffset=<optimized out>, local_signal_index=<optimized out>,
argv=<optimized out>) at kernel/qobject.cpp:3740
#12 0xb525885d in QMetaObject::activate (sender=0x80c5c490, m=0xb54a1fd0
<QAbstractItemModel::staticMetaObject>, local_signal_index=12, argv=0xbfc79d1c)
at kernel/qobject.cpp:3602
#13 0xb52d6821 in QAbstractItemModel::rowsRemoved (this=0x80c5c490, _t1=...,
_t2=<optimized out>, _t3=<optimized out>) at
.moc/moc_qabstractitemmodel.cpp:615
#14 0xb51cc349 in QAbstractItemModel::endRemoveRows (this=0x80c5c490) at
itemmodels/qabstractitemmodel.cpp:2715
#15 0xa42f76f2 in
TaskManager::TaskGroupingProxyModel::Private::sourceRowsAboutToBeRemoved
(this=0x80c31898, parent=..., first=7, last=7) at
./libtaskmanager/taskgroupingproxymodel.cpp:197
#16 0xa42fafed in TaskManager::TaskGroupingProxyModel::qt_static_metacall
(_o=0x80c5c490, _c=QMetaObject::InvokeMetaMethod, _id=7, _a=0xbfc79f6c) at
./obj-i686-linux-gnu/libtaskmanager/moc_taskgroupingproxymodel.cpp:152
#17 0xb5257fdb in QMetaObject::activate (sender=<optimized out>,
signalOffset=<optimized out>, local_signal_index=<optimized out>,
argv=<optimized out>) at kernel/qobject.cpp:3740
#18 0xb525885d in QMetaObject::activate (sender=0x80c5c048, m=0xb54a1fd0
<QAbstractItemModel::staticMetaObject>, local_signal_index=11, argv=0xbfc79f6c)
at kernel/qobject.cpp:3602
#19 0xb52d67b1 in QAbstractItemModel::rowsAboutToBeRemoved (this=0x80c5c048,
_t1=..., _t2=<optimized out>, _t3=<optimized out>) at
.moc/moc_qabstractitemmodel.cpp:608
#20 0xb51cbc00 in QAbstractItemModel::beginRemoveRows (this=0x80c5c048,
parent=..., first=7, last=7) at itemmodels/qabstractitemmodel.cpp:2698
#21 0xb51f24f0 in QSortFilterProxyModelPrivate::remove_proxy_interval
(emit_signal=true, orient=Qt::Vertical, proxy_parent=..., proxy_end=7,
proxy_start=7, proxy_to_source=..., source_to_proxy=..., this=0x80c94388) at
itemmodels/qsortfilterproxymodel.cpp:583
#22 QSortFilterProxyModelPrivate::remove_source_items (this=<optimized out>,
source_to_proxy=..., proxy_to_source=..., source_items=..., source_parent=...,
orient=Qt::Vertical, emit_signal=true) at
itemmodels/qsortfilterproxymodel.cpp:565
#23 0xb51f26cb in
QSortFilterProxyModelPrivate::source_items_about_to_be_removed (this=<optimized
out>, source_parent=..., start=<optimized out>, end=<optimized out>,
orient=<optimized out>) at itemmodels/qsortfilterproxymodel.cpp:866
#24 0xb51f4b6d in QSortFilterProxyModelPrivate::_q_sourceRowsAboutToBeRemoved
(end=7, start=<optimized out>, source_parent=..., this=<optimized out>) at
itemmodels/qsortfilterproxymodel.cpp:1417
#25 QSortFilterProxyModel::qt_static_metacall (_o=0x80c5c048,
_c=QMetaObject::InvokeMetaMethod, _id=13, _a=0xbfc7a23c) at
.moc/moc_qsortfilterproxymodel.cpp:210
#26 0xb5257fdb in QMetaObject::activate (sender=<optimized out>,
signalOffset=<optimized out>, local_signal_index=<optimized out>,
argv=<optimized out>) at kernel/qobject.cpp:3740
#27 0xb525885d in QMetaObject::activate (sender=0x80c5a490, m=0xb54a1fd0
<QAbstractItemModel::staticMetaObject>, local_signal_index=11, argv=0xbfc7a23c)
at kernel/qobject.cpp:3602
#28 0xb52d67b1 in QAbstractItemModel::rowsAboutToBeRemoved (this=0x80c5a490,
_t1=..., _t2=<optimized out>, _t3=<optimized out>) at
.moc/moc_qabstractitemmodel.cpp:608
#29 0xb51cbc00 in QAbstractItemModel::beginRemoveRows (this=0x80c5a490,
parent=..., first=7, last=7) at itemmodels/qabstractitemmodel.cpp:2698
#30 0xa482d386 in KConcatenateRowsProxyModelPrivate::slotRowsAboutToBeRemoved
(this=0x80c5a448, start=7, end=7) at ./src/kconcatenaterowsproxymodel.cpp:241
#31 0xa482e7cd in KConcatenateRowsProxyModel::qt_static_metacall
(_o=0x80c5a490, _c=QMetaObject::InvokeMetaMethod, _id=2, _a=0xbfc7a45c) at
./obj-i686-linux-gnu/src/moc_kconcatenaterowsproxymodel.cpp:130
#32 0xb5257fdb in QMetaObject::activate (sender=<optimized out>,
signalOffset=<optimized out>, local_signal_index=<optimized out>,
argv=<optimized out>) at kernel/qobject.cpp:3740
#33 0xb525885d in QMetaObject::activate (sender=0x80c31c80, m=0xb54a1fd0
<QAbstractItemModel::staticMetaObject>, local_signal_index=11, argv=0xbfc7a45c)
at kernel/qobject.cpp:3602
#34 0xb52d67b1 in QAbstractItemModel::rowsAboutToBeRemoved (this=0x80c31c80,
_t1=..., _t2=<optimized out>, _t3=<optimized out>) at
.moc/moc_qabstractitemmodel.cpp:608
#35 0xb51cbc00 in QAbstractItemModel::beginRemoveRows (this=0x80c31c80,
parent=..., first=7, last=7) at itemmodels/qabstractitemmodel.cpp:2698
#36 0xb51e796e in QIdentityProxyModelPrivate::_q_sourceRowsAboutToBeRemoved
(end=<optimized out>, start=<optimized out>, parent=..., this=<optimized out>)
at itemmodels/qidentityproxymodel.cpp:580
#37 QIdentityProxyModel::qt_static_metacall (_o=0x80c31c80,
_c=QMetaObject::InvokeMetaMethod, _id=<optimized out>, _a=<optimized out>) at
.moc/moc_qidentityproxymodel.cpp:150
#38 0xb5257fdb in QMetaObject::activate (sender=<optimized out>,
signalOffset=<optimized out>, local_signal_index=<optimized out>,
argv=<optimized out>) at kernel/qobject.cpp:3740
#39 0xb525885d in QMetaObject::activate (sender=0x80b5b198, m=0xb54a1fd0
<QAbstractItemModel::staticMetaObject>, local_signal_index=11, argv=0xbfc7a63c)
at kernel/qobject.cpp:3602
#40 0xb52d67b1 in QAbstractItemModel::rowsAboutToBeRemoved (this=0x80b5b198,
_t1=..., _t2=<optimized out>, _t3=<optimized out>) at
.moc/moc_qabstractitemmodel.cpp:608
#41 0xb51cbc00 in QAbstractItemModel::beginRemoveRows (this=0x80b5b198,
parent=..., first=7, last=7) at itemmodels/qabstractitemmodel.cpp:2698
#42 0xa43135c3 in TaskManager::XWindowTasksModel::Private::removeWindow
(this=0x80bc5590, window=<optimized out>) at
./libtaskmanager/xwindowtasksmodel.cpp:250
#43 0xa4313858 in
TaskManager::XWindowTasksModel::Private::<lambda(WId)>::operator()
(window=<optimized out>, __closure=0x80af8478) at
./libtaskmanager/xwindowtasksmodel.cpp:160
#44 QtPrivate::FunctorCall<QtPrivate::IndexesList<0>, QtPrivate::List<unsigned
int>, void, TaskManager::XWindowTasksModel::Private::init()::<lambda(WId)>
>::call (arg=0xbfc7a844, f=...) at
/usr/include/i386-linux-gnu/qt5/QtCore/qobjectdefs_impl.h:135
#45
QtPrivate::Functor<TaskManager::XWindowTasksModel::Private::init()::<lambda(WId)>,
1>::call<QtPrivate::List<unsigned int>, void> (arg=0xbfc7a844, f=...) at
/usr/include/i386-linux-gnu/qt5/QtCore/qobjectdefs_impl.h:192
#46
QtPrivate::QFunctorSlotObject<TaskManager::XWindowTasksModel::Private::init()::<lambda(WId)>,
1, QtPrivate::List<unsigned int>, void>::impl(int, QtPrivate::QSlotObjectBase
*, QObject *, void **, bool *) (which=1, this_=0x80af8470, r=0x80b5b198,
a=0xbfc7a844, 
    ret=0x0) at /usr/include/i386-linux-gnu/qt5/QtCore/qobject_impl.h:169
#47 0xb525834e in QtPrivate::QSlotObjectBase::call (a=0xbfc7a844, r=0x80b5b198,
this=<optimized out>) at
../../include/QtCore/../../src/corelib/kernel/qobject_impl.h:101
#48 QMetaObject::activate (sender=<optimized out>, signalOffset=<optimized
out>, local_signal_index=<optimized out>, argv=<optimized out>) at
kernel/qobject.cpp:3723
#49 0xb525885d in QMetaObject::activate (sender=0xb6629900, m=0xb6628dc0
<KWindowSystem::staticMetaObject>, local_signal_index=2, argv=0xbfc7a844) at
kernel/qobject.cpp:3602
#50 0xb660fd91 in KWindowSystem::windowRemoved(unsigned int) () from
/usr/lib/i386-linux-gnu/libKF5WindowSystem.so.5
#51 0xae2393f2 in ?? () from
/usr/lib/i386-linux-gnu/qt5/plugins/kf5/org.kde.kwindowsystem.platforms/KF5WindowSystemX11Plugin.so
#52 0xb66080b7 in NETRootInfo::update(QFlags<NET::Property>,
QFlags<NET::Property2>) () from /usr/lib/i386-linux-gnu/libKF5WindowSystem.so.5
#53 0xb6608ffb in NETRootInfo::event(xcb_generic_event_t*,
QFlags<NET::Property>*, QFlags<NET::Property2>*) () from
/usr/lib/i386-linux-gnu/libKF5WindowSystem.so.5
#54 0xb6609393 in NETRootInfo::event(xcb_generic_event_t*, unsigned long*, int)
() from /usr/lib/i386-linux-gnu/libKF5WindowSystem.so.5
#55 0xae238a7f in ?? () from
/usr/lib/i386-linux-gnu/qt5/plugins/kf5/org.kde.kwindowsystem.platforms/KF5WindowSystemX11Plugin.so
#56 0xb5226860 in QAbstractEventDispatcher::filterNativeEvent (this=<optimized
out>, eventType=..., message=<optimized out>, result=<optimized out>) at
kernel/qabstracteventdispatcher.cpp:466
#57 0xaf733122 in QXcbConnection::handleXcbEvent(xcb_generic_event_t*) () from
/usr/lib/i386-linux-gnu/libQt5XcbQpa.so.5
#58 0xaf733ef7 in QXcbConnection::processXcbEvents() () from
/usr/lib/i386-linux-gnu/libQt5XcbQpa.so.5
#59 0xaf76ade1 in ?? () from /usr/lib/i386-linux-gnu/libQt5XcbQpa.so.5
#60 0xb52550e0 in QMetaCallEvent::placeMetaCall (this=0x9d4cf7e0,
object=0x803684f8) at kernel/qobject.cpp:502
#61 0xb5258e33 in QObject::event (this=0x803684f8, e=0x9d4cf7e0) at
kernel/qobject.cpp:1263
#62 0xaf736a49 in QXcbConnection::event(QEvent*) () from
/usr/lib/i386-linux-gnu/libQt5XcbQpa.so.5
#63 0xb5ba317a in QApplicationPrivate::notify_helper(QObject*, QEvent*) () from
/usr/lib/i386-linux-gnu/libQt5Widgets.so.5
#64 0xb5bab03c in QApplication::notify(QObject*, QEvent*) () from
/usr/lib/i386-linux-gnu/libQt5Widgets.so.5
#65 0xb5229c5d in QCoreApplication::notifyInternal2 (receiver=0x803684f8,
event=0x9d4cf7e0) at kernel/qcoreapplication.cpp:988
#66 0xb522c647 in QCoreApplication::sendEvent (event=0x9d4cf7e0,
receiver=<optimized out>) at kernel/qcoreapplication.h:231
#67 QCoreApplicationPrivate::sendPostedEvents (receiver=<optimized out>,
event_type=<optimized out>, data=0x803552a8) at
kernel/qcoreapplication.cpp:1649
#68 0xb522ca87 in QCoreApplication::sendPostedEvents (receiver=0x0,
event_type=0) at kernel/qcoreapplication.cpp:1503
#69 0xb52830a3 in postEventSourceDispatch (s=0x803907a8) at
kernel/qeventdispatcher_glib.cpp:276
#70 0xb3cde4e9 in g_main_context_dispatch () from
/lib/i386-linux-gnu/libglib-2.0.so.0
#71 0xb3cde789 in ?? () from /lib/i386-linux-gnu/libglib-2.0.so.0
#72 0xb3cde854 in g_main_context_iteration () from
/lib/i386-linux-gnu/libglib-2.0.so.0
---Type <return> to continue, or q <return> to quit---frame 7
#73 0xb5283493 in QEventDispatcherGlib::processEvents (this=0x80395a08,
flags=...) at kernel/qeventdispatcher_glib.cpp:423
#74 0xaf76bd81 in ?? () from /usr/lib/i386-linux-gnu/libQt5XcbQpa.so.5
#75 0xb522783d in QEventLoop::exec (this=<optimized out>, flags=...) at
kernel/qeventloop.cpp:212
#76 0xb523099f in QCoreApplication::exec () at kernel/qcoreapplication.cpp:1261
#77 0xb5565aa1 in QGuiApplication::exec() () from
/usr/lib/i386-linux-gnu/sse2/libQt5Gui.so.5
#78 0xb5ba30d4 in QApplication::exec() () from
/usr/lib/i386-linux-gnu/libQt5Widgets.so.5
#79 0x800b3a4c in ?? ()
#80 0xb4ca8276 in __libc_start_main (main=0x800b2ee0, argc=2, argv=0xbfc7b6f4,
init=0x80112890 <__libc_csu_init>, fini=0x801128f0 <__libc_csu_fini>,
rtld_fini=0xb77ea080 <_dl_fini>, stack_end=0xbfc7b6ec) at
../csu/libc-start.c:291
#81 0x800b3dc7 in _start ()

I'm quite convinced it is the same crash in these many bugreports, but I can't
be sure, because it is nearly unreproducible and the cause is not evident from
the bt. However, the immediate cause of my crash is clear:

(gdb) frame 7
#7  QSortFilterProxyModelPrivate::updateChildrenMapping
(this=this@entry=0x80c51650, source_parent=...,
parent_mapping=parent_mapping@entry=0x81a6f338, start=<optimized out>,
end=<optimized out>, delta_item_count=<optimized out>, remove=true, 
...
(gdb) x/32 parent_mapping->mapped_children.d  
0x82b2c9a0:     1       5       15      16
0x82b2c9b0:     0       0       6       -2134522736
0x82b2c9c0:     0       0       6       -2134522736
0x82b2c9d0:     0       0       6       -2134522736
0x82b2c9e0:     1       0       6       -2134522736
0x82b2c9f0:     2       0       6       -2134522736
0x82b2ca00:     3       0       6       -2134522736
0x82b2ca10:     3       0       6       -2134522736

As you can see, the mapping contains 3 same QModelIndexes. Tho code in
updateChildrenMapping goes like this:

            // update mapping
            Mapping *cm = source_index_mapping.take(source_child_index);
            Q_ASSERT(cm);
            // we do not reinsert right away, because the new index might be
identical with another, old index
            moved_source_index_mappings.append(QPair<QModelIndex,
Mapping*>(new_index, cm));

This is executed for all source_child_index-es which are in the mapping (or
more precisely, a suffix thereof). When source_index_mapping.take(...) executes
several times for the same source_child_index, it can't retrieve a valid
Mapping for the second and subsequent times. It would return NULL, and this
eventually causes a crash (in a debug build, it would fail the Q_ASSERT; in
release builds, it leads to SIGSEGV several lines below).

Now, what does lead to such unfortuante state that
parent_mapping->mapped_children contains an index several times? After all, the
code in QSortFilterProxyModelPrivate written in such a way that no QModelIndex
should be more than once in all of the mapped_children taken together. I placed
some asserts over the code and came to a crash that could be closer to the
cause:

(gdb) bt                                                                        
#0  0xb77aecf9 in __kernel_vsyscall ()                                          
#1  0xb4c212fa in nanosleep () at ../sysdeps/unix/syscall-template.S:84         
#2  0xb4c21225 in __sleep (seconds=0) at ../sysdeps/posix/sleep.c:55            
#3  0xb7774c3a in ?? () from /usr/lib/i386-linux-gnu/libKF5Crash.so.5           
#4  0xb77753e0 in ?? () from /usr/lib/i386-linux-gnu/libKF5Crash.so.5           
#5  0xb7775860 in KCrash::defaultCrashHandler(int) () from
/usr/lib/i386-linux-gnu/libKF5Crash.so.5                                        
#6  <signal handler called>                                                     
#7  0xb77aecf9 in __kernel_vsyscall ()                                          
#8  0xb4b9bdc0 in __libc_signal_restore_set (set=0xbf9ee900) at
../sysdeps/unix/sysv/linux/nptl-signals.h:79                                    
#9  __GI_raise (sig=6) at ../sysdeps/unix/sysv/linux/raise.c:48                 
#10 0xb4b9d287 in __GI_abort () at abort.c:89                                   
#11 0xb4f1d0d3 in qt_message_fatal (context=..., message=<synthetic
pointer>...) at global/qlogging.cpp:1682                                        
#12 QMessageLogger::fatal (this=0xbf9eebb8, msg=0xb51a2188 "ASSERT: \"%s\" in
file %s, line %d") at global/qlogging.cpp:793                                   
#13 0xb4f15d76 in qt_assert (assertion=0xb5253bfc
"std::find(parent_mapping->mapped_children.begin(), it2, new_index) == it2",
file=0xb5253b20 "itemmodels/qsortfilterproxymodel.cpp", line=1002) at
global/qglobal.cpp:3081                                                   
#14 0xb50ad8ae in QSortFilterProxyModelPrivate::updateChildrenMapping
(this=<optimized out>, source_parent=..., parent_mapping=<optimized out>,
orient=Qt::Vertical, start=<optimized out>, end=<optimized out>,
delta_item_count=<optimized out>, remove=true)                
    at itemmodels/qsortfilterproxymodel.cpp:1002                                
#15 0xb50ada08 in QSortFilterProxyModelPrivate::source_items_removed
(this=0x818139a0, source_parent=..., start=start@entry=1, end=1,
orient=Qt::Vertical) at itemmodels/qsortfilterproxymodel.cpp:960                
#16 0xb50adcc7 in QSortFilterProxyModelPrivate::source_items_removed
(orient=Qt::Vertical, end=1, start=1, source_parent=..., this=<optimized out>)
at itemmodels/qsortfilterproxymodel.cpp:1473                                    
#17 QSortFilterProxyModelPrivate::_q_sourceRowsRemoved (this=<optimized out>,
source_parent=..., start=1, end=1) at itemmodels/qsortfilterproxymodel.cpp:1472 
#18 0xb50b381d in QSortFilterProxyModel::qt_static_metacall (_o=0x81857db0,
_c=QMetaObject::InvokeMetaMethod, _id=14, _a=0xbf9eee3c) at
.moc/moc_qsortfilterproxymodel.cpp:211                                          
#19 0xb511b5af in QMetaObject::activate (sender=<optimized out>,
signalOffset=<optimized out>, local_signal_index=<optimized out>,
argv=<optimized out>) at kernel/qobject.cpp:3740                                
#20 0xb511b96d in QMetaObject::activate (sender=0x818123f0, m=0xb5384fd0
<QAbstractItemModel::staticMetaObject>, local_signal_index=12, argv=0xbf9eee3c)
at kernel/qobject.cpp:3602                                                      
#21 0xb519a051 in QAbstractItemModel::rowsRemoved (this=0x818123f0, _t1=...,
_t2=<optimized out>, _t3=<optimized out>) at
.moc/moc_qabstractitemmodel.cpp:615                                             
#22 0xb508d949 in QAbstractItemModel::endRemoveRows (this=0x818123f0) at
itemmodels/qabstractitemmodel.cpp:2715                                          
#23 0xa708c6f2 in
TaskManager::TaskGroupingProxyModel::Private::sourceRowsAboutToBeRemoved
(this=0x81805908, parent=..., first=9, last=9) at
./libtaskmanager/taskgroupingproxymodel.cpp:197                                 
#24 0xa708ffed in TaskManager::TaskGroupingProxyModel::qt_static_metacall
(_o=0x818123f0, _c=QMetaObject::InvokeMetaMethod, _id=7, _a=0xbf9ef07c) at
./obj-i686-linux-gnu/libtaskmanager/moc_taskgroupingproxymodel.cpp:152
#25 0xb511b5af in QMetaObject::activate (sender=<optimized out>,
signalOffset=<optimized out>, local_signal_index=<optimized out>,
argv=<optimized out>) at kernel/qobject.cpp:3740
#26 0xb511b96d in QMetaObject::activate (sender=0x81866c00, m=0xb5384fd0
<QAbstractItemModel::staticMetaObject>, local_signal_index=11, argv=0xbf9ef07c)
at kernel/qobject.cpp:3602
#27 0xb5199fe1 in QAbstractItemModel::rowsAboutToBeRemoved (this=0x81866c00,
_t1=..., _t2=<optimized out>, _t3=<optimized out>) at
.moc/moc_qabstractitemmodel.cpp:608
#28 0xb508d064 in QAbstractItemModel::beginRemoveRows (this=0x81866c00,
parent=..., first=9, last=9) at itemmodels/qabstractitemmodel.cpp:2698
#29 0xb50ac2fc in QSortFilterProxyModelPrivate::remove_proxy_interval
(this=0x81858320, source_to_proxy=..., proxy_to_source=..., proxy_start=9,
proxy_end=9, proxy_parent=..., orient=Qt::Vertical, emit_signal=true) at
itemmodels/qsortfilterproxymodel.cpp:626
#30 0xb50b113c in QSortFilterProxyModelPrivate::remove_source_items
(this=<optimized out>, source_to_proxy=..., proxy_to_source=...,
source_items=..., source_parent=..., orient=<optimized out>, emit_signal=true)
at itemmodels/qsortfilterproxymodel.cpp:607
#31 0xb50b1328 in
QSortFilterProxyModelPrivate::source_items_about_to_be_removed (this=<optimized
out>, source_parent=..., start=<optimized out>, end=<optimized out>,
orient=<optimized out>) at itemmodels/qsortfilterproxymodel.cpp:908
#32 0xb50b37fd in QSortFilterProxyModelPrivate::_q_sourceRowsAboutToBeRemoved
(end=9, start=<optimized out>, source_parent=..., this=<optimized out>) at
itemmodels/qsortfilterproxymodel.cpp:1464
#33 QSortFilterProxyModel::qt_static_metacall (_o=0x81866c00,
_c=QMetaObject::InvokeMetaMethod, _id=13, _a=0xbf9ef37c) at
.moc/moc_qsortfilterproxymodel.cpp:210
#34 0xb511b5af in QMetaObject::activate (sender=<optimized out>,
signalOffset=<optimized out>, local_signal_index=<optimized out>,
argv=<optimized out>) at kernel/qobject.cpp:3740
#35 0xb511b96d in QMetaObject::activate (sender=0x81859478, m=0xb5384fd0
<QAbstractItemModel::staticMetaObject>, local_signal_index=11, argv=0xbf9ef37c)
at kernel/qobject.cpp:3602
#36 0xb5199fe1 in QAbstractItemModel::rowsAboutToBeRemoved (this=0x81859478,
_t1=..., _t2=<optimized out>, _t3=<optimized out>) at
.moc/moc_qabstractitemmodel.cpp:608
#37 0xb508d064 in QAbstractItemModel::beginRemoveRows (this=0x81859478,
parent=..., first=9, last=9) at itemmodels/qabstractitemmodel.cpp:2698
#38 0xa75c2386 in KConcatenateRowsProxyModelPrivate::slotRowsAboutToBeRemoved
(this=0x81859430, start=9, end=9) at ./src/kconcatenaterowsproxymodel.cpp:241
#39 0xa75c37cd in KConcatenateRowsProxyModel::qt_static_metacall
(_o=0x81859478, _c=QMetaObject::InvokeMetaMethod, _id=2, _a=0xbf9ef58c) at
./obj-i686-linux-gnu/src/moc_kconcatenaterowsproxymodel.cpp:130
#40 0xb511b5af in QMetaObject::activate (sender=<optimized out>,
signalOffset=<optimized out>, local_signal_index=<optimized out>,
argv=<optimized out>) at kernel/qobject.cpp:3740
#41 0xb511b96d in QMetaObject::activate (sender=0x81868180, m=0xb5384fd0
<QAbstractItemModel::staticMetaObject>, local_signal_index=11, argv=0xbf9ef58c)
at kernel/qobject.cpp:3602
#42 0xb5199fe1 in QAbstractItemModel::rowsAboutToBeRemoved (this=0x81868180,
_t1=..., _t2=<optimized out>, _t3=<optimized out>) at
.moc/moc_qabstractitemmodel.cpp:608
#43 0xb508d064 in QAbstractItemModel::beginRemoveRows (this=0x81868180,
parent=..., first=9, last=9) at itemmodels/qabstractitemmodel.cpp:2698
#44 0xb50a7466 in QIdentityProxyModelPrivate::_q_sourceRowsAboutToBeRemoved
(this=0x8182c0e0, parent=..., start=9, end=9) at
itemmodels/qidentityproxymodel.cpp:580
#45 0xb50a8315 in QIdentityProxyModel::qt_static_metacall (_o=0x81868180,
_c=QMetaObject::InvokeMetaMethod, _id=2, _a=0xbf9ef78c) at
.moc/moc_qidentityproxymodel.cpp:150
#46 0xb511b5af in QMetaObject::activate (sender=<optimized out>,
signalOffset=<optimized out>, local_signal_index=<optimized out>,
argv=<optimized out>) at kernel/qobject.cpp:3740
#47 0xb511b96d in QMetaObject::activate (sender=0x817b3cc0, m=0xb5384fd0
<QAbstractItemModel::staticMetaObject>, local_signal_index=11, argv=0xbf9ef78c)
at kernel/qobject.cpp:3602
#48 0xb5199fe1 in QAbstractItemModel::rowsAboutToBeRemoved (this=0x817b3cc0,
_t1=..., _t2=<optimized out>, _t3=<optimized out>) at
.moc/moc_qabstractitemmodel.cpp:608
#49 0xb508d064 in QAbstractItemModel::beginRemoveRows (this=0x817b3cc0,
parent=..., first=9, last=9) at itemmodels/qabstractitemmodel.cpp:2698
#50 0xa70a85c3 in TaskManager::XWindowTasksModel::Private::removeWindow
(this=0x8176b578, window=<optimized out>) at
./libtaskmanager/xwindowtasksmodel.cpp:250
#51 0xa70a8858 in
TaskManager::XWindowTasksModel::Private::<lambda(WId)>::operator()
(window=<optimized out>, __closure=0x8162dc20) at
./libtaskmanager/xwindowtasksmodel.cpp:160
#52 QtPrivate::FunctorCall<QtPrivate::IndexesList<0>, QtPrivate::List<unsigned
int>, void, TaskManager::XWindowTasksModel::Private::init()::<lambda(WId)>
>::call (arg=0xbf9ef984, f=...) at
/usr/include/i386-linux-gnu/qt5/QtCore/qobjectdefs_impl.h:135
#53
QtPrivate::Functor<TaskManager::XWindowTasksModel::Private::init()::<lambda(WId)>,
1>::call<QtPrivate::List<unsigned int>, void> (arg=0xbf9ef984, f=...) at
/usr/include/i386-linux-gnu/qt5/QtCore/qobjectdefs_impl.h:192
#54
QtPrivate::QFunctorSlotObject<TaskManager::XWindowTasksModel::Private::init()::<lambda(WId)>,
1, QtPrivate::List<unsigned int>, void>::impl(int, QtPrivate::QSlotObjectBase
*, QObject *, void **, bool *) (which=1, this_=0x8162dc18, r=0x817b3cc0,
a=0xbf9ef984, 
    ret=0x0) at /usr/include/i386-linux-gnu/qt5/QtCore/qobject_impl.h:169
#55 0xb511b3f3 in QtPrivate::QSlotObjectBase::call (a=0xbf9ef984, r=0x817b3cc0,
this=0x8162dc18) at
../../include/QtCore/../../src/corelib/kernel/qobject_impl.h:101
#56 QMetaObject::activate (sender=<optimized out>, signalOffset=<optimized
out>, local_signal_index=<optimized out>, argv=<optimized out>) at
kernel/qobject.cpp:3723
#57 0xb511b96d in QMetaObject::activate (sender=0xb65fc900, m=0xb65fbdc0
<KWindowSystem::staticMetaObject>, local_signal_index=2, argv=0xbf9ef984) at
kernel/qobject.cpp:3602
#58 0xb65e2d91 in KWindowSystem::windowRemoved(unsigned int) () from
/usr/lib/i386-linux-gnu/libKF5WindowSystem.so.5
#59 0xae0de3f2 in ?? () from
/usr/lib/i386-linux-gnu/qt5/plugins/kf5/org.kde.kwindowsystem.platforms/KF5WindowSystemX11Plugin.so
#60 0xb65db0b7 in NETRootInfo::update(QFlags<NET::Property>,
QFlags<NET::Property2>) () from /usr/lib/i386-linux-gnu/libKF5WindowSystem.so.5
#61 0xb65dbffb in NETRootInfo::event(xcb_generic_event_t*,
QFlags<NET::Property>*, QFlags<NET::Property2>*) () from
/usr/lib/i386-linux-gnu/libKF5WindowSystem.so.5
#62 0xb65dc393 in NETRootInfo::event(xcb_generic_event_t*, unsigned long*, int)
() from /usr/lib/i386-linux-gnu/libKF5WindowSystem.so.5

(gdb) frame 14
#14 0xb50ad8ae in QSortFilterProxyModelPrivate::updateChildrenMapping
(this=<optimized out>, source_parent=..., parent_mapping=<optimized out>,
orient=Qt::Vertical, start=<optimized out>, end=<optimized out>,
delta_item_count=<optimized out>, remove=true)
    at itemmodels/qsortfilterproxymodel.cpp:1002

(gdb) x/48x it2-6
0x87737308:     0x00000001      0x00000007      0x0000000f      0x00000010
0x87737318:     0x00000000      0x00000000      0x0000000a      0x818123f0
0x87737328:     0x00000000      0x00000000      0x00000009      0x818123f0
0x87737338:     0x00000001      0x00000000      0x00000008      0x818123f0
0x87737348:     0x00000002      0x00000000      0x00000008      0x818123f0
0x87737358:     0x00000000      0x00000000      0x00000008      0x818123f0
0x87737368:     0x00000002      0x00000000      0x00000008      0x818123f0
0x87737378:     0x00000003      0x00000000      0x00000008      0x818123f0
0x87737388:     0x00000003      0x00000000      0x00000008      0x818123f0
0x87737398:     0x00000003      0x00000000      0x00000008      0x818123f0
0x877373a8:     0x00000003      0x00000000      0x00000008      0x818123f0
0x877373b8:     0x00000000      0x00000000      0x00000000      0x00000031

As you can see, the parent_mapping now contains not only identical
QModelIndexes, but also different QModelIndexes of different parents. However,
it should only contain indexes which are siblings. Note that the four dwords
shown here are row/column/parent/model. So there should be only a single number
in the third column.

My theory about how does this arise and how it leads to crashes goes like this:

1) TaskManager uses the third number of a QModelIndex as a row index of its
parent in TaskGroupingProxyModel. That means that when a row is deleted, the
subsequent rows change indexes, and therefore, their children's QModelIndexes
change as well.
2) A group of three is created at position eg. 10. That creates parent index
10/0/0 and children 0/0/10, 1/0/10, 2/0/10 (modulo some +-1 error, because it's
actually shifted by one, but whatever).
3) A row is destroyed at row <10, shifting our group one back. That leaves us
with parent index 9/0/0, children 0/0/9, 1/0/9, 2/0/9. However, the
mapped_children vector of QSortFilterProxyMappingPrivate still contains the
original indexes 0/0/10 etc.
4) Eventually, QSFPMPrivate creates records for the new child indexes as well.
The mapped_children are now 0/0/9, 1/0/9, 2/0/9, 0/0/10, 1/0/10, 2/0/10. Note
that this is somewhat similar to what you see above.
5) The first child of the group is deleted. updateChildrenMapping will shift
the rest of the indexes, but also it will make them have the same parent.
mapped_children will now be 0/0/9, 1/0/9, 0/0/9, 1/0/9.
6) The next updateChildrenProxyMapping could see two identical indexes, which
causes the crash described above.

What to do with it?

1. If the TaskManager's way of managing QModelIndexes should be legal, the bug
is almost certainly on Qt's side. QSFPM should react to a row being deleted by
not only changing the indexes of subsequent rows, but also their children. The
easiest way to do it is to recurse in updateChildrenProxyMapping:

            // update mapping
            Mapping *cm = source_index_mapping.take(source_child_index);
            Q_ASSERT(cm);
            // we do not reinsert right away, because the new index might be
identical with another, old index
            moved_source_index_mappings.append(QPair<QModelIndex,
Mapping*>(new_index, cm));
            // reparent the children to the new index
            updateChildrenMapping(new_index, cm, orient, 0, -1, 0, 0);

I made that change to my Qt and it seems to work.

2. Or else, taskmanager should be rewritten NOT to use the third number in
QModelIndex as a row index.

What do you think?

   Jiri Palecek

-- 
You are receiving this mail because:
You are watching all bug changes.

Reply via email to