Bug 437862 - Plasma System Monitor segfaults when viewing processes tab
Summary: Plasma System Monitor segfaults when viewing processes tab
Status: RESOLVED FIXED
Alias: None
Product: plasma-systemmonitor
Classification: Applications
Component: general (show other bugs)
Version: 5.21.5
Platform: Neon Linux
: NOR crash
Target Milestone: ---
Assignee: KSysGuard Developers
URL:
Keywords: drkonqi
: 437835 440573 440579 (view as bug list)
Depends on:
Blocks:
 
Reported: 2021-05-30 15:58 UTC by Alek Evans
Modified: 2021-08-26 14:56 UTC (History)
7 users (show)

See Also:
Latest Commit:
Version Fixed In: 5.23


Attachments
Screenshot of the crash's code and variable viewer in Qt Creator's debugger. (140.57 KB, image/png)
2021-08-14 00:19 UTC, nyanpasu64
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Alek Evans 2021-05-30 15:58:57 UTC
Application: plasma-systemmonitor (5.21.5)

Qt Version: 5.15.2
Frameworks Version: 5.82.0
Operating System: Linux 5.8.0-53-generic x86_64
Windowing System: X11
Drkonqi Version: 5.21.5
Distribution: KDE neon User Edition 5.21

-- Information about the crash:
- What I was doing when the application crashed:

Whenever viewing the processes page in the system monitor, periodically when a process is removed from the list it will crash with segfault 11. This also occurs on my laptop using KDE neon User Edition 5.2.1. For the most part it's random but the crash will only occur when viewing the processes page.

The crash can be reproduced every time.

-- Backtrace:
Application: System Monitor (plasma-systemmonitor), signal: Segmentation fault

[New LWP 100076]
[New LWP 100080]
[New LWP 100081]
[New LWP 100092]
[New LWP 100094]
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
0x00007f76e1c56aff in __GI___poll (fds=0x7ffef25bd668, nfds=1, timeout=1000) at ../sysdeps/unix/sysv/linux/poll.c:29
[Current thread is 1 (Thread 0x7f76de8fb340 (LWP 100075))]

Thread 6 (Thread 0x7f76c5c3e700 (LWP 100094)):
#0  0x00007f76e1c5912b in __GI___select (nfds=41, readfds=0x7f76c5c3dd20, writefds=0x0, exceptfds=0x0, timeout=0x7f76c5c3dd10) at ../sysdeps/unix/sysv/linux/select.c:41
#1  0x00007f76cee69991 in ?? () from /lib/x86_64-linux-gnu/libnvidia-glcore.so.460.80
#2  0x00007f76cee6747a in ?? () from /lib/x86_64-linux-gnu/libnvidia-glcore.so.460.80
#3  0x00007f76e1955609 in start_thread (arg=<optimized out>) at pthread_create.c:477
#4  0x00007f76e1c63293 in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95

Thread 5 (Thread 0x7f76c67fc700 (LWP 100092)):
#0  futex_wait_cancelable (private=<optimized out>, expected=0, futex_word=0x558f9a386be4) at ../sysdeps/nptl/futex-internal.h:183
#1  __pthread_cond_wait_common (abstime=0x0, clockid=0, mutex=0x558f9a386b90, cond=0x558f9a386bb8) at pthread_cond_wait.c:508
#2  __pthread_cond_wait (cond=0x558f9a386bb8, mutex=0x558f9a386b90) at pthread_cond_wait.c:638
#3  0x00007f76e1fe7d5b in QWaitConditionPrivate::wait (deadline=..., this=0x558f9a386b90) at thread/qwaitcondition_unix.cpp:146
#4  QWaitCondition::wait (this=<optimized out>, mutex=0x558f9a38fbb0, deadline=...) at thread/qwaitcondition_unix.cpp:225
#5  0x00007f76dc714814 in ?? () from /lib/x86_64-linux-gnu/libQt5Quick.so.5
#6  0x00007f76dc714c89 in ?? () from /lib/x86_64-linux-gnu/libQt5Quick.so.5
#7  0x00007f76e1fe1bec in QThreadPrivate::start (arg=0x558f9a38fb10) at thread/qthread_unix.cpp:329
#8  0x00007f76e1955609 in start_thread (arg=<optimized out>) at pthread_create.c:477
#9  0x00007f76e1c63293 in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95

Thread 4 (Thread 0x7f76d69d6700 (LWP 100081)):
#0  0x00007f76e0bae4dd in g_mutex_lock () from /lib/x86_64-linux-gnu/libglib-2.0.so.0
#1  0x00007f76e0b61354 in ?? () from /lib/x86_64-linux-gnu/libglib-2.0.so.0
#2  0x00007f76e0b614a3 in g_main_context_iteration () from /lib/x86_64-linux-gnu/libglib-2.0.so.0
#3  0x00007f76e2221ffb in QEventDispatcherGlib::processEvents (this=0x7f76c8000b60, flags=...) at kernel/qeventdispatcher_glib.cpp:425
#4  0x00007f76e21c61eb in QEventLoop::exec (this=this@entry=0x7f76d69d5d40, flags=..., flags@entry=...) at ../../include/QtCore/../../src/corelib/global/qflags.h:141
#5  0x00007f76e1fe0a52 in QThread::exec (this=<optimized out>) at ../../include/QtCore/../../src/corelib/global/qflags.h:121
#6  0x00007f76e3897fa9 in ?? () from /lib/x86_64-linux-gnu/libQt5Qml.so.5
#7  0x00007f76e1fe1bec in QThreadPrivate::start (arg=0x558f99cfeb20) at thread/qthread_unix.cpp:329
#8  0x00007f76e1955609 in start_thread (arg=<optimized out>) at pthread_create.c:477
#9  0x00007f76e1c63293 in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95

Thread 3 (Thread 0x7f76d7be7700 (LWP 100080)):
#0  0x00007f76e0b5f25d in g_source_ref () from /lib/x86_64-linux-gnu/libglib-2.0.so.0
#1  0x00007f76e0b5f328 in ?? () from /lib/x86_64-linux-gnu/libglib-2.0.so.0
#2  0x00007f76e0b6082b in g_main_context_prepare () from /lib/x86_64-linux-gnu/libglib-2.0.so.0
#3  0x00007f76e0b6129b in ?? () from /lib/x86_64-linux-gnu/libglib-2.0.so.0
#4  0x00007f76e0b614a3 in g_main_context_iteration () from /lib/x86_64-linux-gnu/libglib-2.0.so.0
#5  0x00007f76e2221ffb in QEventDispatcherGlib::processEvents (this=0x7f76d0000b60, flags=...) at kernel/qeventdispatcher_glib.cpp:425
#6  0x00007f76e21c61eb in QEventLoop::exec (this=this@entry=0x7f76d7be6d30, flags=..., flags@entry=...) at ../../include/QtCore/../../src/corelib/global/qflags.h:141
#7  0x00007f76e1fe0a52 in QThread::exec (this=<optimized out>) at ../../include/QtCore/../../src/corelib/global/qflags.h:121
#8  0x00007f76e2483f4b in ?? () from /lib/x86_64-linux-gnu/libQt5DBus.so.5
#9  0x00007f76e1fe1bec in QThreadPrivate::start (arg=0x7f76e2507d80) at thread/qthread_unix.cpp:329
#10 0x00007f76e1955609 in start_thread (arg=<optimized out>) at pthread_create.c:477
#11 0x00007f76e1c63293 in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95

Thread 2 (Thread 0x7f76ddc75700 (LWP 100076)):
#0  0x00007f76e1c56aff in __GI___poll (fds=0x7f76ddc74c68, nfds=1, timeout=-1) at ../sysdeps/unix/sysv/linux/poll.c:29
#1  0x00007f76e092bc1a in ?? () from /lib/x86_64-linux-gnu/libxcb.so.1
#2  0x00007f76e092d90a in xcb_wait_for_event () from /lib/x86_64-linux-gnu/libxcb.so.1
#3  0x00007f76de253d58 in ?? () from /lib/x86_64-linux-gnu/libQt5XcbQpa.so.5
#4  0x00007f76e1fe1bec in QThreadPrivate::start (arg=0x558f99ac94e0) at thread/qthread_unix.cpp:329
#5  0x00007f76e1955609 in start_thread (arg=<optimized out>) at pthread_create.c:477
#6  0x00007f76e1c63293 in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95

Thread 1 (Thread 0x7f76de8fb340 (LWP 100075)):
[KCrash Handler]
#4  0x00007f76e2197f5d in QSortFilterProxyModel::parent (this=0x558f9bb752f0, child=...) at itemmodels/qsortfilterproxymodel.cpp:2175
#5  0x00007f76e2198045 in QSortFilterProxyModel::parent (this=<optimized out>, child=...) at ../../include/QtCore/../../src/corelib/itemmodels/qabstractitemmodel.h:60
#6  0x00007f76d4db3ceb in QModelIndex::parent (this=0x7ffef25bdf80) at ./src/core/kdescendantsproxymodel.cpp:582
#7  KDescendantsProxyModel::mapFromSource (this=0x558f9bd43140, sourceIndex=...) at ./src/core/kdescendantsproxymodel.cpp:586
#8  0x00007f76d4db43be in KDescendantsProxyModelPrivate::sourceDataChanged (this=<optimized out>, topLeft=..., bottomRight=...) at ./src/core/kdescendantsproxymodel.cpp:1285
#9  0x00007f76d4db8f1c in KDescendantsProxyModel::qt_static_metacall (_o=<optimized out>, _c=<optimized out>, _id=<optimized out>, _a=<optimized out>) at ./src/core/kdescendantsproxymodel.h:252
#10 0x00007f76e21fe730 in doActivate<false> (sender=0x558f9bb752f0, signal_index=3, argv=0x7ffef25be200) at ../../include/QtCore/../../src/corelib/kernel/qobjectdefs_impl.h:395
#11 0x00007f76e21f7ac7 in QMetaObject::activate (sender=sender@entry=0x558f9bb752f0, m=m@entry=0x7f76e2460020 <QAbstractItemModel::staticMetaObject>, local_signal_index=local_signal_index@entry=0, argv=argv@entry=0x7ffef25be200) at kernel/qobject.cpp:3946
#12 0x00007f76e2169819 in QAbstractItemModel::dataChanged (this=this@entry=0x558f9bb752f0, _t1=..., _t2=..., _t3=...) at .moc/moc_qabstractitemmodel.cpp:557
#13 0x00007f76e219ee7d in QSortFilterProxyModelPrivate::_q_sourceDataChanged (this=0x558f9bd434d0, source_top_left=..., source_bottom_right=..., roles=...) at itemmodels/qsortfilterproxymodel.cpp:1500
#14 0x00007f76e219ff2a in QSortFilterProxyModel::qt_static_metacall (_o=<optimized out>, _c=<optimized out>, _id=<optimized out>, _a=<optimized out>) at itemmodels/qsortfilterproxymodel.h:199
#15 0x00007f76e21fe730 in doActivate<false> (sender=0x558f9bd43ec0, signal_index=3, argv=0x7ffef25be4f0) at ../../include/QtCore/../../src/corelib/kernel/qobjectdefs_impl.h:395
#16 0x00007f76e21f7ac7 in QMetaObject::activate (sender=sender@entry=0x558f9bd43ec0, m=m@entry=0x7f76e2460020 <QAbstractItemModel::staticMetaObject>, local_signal_index=local_signal_index@entry=0, argv=argv@entry=0x7ffef25be4f0) at kernel/qobject.cpp:3946
#17 0x00007f76e2169819 in QAbstractItemModel::dataChanged (this=this@entry=0x558f9bd43ec0, _t1=..., _t2=..., _t3=...) at .moc/moc_qabstractitemmodel.cpp:557
#18 0x00007f76e21909d1 in QIdentityProxyModelPrivate::_q_sourceDataChanged (this=<optimized out>, topLeft=..., bottomRight=..., roles=...) at ../../include/QtCore/../../src/corelib/itemmodels/qabstractitemmodel.h:60
#19 0x00007f76e21921c6 in QIdentityProxyModel::qt_static_metacall (_c=QMetaObject::InvokeMetaMethod, _a=<optimized out>, _id=<optimized out>, _o=<optimized out>) at itemmodels/qidentityproxymodel.h:87
#20 QIdentityProxyModel::qt_static_metacall (_o=<optimized out>, _c=<optimized out>, _id=<optimized out>, _a=<optimized out>) at .moc/moc_qidentityproxymodel.cpp:146
#21 0x00007f76e21fe730 in doActivate<false> (sender=0x558f9bd445b0, signal_index=3, argv=0x7ffef25be6e0) at ../../include/QtCore/../../src/corelib/kernel/qobjectdefs_impl.h:395
#22 0x00007f76e21f7ac7 in QMetaObject::activate (sender=sender@entry=0x558f9bd445b0, m=m@entry=0x7f76e2460020 <QAbstractItemModel::staticMetaObject>, local_signal_index=local_signal_index@entry=0, argv=argv@entry=0x7ffef25be6e0) at kernel/qobject.cpp:3946
#23 0x00007f76e2169819 in QAbstractItemModel::dataChanged (this=this@entry=0x558f9bd445b0, _t1=..., _t2=..., _t3=...) at .moc/moc_qabstractitemmodel.cpp:557
#24 0x00007f76e21909d1 in QIdentityProxyModelPrivate::_q_sourceDataChanged (this=<optimized out>, topLeft=..., bottomRight=..., roles=...) at ../../include/QtCore/../../src/corelib/itemmodels/qabstractitemmodel.h:60
#25 0x00007f76e21921c6 in QIdentityProxyModel::qt_static_metacall (_c=QMetaObject::InvokeMetaMethod, _a=<optimized out>, _id=<optimized out>, _o=<optimized out>) at itemmodels/qidentityproxymodel.h:87
#26 QIdentityProxyModel::qt_static_metacall (_o=<optimized out>, _c=<optimized out>, _id=<optimized out>, _a=<optimized out>) at .moc/moc_qidentityproxymodel.cpp:146
#27 0x00007f76e21fe730 in doActivate<false> (sender=0x558f9bd44d50, signal_index=3, argv=0x7ffef25be8d0) at ../../include/QtCore/../../src/corelib/kernel/qobjectdefs_impl.h:395
#28 0x00007f76e21f7ac7 in QMetaObject::activate (sender=<optimized out>, m=m@entry=0x7f76e2460020 <QAbstractItemModel::staticMetaObject>, local_signal_index=local_signal_index@entry=0, argv=argv@entry=0x7ffef25be8d0) at kernel/qobject.cpp:3946
#29 0x00007f76e2169819 in QAbstractItemModel::dataChanged (this=<optimized out>, _t1=..., _t2=..., _t3=...) at .moc/moc_qabstractitemmodel.cpp:557
#30 0x00007f76c5f7438b in ?? () from /lib/x86_64-linux-gnu/libprocesscore.so.9
#31 0x00007f76e21fe6fe in QtPrivate::QSlotObjectBase::call (a=0x7ffef25bea50, r=0x558f9bd44d50, this=0x558f9bf1c440) at ../../include/QtCore/../../src/corelib/kernel/qobjectdefs_impl.h:398
#32 doActivate<false> (sender=0x558f9bd4f5f0, signal_index=3, argv=0x7ffef25bea50) at kernel/qobject.cpp:3886
#33 0x00007f76c5f4f513 in KSysGuard::ProcessAttribute::dataChanged(KSysGuard::Process*) () from /lib/x86_64-linux-gnu/libprocesscore.so.9
#34 0x00007f76e21fe6fe in QtPrivate::QSlotObjectBase::call (a=0x7ffef25beb70, r=0x558f9bd4f5f0, this=0x558f9b487970) at ../../include/QtCore/../../src/corelib/kernel/qobjectdefs_impl.h:398
#35 doActivate<false> (sender=0x558f9bd44e90, signal_index=3, argv=0x7ffef25beb70) at kernel/qobject.cpp:3886
#36 0x00007f76c5f4f711 in KSysGuard::Processes::processChanged(KSysGuard::Process*, bool) () from /lib/x86_64-linux-gnu/libprocesscore.so.9
#37 0x00007f76c5f61b87 in KSysGuard::Processes::updateProcess(KSysGuard::Process*, long) () from /lib/x86_64-linux-gnu/libprocesscore.so.9
#38 0x00007f76c5f61c96 in KSysGuard::Processes::updateOrAddProcess(long) () from /lib/x86_64-linux-gnu/libprocesscore.so.9
#39 0x00007f76c5f6214e in KSysGuard::Processes::processesUpdated() () from /lib/x86_64-linux-gnu/libprocesscore.so.9
#40 0x00007f76e21fe6fe in QtPrivate::QSlotObjectBase::call (a=0x7ffef25bed40, r=0x558f9bd44e90, this=0x558f9bd4d390) at ../../include/QtCore/../../src/corelib/kernel/qobjectdefs_impl.h:398
#41 doActivate<false> (sender=0x558f9bd451d0, signal_index=3, argv=0x7ffef25bed40) at kernel/qobject.cpp:3886
#42 0x00007f76e21fe6fe in QtPrivate::QSlotObjectBase::call (a=0x7ffef25bee80, r=0x558f9bd44d50, this=0x558f9b477260) at ../../include/QtCore/../../src/corelib/kernel/qobjectdefs_impl.h:398
#43 doActivate<false> (sender=0x558f9bd55300, signal_index=3, argv=0x7ffef25bee80) at kernel/qobject.cpp:3886
#44 0x00007f76e21f7ac7 in QMetaObject::activate (sender=<optimized out>, m=m@entry=0x7f76e2461c80 <QTimer::staticMetaObject>, local_signal_index=local_signal_index@entry=0, argv=argv@entry=0x7ffef25bee80) at kernel/qobject.cpp:3946
#45 0x00007f76e220322e in QTimer::timeout (this=<optimized out>, _t1=...) at .moc/moc_qtimer.cpp:205
#46 0x00007f76e21f5195 in QObject::event (this=0x558f9bd55300, e=0x7ffef25bf1b0) at kernel/qobject.cpp:1336
#47 0x00007f76e2d3edc3 in QApplicationPrivate::notify_helper (this=this@entry=0x558f99ac49b0, receiver=receiver@entry=0x558f9bd55300, e=e@entry=0x7ffef25bf1b0) at kernel/qapplication.cpp:3632
#48 0x00007f76e2d47bb8 in QApplication::notify (this=0x7ffef25bf4d0, receiver=0x558f9bd55300, e=0x7ffef25bf1b0) at kernel/qapplication.cpp:3156
#49 0x00007f76e21c76da in QCoreApplication::notifyInternal2 (receiver=0x558f9bd55300, event=0x7ffef25bf1b0) at ../../include/QtCore/5.15.2/QtCore/private/../../../../../src/corelib/thread/qthread_p.h:325
#50 0x00007f76e2221330 in QTimerInfoList::activateTimers (this=0x558f99c5b6f0) at kernel/qtimerinfo_unix.cpp:643
#51 0x00007f76e2221c64 in timerSourceDispatch (source=<optimized out>) at kernel/qeventdispatcher_glib.cpp:183
#52 idleTimerSourceDispatch (source=<optimized out>) at kernel/qeventdispatcher_glib.cpp:230
#53 0x00007f76e0b6117d in g_main_context_dispatch () from /lib/x86_64-linux-gnu/libglib-2.0.so.0
#54 0x00007f76e0b61400 in ?? () from /lib/x86_64-linux-gnu/libglib-2.0.so.0
#55 0x00007f76e0b614a3 in g_main_context_iteration () from /lib/x86_64-linux-gnu/libglib-2.0.so.0
#56 0x00007f76e2221fe2 in QEventDispatcherGlib::processEvents (this=0x558f99c5b430, flags=...) at kernel/qeventdispatcher_glib.cpp:423
#57 0x00007f76e21c61eb in QEventLoop::exec (this=this@entry=0x7ffef25bf3f0, flags=..., flags@entry=...) at ../../include/QtCore/../../src/corelib/global/qflags.h:141
#58 0x00007f76e21ce394 in QCoreApplication::exec () at ../../include/QtCore/../../src/corelib/global/qflags.h:121
#59 0x0000558f9994d05d in main (argc=<optimized out>, argv=<optimized out>) at ./src/main.cpp:133
[Inferior 1 (process 100075) detached]

Possible duplicates by query: bug 323748, bug 323642, bug 307631, bug 290586, bug 289802.

Reported using DrKonqi
Comment 1 Nate Graham 2021-06-08 22:18:19 UTC
Similar to Bug 437835?
Comment 2 David Edmundson 2021-06-17 13:04:19 UTC
*** Bug 437835 has been marked as a duplicate of this bug. ***
Comment 3 David Edmundson 2021-06-17 13:15:32 UTC
I hope this is fixed in 5.22, the dupe is in the beta, but I made a relevant change afterwards. Please reopen if it happens after.
Comment 4 d3coder 2021-06-17 13:28:05 UTC
1. Open system monitor processes tab
2. Open yakuake or konsole and run this: while :; do /usr/bin/bash &; done
3. Wait when many processes start
4. Close yakuake or konsole
5. Observe crash in a few seconds
Comment 5 David Edmundson 2021-07-07 09:17:27 UTC
I could not reproduce with the steps suggested
Comment 6 Nate Graham 2021-07-07 13:04:16 UTC
Also cannot reproduce. Is anyone still seeing this in 5.22, or was it only seen in 5.21.x?
Comment 7 d3coder 2021-07-07 13:16:08 UTC
I opened plasma monitor to test if i can crash it, it crashed before i ran shell command
Stacktraces: https://invent.kde.org/-/snippets/1742

System monitor 5.22.3
KF 5.83.0
Qt 5.15.2+kde+r207-1


Enable tree view in process list and try to reproduce again. I can reproduce with 100% reliability. I can't reproduce it in non-tree process view.

1. Open system monitor processes tab
2. Enable tree view instead of list view
3. Open yakuake or konsole and run this: while :; do /usr/bin/bash &; done
4. Wait when many processes start
5. Close yakuake or konsole
6. Observe crash in a few seconds
Comment 8 Arjen Hiemstra 2021-08-06 10:49:16 UTC
*** Bug 440573 has been marked as a duplicate of this bug. ***
Comment 9 Arjen Hiemstra 2021-08-06 10:49:39 UTC
*** Bug 440579 has been marked as a duplicate of this bug. ***
Comment 10 nyanpasu64 2021-08-14 00:19:07 UTC
Created attachment 140702 [details]
Screenshot of the crash's code and variable viewer in Qt Creator's debugger.

Seems `QModelIndex ProcessDataModel::parent(const QModelIndex &index) const` is being passed an index whose internalPointer(), when casted to a KSysGuard::Process *, has a corrupted d-pointer with value 0x21 (close to a nullptr).

I made several execution runs with debug statements in libksysguard's Process and ~Process, and found that this happens when a Process is created at addr, freed at addr, and then internalPointer() has value addr + 0x10.

I also found crashes where a Process is created at addr, freed at addr, and then proc->parent() has value addr (a dangling pointer) but ProcessDataModel::parent() calls d->getQModelIndex(proc->parent(), 0) anyway. Backtrace at https://gist.github.com/nyanpasu64/0efbf70fc300203700233d1a56488453/raw/2ef75597b717c9dcf945acfa1afcf0e77b7e07d0/gistfile1.txt.

I think the bug is that when a system creates a parent process with a child, it's represented as a parent and child Process. And when the parent gets killed before the child, I guess there's a race condition where sometimes the Process::d::parent pointer isn't updated to init by Process::setParent().

I also saw another crash where index.internalPointer() was null: https://gist.githubusercontent.com/nyanpasu64/0efbf70fc300203700233d1a56488453/raw/2ef75597b717c9dcf945acfa1afcf0e77b7e07d0/gistfile2.txt

I didn't investigate how this happened though.
Comment 11 nyanpasu64 2021-08-14 03:00:24 UTC
I think I found the crash (or at least one cause of it). Crash call stack:

#0  KSysGuard::Process::parent (this=<optimized out>) at /usr/src/debug/libksysguard-5.22.4/processcore/process.cpp:248
#1  0x00007fffe011dd76 in KSysGuard::ProcessDataModel::parent (this=<optimized out>, index=...) at /usr/src/debug/libksysguard-5.22.4/processcore/process_data_model.cpp:181
#2  0x00007ffff5d52f83 in QIdentityProxyModel::parent(QModelIndex const&) const () from /usr/lib/libQt5Core.so.5
#3  0x00007ffff5d52f83 in QIdentityProxyModel::parent(QModelIndex const&) const () from /usr/lib/libQt5Core.so.5
#4  0x00007ffff5d65b41 in ?? () from /usr/lib/libQt5Core.so.5
#5  0x00007ffff5dc8790 in ?? () from /usr/lib/libQt5Core.so.5
#6  0x00007ffff5d2a186 in QAbstractItemModel::dataChanged(QModelIndex const&, QModelIndex const&, QVector<int> const&) () from /usr/lib/libQt5Core.so.5
#7  0x00007fffe015c95b in ComponentCacheProxyModel::createPendingInstance (this=<optimized out>) at /usr/src/debug/plasma-systemmonitor-5.22.4/src/table/ComponentCacheProxyModel.cpp:126
#8  ComponentCacheProxyModel::createPendingInstance (this=0x555557efe9b0) at /usr/src/debug/plasma-systemmonitor-5.22.4/src/table/ComponentCacheProxyModel.cpp:106
#9  0x00007ffff5dbe4ff in QObject::event(QEvent*) () from /usr/lib/libQt5Core.so.5

For some reason, plasma-systemmonitor creates a ComponentCacheProxyModel (https://github.com/KDE/plasma-systemmonitor/blob/1612127fb300a71dfa187cb78128f6728e489352/src/table/ComponentCacheProxyModel.cpp) to wrap a KSysGuard::ProcessDataModel. When a ComponentCacheProxyModel receives a ComponentCacheProxyModel::data() request with role CachedComponentRole, it *queues* the QModelIndex passed in (whose internalPointer() points to a KSysGuard::Process) into ComponentCacheProxyModel::m_pendingInstances, and *schedules* a call to ComponentCacheProxyModel::createPendingInstance(). By the time createPendingInstance() is called, Processes::processesUpdated() has been called which deletes the KSysGuard::Process. createPendingInstance() calls Q_EMIT dataChanged(index, index, {CachedComponentRole}) on a QModelIndex index, whose internalPointer() is dangling, but gets used anyway (use-after-free) with unpredictable results.

I think it's wrong for ComponentCacheProxyModel to be caching QModelIndex values (which are ephemeral and "borrowed" from Processes) across event loop iterations, since they can get invalidated by other event loop callbacks.

I think that looking for bugs in Processes::processesUpdated() was a false lead. The code is confusing to follow and not obviously correct, but I haven't found any errors that occur in practice (d->mAbstractProcesses->getParentPid(pid) never returns a Pid not found in d->mAbstractProcesses->getAllPids()). However, Processes is *very* precarious and may segfault if mAbstractProcesses's AbstractProcesses subclass returns malformed data.
Comment 12 Bug Janitor Service 2021-08-20 12:35:56 UTC
A possibly relevant merge request was started @ https://invent.kde.org/plasma/plasma-systemmonitor/-/merge_requests/158
Comment 13 Arjen Hiemstra 2021-08-24 19:41:23 UTC
Git commit f96f1d20ee03e36bd9d59cf145bf26d15ef860d7 by Arjen Hiemstra.
Committed on 24/08/2021 at 19:37.
Pushed by ahiemstra into branch 'master'.

Do not emit dataChange for a row that is being removed

This keeps track of which process that is being removed and prevents
dataChange signals from being emitted for that process, since this is
something that can trip up proxy models.

M  +7    -2    processcore/process_data_model.cpp

https://invent.kde.org/plasma/libksysguard/commit/f96f1d20ee03e36bd9d59cf145bf26d15ef860d7
Comment 14 Arjen Hiemstra 2021-08-26 08:06:52 UTC
Git commit e9abcd11d553bd93ed143e81d8cd3fe226faa606 by Arjen Hiemstra.
Committed on 26/08/2021 at 08:06.
Pushed by ahiemstra into branch 'master'.

Use QPersistentModelIndex to store indices in ComponentCacheProxyModel

QModelIndex becomes invalid if anything in the model it comes from
changes. This can lead to crashes if the underlying item has been
removed.

M  +3    -0    src/table/ComponentCacheProxyModel.cpp
M  +2    -2    src/table/ComponentCacheProxyModel.h

https://invent.kde.org/plasma/plasma-systemmonitor/commit/e9abcd11d553bd93ed143e81d8cd3fe226faa606