Bug 435532 - Crash in KSysGuard::Process::userUsage() while browsing processes page
Summary: Crash in KSysGuard::Process::userUsage() while browsing processes page
Status: RESOLVED FIXED
Alias: None
Product: plasma-systemmonitor
Classification: Applications
Component: general (other bugs)
Version First Reported In: unspecified
Platform: Other Linux
: NOR crash
Target Milestone: ---
Assignee: KSysGuard Developers
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2021-04-09 05:00 UTC by Nate Graham
Modified: 2021-04-09 09:40 UTC (History)
3 users (show)

See Also:
Latest Commit:
Version Fixed/Implemented In:
Sentry Crash Report:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Nate Graham 2021-04-09 05:00:38 UTC
Everything KDE from git master on openSUSE Tumbleweed.

I have seen this crash twice, though I cannot reproduce it on demand.


Core was generated by `plasma-systemmonitor'.
Program terminated with signal SIGSEGV, Segmentation fault.
#0  0x00007fb034251984 in KSysGuard::Process::userUsage (this=this@entry=0x36e5e30)
    at /home/nate/kde/src/libksysguard/processcore/process.cpp:308
308         return d->userUsage;
[Current thread is 1 (Thread 0x7fb05985d880 (LWP 18644))]
(gdb) bt
#0  0x00007fb034251984 in KSysGuard::Process::userUsage (this=this@entry=0x36e5e30)
    at /home/nate/kde/src/libksysguard/processcore/process.cpp:308
#1  0x00007fb034248ec1 in operator() (__closure=<optimized out>, p=0x36e5e30)
    at /home/nate/kde/src/libksysguard/processcore/extended_process_list.cpp:214
#2  std::__invoke_impl<int, KSysGuard::ExtendedProcesses::ExtendedProcesses(QObject*)::<lambda(KSysGuard::Process*)>&, KSysGuard::Process*> (__f=...) at /usr/include/c++/10/bits/invoke.h:60
#3  std::__invoke_r<int, KSysGuard::ExtendedProcesses::ExtendedProcesses(QObject*)::<lambda(KSysGuard::Process*)>&, KSysGuard::Process*> (__fn=...) at /usr/include/c++/10/bits/invoke.h:113
#4  std::_Function_handler<int(KSysGuard::Process*), KSysGuard::ExtendedProcesses::ExtendedProcesses(QObject*)::<lambda(KSysGuard::Process*)> >::_M_invoke(const std::_Any_data &, KSysGuard::Process *&&) (__functor=..., __args#0=<optimized out>) at /usr/include/c++/10/bits/std_function.h:291
#5  0x00007fb03424d0c9 in std::function<int (KSysGuard::Process*)>::operator()(KSysGuard::Process*) const (__args#0=<optimized out>, this=<optimized out>)
    at /usr/include/c++/10/bits/std_function.h:622
#6  ProcessSensor<int>::data (this=<optimized out>, process=<optimized out>)
    at /home/nate/kde/src/libksysguard/processcore/extended_process_list.cpp:74
#7  0x00007fb0342527ab in operator() (process=<optimized out>, total=32, 
    __closure=<synthetic pointer>)
    at /home/nate/kde/src/libksysguard/processcore/process_attribute.cpp:169
#8  std::accumulate<KSysGuard::Process* const*, double, KSysGuard::ProcessAttribute::cgroupData(KSysGuard::CGroup*, const QVector<KSysGuard::Process*>&) const::<lambda(qreal, KSysGuard::Process*)> >
    (__binary_op=..., __init=32, __last=0x35ce5b0, __first=0x35ce568)
    at /usr/include/c++/10/bits/stl_numeric.h:169
#9  KSysGuard::ProcessAttribute::cgroupData (this=this@entry=0x4b50960, 
    cgroup=cgroup@entry=0x4fa3e50, groupProcesses=...)
    at /home/nate/kde/src/libksysguard/processcore/process_attribute.cpp:168
#10 0x00007fb0342477ca in KSysGuard::CGroupDataModel::data (this=0x4b430a0, index=..., 
    role=<optimized out>) at /home/nate/kde/src/libksysguard/processcore/cgroup_data_model.cpp:258
#11 0x00007fb05bc1494e in QAbstractProxyModel::data (this=<optimized out>, proxyIndex=..., 
    role=256) at itemmodels/qabstractproxymodel.cpp:245
#12 0x00007fb03421c68d in ColumnDisplayModel::data (this=0x4b42d30, index=..., 
    role=<optimized out>)
    at /home/nate/kde/src/plasma-systemmonitor/src/table/ColumnDisplayModel.cpp:36
#13 0x00007fb05bc1494e in QAbstractProxyModel::data (this=<optimized out>, proxyIndex=..., 
    role=256) at itemmodels/qabstractproxymodel.cpp:245
#14 0x00007fb03421ebd4 in ComponentCacheProxyModel::data (this=0x4b42850, proxyIndex=..., 
    role=<optimized out>)
    at /home/nate/kde/src/plasma-systemmonitor/src/table/ComponentCacheProxyModel.cpp:48
#15 0x00007fb05bc23749 in QSortFilterProxyModel::data (this=<optimized out>, index=..., role=256)
    at itemmodels/qsortfilterproxymodel.cpp:2250
#16 0x00007fb05c62ff4f in QModelIndex::data (arole=256, this=0x7ffd816957c0)
    at /usr/include/qt5/QtCore/qabstractitemmodel.h:460
#17 QQmlDMAbstractItemModelData::value (role=256, this=0x4f42580)
    at /usr/src/debug/libqt5-qtdeclarative-5.15.2-3.1.x86_64/src/qmlmodels/qqmladaptormodel.cpp:414
#18 QQmlDMCachedModelData::metaCall (this=0x4f42580, call=<optimized out>, id=<optimized out>, 
    arguments=0x7ffd81695870)
    at /usr/src/debug/libqt5-qtdeclarative-5.15.2-3.1.x86_64/src/qmlmodels/qqmladaptormodel.cpp:282
#19 0x00007fb05c3247c1 in QQmlPropertyData::readPropertyWithArgs (this=<optimized out>, 
    this=<optimized out>, args=0x7ffd81695870, target=0x4f42580)
    at /usr/src/debug/libqt5-qtdeclarative-5.15.2-3.1.x86_64/include/QtQml/5.15.2/QtQml/private/../.--Type <RET> for more, q to quit, c to continue without paging--
./../../../src/qml/qml/qqmlpropertydata_p.h:285
#20 QQmlPropertyData::readPropertyWithArgs (args=0x7ffd81695870, target=0x4f42580, this=0x4de7008)
    at /usr/src/debug/libqt5-qtdeclarative-5.15.2-3.1.x86_64/include/QtQml/5.15.2/QtQml/private/../../../../../src/qml/qml/qqmlpropertydata_p.h:360
#21 QQmlPropertyData::readProperty (property=0x7ffd81695850, target=0x4f42580, this=0x4de7008)
    at /usr/src/debug/libqt5-qtdeclarative-5.15.2-3.1.x86_64/include/QtQml/5.15.2/QtQml/private/../../../../../src/qml/qml/qqmlpropertydata_p.h:357
#22 loadProperty (v4=0x7fb050006fe0, object=0x4f42580, property=...)
    at /usr/src/debug/libqt5-qtdeclarative-5.15.2-3.1.x86_64/src/qml/jsruntime/qv4qobjectwrapper.cpp:176
#23 0x00007fb0340aa8ba in ?? ()
#24 0x0000000000000000 in ?? ()
Comment 1 David Edmundson 2021-04-09 09:09:36 UTC
valggrind log

I suspect it's a regression with the shared processes's list 

,QObject(0x0)) is not valid (expected valid)
==60008== Invalid read of size 8
==60008==    at 0x1BA3B27C: KSysGuard::Process::userUsage() const (src/kde/workspace/libksysguard/processcore/process.cpp:308)
==60008==    by 0x1BA29F48: KSysGuard::ExtendedProcesses::ExtendedProcesses(QObject*)::$_25::operator()(KSysGuard::Process*) const (src/kde/workspace/libksysguard/processcore/extended_process_list.cpp:214)
==60008==    by 0x1BA29F11: int std::__invoke_impl<int, KSysGuard::ExtendedProcesses::ExtendedProcesses(QObject*)::$_25&, KSysGuard::Process*>(std::__invoke_other, KSysGuard::ExtendedProcesses::ExtendedProcesses(QObject*)::$_25&, KSysGuard::Process*&&) (invoke.h:60)
==60008==    by 0x1BA29EA1: std::enable_if<is_invocable_r_v<int, KSysGuard::ExtendedProcesses::ExtendedProcesses(QObject*)::$_25&, KSysGuard::Process*>, int>::type std::__invoke_r<int, KSysGuard::ExtendedProcesses::ExtendedProcesses(QObject*)::$_25&, KSysGuard::Process*>(KSysGuard::ExtendedProcesses::ExtendedProcesses(QObject*)::$_25&, KSysGuard::Process*&&) (invoke.h:113)
==60008==    by 0x1BA29DA1: std::_Function_handler<int (KSysGuard::Process*), KSysGuard::ExtendedProcesses::ExtendedProcesses(QObject*)::$_25>::_M_invoke(std::_Any_data const&, KSysGuard::Process*&&) (std_function.h:291)
==60008==    by 0x1BA30CB3: std::function<int (KSysGuard::Process*)>::operator()(KSysGuard::Process*) const (std_function.h:622)
==60008==    by 0x1BA3091F: ProcessSensor<int>::data(KSysGuard::Process*) const (src/kde/workspace/libksysguard/processcore/extended_process_list.cpp:74)
==60008==    by 0x1BA3DA0D: KSysGuard::ProcessAttribute::cgroupData(KSysGuard::CGroup*, QVector<KSysGuard::Process*> const&) const::$_0::operator()(double, KSysGuard::Process*) const (src/kde/workspace/libksysguard/processcore/process_attribute.cpp:169)
==60008==    by 0x1BA3D788: double std::accumulate<KSysGuard::Process* const*, double, KSysGuard::ProcessAttribute::cgroupData(KSysGuard::CGroup*, QVector<KSysGuard::Process*> const&) const::$_0>(KSysGuard::Process* const*, KSysGuard::Process* const*, double, KSysGuard::ProcessAttribute::cgroupData(KSysGuard::CGroup*, QVector<KSysGuard::Process*> const&) const::$_0) (stl_numeric.h:169)
==60008==    by 0x1BA3D715: KSysGuard::ProcessAttribute::cgroupData(KSysGuard::CGroup*, QVector<KSysGuard::Process*> const&) const (src/kde/workspace/libksysguard/processcore/process_attribute.cpp:168)
==60008==    by 0x1BA15EA0: KSysGuard::CGroupDataModel::data(QModelIndex const&, int) const (src/kde/workspace/libksysguard/processcore/cgroup_data_model.cpp:258)
==60008==    by 0x78EF8D3: QAbstractProxyModel::data(QModelIndex const&, int) const (qabstractproxymodel.cpp:245)
==60008==  Address 0x17070bf8 is 8 bytes inside a block of size 16 free'd
==60008==    at 0x483FEAB: operator delete(void*) (vg_replace_malloc.c:584)
==60008==    by 0x1BA3A9A7: KSysGuard::Process::~Process() (src/kde/workspace/libksysguard/processcore/process.cpp:108)
==60008==    by 0x1BA36EE7: KSysGuard::Processes::deleteProcess(long) (src/kde/workspace/libksysguard/processcore/processes.cpp:430)
==60008==    by 0x1BA341AD: KSysGuard::Processes::processesUpdated() (src/kde/workspace/libksysguard/processcore/processes.cpp:330)
==60008==    by 0x1BA38D50: QtPrivate::FunctorCall<QtPrivate::IndexesList<>, QtPrivate::List<>, void, void (KSysGuard::Processes::*)()>::call(void (KSysGuard::Processes::*)(), KSysGuard::Processes*, void**) (qobjectdefs_impl.h:152)
==60008==    by 0x1BA38CB7: void QtPrivate::FunctionPointer<void (KSysGuard::Processes::*)()>::call<QtPrivate::List<>, void>(void (KSysGuard::Processes::*)(), KSysGuard::Processes*, void**) (qobjectdefs_impl.h:185)
==60008==    by 0x1BA38BE4: QtPrivate::QSlotObject<void (KSysGuard::Processes::*)(), QtPrivate::List<>, void>::impl(int, QtPrivate::QSlotObjectBase*, QObject*, void**, bool*) (qobjectdefs_impl.h:418)
==60008==    by 0x794AC56: QtPrivate::QSlotObjectBase::call(QObject*, void**) (qobjectdefs_impl.h:398)
==60008==    by 0x798DF0F: void doActivate<false>(QObject*, int, void**) (qobject.cpp:3886)
==60008==    by 0x7987470: QMetaObject::activate(QObject*, QMetaObject const*, int, void**) (qobject.cpp:3946)
==60008==    by 0x1BA0B374: KSysGuard::AbstractProcesses::processesUpdated() (moc_processes_base_p.cpp:157)
==60008==    by 0x1BA4197D: KSysGuard::ProcessesLocal::updateAllProcesses(QFlags<KSysGuard::Processes::UpdateFlag>) (src/kde/workspace/libksysguard/processcore/processes_local_p.h:57)
==60008==  Block was alloc'd at
==60008==    at 0x483EDEF: operator new(unsigned long) (vg_replace_malloc.c:342)
==60008==    by 0x1BA34F48: KSysGuard::Processes::addProcess(long, long) (src/kde/workspace/libksysguard/processcore/processes.cpp:261)
==60008==    by 0x1BA351DF: KSysGuard::Processes::updateOrAddProcess(long) (src/kde/workspace/libksysguard/processcore/processes.cpp:305)
==60008==    by 0x1BA342BF: KSysGuard::Processes::processesUpdated() (src/kde/workspace/libksysguard/processcore/processes.cpp:348)
==60008==    by 0x1BA38D50: QtPrivate::FunctorCall<QtPrivate::IndexesList<>, QtPrivate::List<>, void, void (KSysGuard::Processes::*)()>::call(void (KSysGuard::Processes::*)(), KSysGuard::Processes*, void**) (qobjectdefs_impl.h:152)
==60008==    by 0x1BA38CB7: void QtPrivate::FunctionPointer<void (KSysGuard::Processes::*)()>::call<QtPrivate::List<>, void>(void (KSysGuard::Processes::*)(), KSysGuard::Processes*, void**) (qobjectdefs_impl.h:185)
==60008==    by 0x1BA38BE4: QtPrivate::QSlotObject<void (KSysGuard::Processes::*)(), QtPrivate::List<>, void>::impl(int, QtPrivate::QSlotObjectBase*, QObject*, void**, bool*) (qobjectdefs_impl.h:418)
==60008==    by 0x794AC56: QtPrivate::QSlotObjectBase::call(QObject*, void**) (qobjectdefs_impl.h:398)
==60008==    by 0x798DF0F: void doActivate<false>(QObject*, int, void**) (qobject.cpp:3886)
==60008==    by 0x7987470: QMetaObject::activate(QObject*, QMetaObject const*, int, void**) (qobject.cpp:3946)
==60008==    by 0x1BA0B374: KSysGuard::AbstractProcesses::processesUpdated() (moc_processes_base_p.cpp:157)
==60008==    by 0x1BA4197D: KSysGuard::ProcessesLocal::updateAllProcesses(QFlags<KSysGuard::Processes::UpdateFlag>) (src/kde/workspace/libksysguard/processcore/processes_local_p.h:57)
Comment 2 David Edmundson 2021-04-09 09:11:37 UTC
Urgh, right we cache processes:

QVector<Process*> CGroupDataModelPrivate::processesFor(CGroup *app)
{
    if (m_processMap.contains(app)) {
        return m_processMap.value(app);
    }
....

but now it's shared, process objects can be deleted at any time
Comment 3 Bug Janitor Service 2021-04-09 09:25:26 UTC
A possibly relevant merge request was started @ https://invent.kde.org/plasma/libksysguard/-/merge_requests/145
Comment 4 David Edmundson 2021-04-09 09:40:28 UTC
Git commit 5e548060802cfbd43a10a7f9c18b646212f7d9c8 by David Edmundson.
Committed on 09/04/2021 at 09:40.
Pushed by davidedmundson into branch 'master'.

Clear cgroup PIDS -> process object cache whenever Processes update

Previously we wiped the cache whenever CGroupDataModel is about to call
updateAllProcesses. With the shared backend we need to clear it whenever
any part updates.

M  +7    -5    processcore/cgroup_data_model.cpp

https://invent.kde.org/plasma/libksysguard/commit/5e548060802cfbd43a10a7f9c18b646212f7d9c8