Bug 482095 - Specific search terms causes discover to assert
Summary: Specific search terms causes discover to assert
Status: RESOLVED FIXED
Alias: None
Product: Discover
Classification: Applications
Component: discover (show other bugs)
Version: 6.0.0
Platform: Neon Linux
: HI crash
Target Milestone: ---
Assignee: Plasma Bugs List
URL:
Keywords: qt6
: 477202 482065 482391 (view as bug list)
Depends on:
Blocks:
 
Reported: 2024-02-29 21:26 UTC by Jacob Osborne
Modified: 2024-03-08 03:08 UTC (History)
7 users (show)

See Also:
Latest Commit:
Version Fixed In: 6.0.2


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Jacob Osborne 2024-02-29 21:26:29 UTC
SUMMARY
Specific search terms causes discover to crash.


STEPS TO REPRODUCE
1. Open discover
2. Type free Into the search box
3. Press enter

OBSERVED RESULT
Discover crashes

EXPECTED RESULT
Search terms shouldn't cause discover to crash

SOFTWARE/OS VERSIONS
Linux/KDE Plasma: 6.5.0-21-generic (64-bit)
KDE Plasma Version: 6.0.0
KDE Frameworks Version: 6.0.0
Qt Version: 6.6.2

ADDITIONAL INFORMATION
Comment 1 guimarcalsilva 2024-02-29 23:14:03 UTC
I can reproduce the crash. It outputs the following in the terminal when the crash happens:
"ASSERT: "_res.size() == QSet(_res.constBegin(), _res.constEnd()).size()" in file ./libdiscover/resources/ResourcesProxyModel.cpp, line 636"

Dr. Konki cannot make a backtrace for some reason.

Words that make it crash:
Aa
Fedora
Open
Media
Plasma
Office

Words that don't crash Discover:
Aaa
Clear
Telegram
Firefox
KDEConnect
Edge
Vivaldi
Keyboard

Interestingly, if I write Fedora as feDoRa it doesn't crash, so capitalization also matters.
Comment 2 guimarcalsilva 2024-02-29 23:28:30 UTC
*** Bug 482065 has been marked as a duplicate of this bug. ***
Comment 3 guimarcalsilva 2024-03-02 16:02:44 UTC
I managed to get a backtrace:

Application: Discover (plasma-discover), signal: Aborted

[KCrash Handler]
#4  __pthread_kill_implementation (no_tid=0, signo=6, threadid=140347001359552) at ./nptl/pthread_kill.c:44
#5  __pthread_kill_internal (signo=6, threadid=140347001359552) at ./nptl/pthread_kill.c:78
#6  __GI___pthread_kill (threadid=140347001359552, signo=signo@entry=6) at ./nptl/pthread_kill.c:89
#7  0x00007fa519242476 in __GI_raise (sig=sig@entry=6) at ../sysdeps/posix/raise.c:26
#8  0x00007fa5192287f3 in __GI_abort () at ./stdlib/abort.c:79
#9  0x00007fa519edb017 in qAbort () at ./src/corelib/global/qglobal.cpp:161
#10 0x00007fa519ed64e5 in qt_message_fatal<QString&> (message=..., context=...) at ./src/corelib/global/qlogging.cpp:2003
#11 qt_message(QtMsgType, const QMessageLogContext &, const char *, typedef __va_list_tag __va_list_tag *) (msgType=msgType@entry=QtFatalMsg, context=..., msg=<optimized out>, ap=ap@entry=0x7ffc095f6460) at ./src/corelib/global/qlogging.cpp:378
#12 0x00007fa519edba43 in QMessageLogger::fatal (this=<optimized out>, msg=<optimized out>) at ./src/corelib/global/qlogging.cpp:901
#13 0x00007fa519ea9c94 in qt_assert (assertion=assertion@entry=0x7fa51c3a7cf0 "_res.size() == QSet(_res.constBegin(), _res.constEnd()).size()", file=file@entry=0x7fa51c3a76c8 "./libdiscover/resources/ResourcesProxyModel.cpp", line=line@entry=636) at ./src/corelib/global/qassert.cpp:68
#14 0x00007fa51c3347dc in ResourcesProxyModel::sortedInsertion (this=0x55f733261510, _res=...) at ./libdiscover/resources/ResourcesProxyModel.cpp:636
#15 0x00007fa51c375254 in ResourcesProxyModel::addResources (this=0x55f733261510, _res=...) at ./libdiscover/resources/ResourcesProxyModel.cpp:275
#16 0x00007fa519e2b7ce in QtPrivate::QSlotObjectBase::call (a=<optimized out>, r=<optimized out>, this=<optimized out>, this=<optimized out>, r=<optimized out>, a=<optimized out>) at ./src/corelib/kernel/qobjectdefs_impl.h:433
#17 doActivate<false> (sender=0x55f7337c9f20, signal_index=3, argv=0x7ffc095f6780) at ./src/corelib/kernel/qobject.cpp:4039
#18 0x00007fa51c339776 in ResultsStream::resourcesFound (this=<optimized out>, _t1=...) at ./obj-x86_64-linux-gnu/libdiscover/DiscoverCommon_autogen/3YJK5W5UP7/moc_AbstractResourcesBackend.cpp:187
#19 0x00007fa51c367e09 in AggregatedResultsStream::emitResults (this=0x55f7337c9f20) at ./libdiscover/resources/ResourcesModel.cpp:343
#20 0x00007fa519e2b7ce in QtPrivate::QSlotObjectBase::call (a=<optimized out>, r=<optimized out>, this=<optimized out>, this=<optimized out>, r=<optimized out>, a=<optimized out>) at ./src/corelib/kernel/qobjectdefs_impl.h:433
#21 doActivate<false> (sender=0x55f7337c9f50, signal_index=3, argv=0x7ffc095f68d0) at ./src/corelib/kernel/qobject.cpp:4039
#22 0x00007fa519dde14e in QTimer::timeout (this=<optimized out>, _t1=...) at ./obj-x86_64-linux-gnu/src/corelib/Core_autogen/include/moc_qtimer.cpp:272
#23 0x00007fa519dc94ce in QObject::event (this=0x55f7337c9f50, e=0x7ffc095f6a40) at ./src/corelib/kernel/qobject.cpp:1414
#24 0x00007fa51bff40eb in QApplicationPrivate::notify_helper (this=<optimized out>, receiver=0x55f7337c9f50, e=0x7ffc095f6a40) at ./src/widgets/kernel/qapplication.cpp:3296
#25 0x00007fa519e63e18 in QCoreApplication::notifyInternal2 (receiver=0x55f7337c9f50, event=0x7ffc095f6a40) at ./src/corelib/kernel/qcoreapplication.cpp:1121
#26 0x00007fa519d5f121 in QTimerInfoList::activateTimers (this=0x55f732c70940) at ./src/corelib/kernel/qtimerinfo_unix.cpp:507
#27 0x00007fa519c630fc in timerSourceDispatch (source=<optimized out>) at ./src/corelib/kernel/qeventdispatcher_glib.cpp:149
#28 0x00007fa518c79d3b in g_main_context_dispatch () from /lib/x86_64-linux-gnu/libglib-2.0.so.0
#29 0x00007fa518ccf258 in ?? () from /lib/x86_64-linux-gnu/libglib-2.0.so.0
#30 0x00007fa518c773e3 in g_main_context_iteration () from /lib/x86_64-linux-gnu/libglib-2.0.so.0
#31 0x00007fa519c5e1f0 in QEventDispatcherGlib::processEvents (this=0x55f732b73390, flags=...) at ./src/corelib/kernel/qeventdispatcher_glib.cpp:393
#32 0x00007fa519e6604b in QEventLoop::exec (this=this@entry=0x7ffc095f6ca0, flags=..., flags@entry=...) at ./src/corelib/global/qflags.h:34
#33 0x00007fa519e67c7c in QCoreApplication::exec () at ./src/corelib/global/qflags.h:74
#34 0x00007fa51a2e9a20 in QGuiApplication::exec () at ./src/gui/kernel/qguiapplication.cpp:1925
#35 0x00007fa51bff1689 in QApplication::exec () at ./src/widgets/kernel/qapplication.cpp:2574
#36 0x000055f732439f3c in main (argc=<optimized out>, argv=<optimized out>) at ./discover/main.cpp:218
[Inferior 1 (process 7680) detached]
Comment 4 Harald Sitter 2024-03-04 13:03:42 UTC
*** Bug 477202 has been marked as a duplicate of this bug. ***
Comment 5 Harald Sitter 2024-03-04 13:17:10 UTC
https://invent.kde.org/plasma/discover/-/blob/318739412171e08c60d13832a1584ebbfdd4bb9d/libdiscover/resources/ResourcesProxyModel.cpp#L636

The assert trips up on KNS resources that have the same user facing name.

For example here's `name packageName` when searching for 'libreoffice':

discover(67140)/(default) ResourcesProxyModel::sortedInsertion: "FS Icons Ubuntu" "1002489"
discover(67140)/(default) ResourcesProxyModel::sortedInsertion: "FS Icons Ubuntu" "1012533"

This happens because AbstractResource implements a nameSortKey() that is based on name. Indeed it must be because we want to sort the visual results by... name.

To pass the assertion I suppose the KNS backend should deduplicate names somehow?
Comment 6 Nate Graham 2024-03-05 20:14:47 UTC
*** Bug 482391 has been marked as a duplicate of this bug. ***
Comment 7 Aleix Pol 2024-03-06 20:06:58 UTC
@Harald, I'm not sure why you reached the conclusion that it's because of the nameSortKey. The deduplication happens when removing duplicates of the StreamResults and this is identified by their resource pointer address:

Q_ASSERT(results.size() == QSet(results.constBegin(), results.constEnd()).size());

inline size_t qHash(const StreamResult &key, size_t seed = 0)
{
    return qHash(quintptr(key.resource), seed);
}

I did a small test and it seems that we are emitting the same resource several times for the same stream. I'll make a patch for that. I have been able to reproduce the issue although not reliably so double-checking would be appreciated.
Comment 8 Bug Janitor Service 2024-03-06 20:12:14 UTC
A possibly relevant merge request was started @ https://invent.kde.org/plasma/discover/-/merge_requests/768
Comment 9 Harald Sitter 2024-03-06 20:31:09 UTC
(In reply to Aleix Pol from comment #7)
> @Harald, I'm not sure why you reached the conclusion that it's because of
> the nameSortKey. The deduplication happens when removing duplicates of the
> StreamResults and this is identified by their resource pointer address:
> 
> Q_ASSERT(results.size() == QSet(results.constBegin(),
> results.constEnd()).size());
> 
> inline size_t qHash(const StreamResult &key, size_t seed = 0)
> {
>     return qHash(quintptr(key.resource), seed);
> }
> 
> I did a small test and it seems that we are emitting the same resource
> several times for the same stream. I'll make a patch for that. I have been
> able to reproduce the issue although not reliably so double-checking would
> be appreciated.

Mh, you are right. I should have put on my glasses ;)
Comment 10 Aleix Pol 2024-03-06 23:36:09 UTC
Git commit 9272feb88bf1e29e4d05097637c21f081cf7775a by Aleix Pol.
Committed on 06/03/2024 at 22:01.
Pushed by apol into branch 'master'.

kns: Make sure we don't emit twice the same resource

It breaks assumptions in the front-end.

M  +9    -1    libdiscover/backends/KNSBackend/KNSBackend.cpp

https://invent.kde.org/plasma/discover/-/commit/9272feb88bf1e29e4d05097637c21f081cf7775a
Comment 11 Aleix Pol 2024-03-08 03:07:57 UTC
Git commit 6e64778eb517ed3fbd0ec440f4ed281443fe268e by Aleix Pol Gonzalez, on behalf of Aleix Pol.
Committed on 06/03/2024 at 23:58.
Pushed by ngraham into branch 'Plasma/6.0'.

kns: Make sure we don't emit twice the same resource

It breaks assumptions in the front-end.


(cherry picked from commit 9272feb88bf1e29e4d05097637c21f081cf7775a)

M  +9    -1    libdiscover/backends/KNSBackend/KNSBackend.cpp

https://invent.kde.org/plasma/discover/-/commit/6e64778eb517ed3fbd0ec440f4ed281443fe268e