Bug 492023 - Falkon crashes when unloading plugins
Summary: Falkon crashes when unloading plugins
Status: RESOLVED FIXED
Alias: None
Product: Falkon
Classification: Applications
Component: general (show other bugs)
Version: unspecified
Platform: Other Linux
: NOR crash
Target Milestone: ---
Assignee: Juraj
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2024-08-22 05:31 UTC by Juraj
Modified: 2024-09-20 20:51 UTC (History)
0 users

See Also:
Latest Commit:
Version Fixed In: 24.12.0
Sentry Crash Report:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Juraj 2024-08-22 05:31:16 UTC
SUMMARY
Falkon mishandles loading of plugins causing weird behaviours and crash.

STEPS TO REPRODUCE
1. Go to [Preferences > Extensions] and enable some plugins (eg. AutoScroll)
2. Press OK, in preferences (to close it)
3. Go to [Preferences > Extensions] and disable the same plugin (eg. Autoscroll)
4. Keep preferences window open till the crash
5. Enable the same plugin (eg. Autoscroll)
6. Disable the same plugin (eg. Autoscroll)

OBSERVED RESULT
Falkon crashes.

EXPECTED RESULT
Falkon does not crash.


There is a reverse version as well:

STEPS TO REPRODUCE
1. To see it better, go to enable StatusBar (since it has no protection from showing the same thing multiple times) [Menu > View > [x] Status Bar]
1. Go to [Preferences > Extensions] and enable some plugins (eg. GreaseMonkey)
2. Keep preferences window open
4. Disable the same plugin (eg. GreaseMonkey)
5. Enable the same plugin (eg. GreaseMonkey)
6. Repeat from point "4" multiple times

OBSERVED RESULT
When plugin is enabled, it loads.
When disabled, nothing happens and the plugin is still loaded.
When enabled multiple times, multiple instances of the same plugin are running.
Restarting Falkon "fixes" this issue.

EXPECTED RESULT
Plugin loads and unloads


SOFTWARE/OS VERSIONS
Qt Version: 6.7.2

ADDITIONAL INFORMATION
Possibly caused by the way how Plugins::Plugin::operator==() compares 2 plugins.
Current implementation does not take into account if the plugin has an isntance (isLoaded) or not, this makes it to look and work fine in Falkon UI and code as well; BUT cuases Qt to think that nothing changed when plugin is enabled  or disabled, so it does not update the item data with new plugin data (with instance changed), so causing this behaviour.

Possible workaround for Preferences window is to keep the plugin status in separate container instead of as data of QListWidgetItem (which relies on QVariant which uses operator==() to check if the new data are any different from the stored ones.)

PS: This is probably cause of SOME !random" crashes.



EXAMPLE BRACKTRACE:
*** Program received signal SIGSEGV (Segmentation fault) ***error: libFalkonPrivate.so.3 0x07841731: DW_TAG_member 'data' refers to type 0x000000000784746b which extends beyond the bounds of 0x07841727
(lldb) 18bt
* thread #1, name = 'falkon', stop reason = signal SIGSEGV: address not mapped to object (fault address: 0xb0)
* frame #0: 0x00007fffba4bc2c1 GreaseMonkey.so`int QAtomicOps<int>::loadRelaxed<int>(std::atomic<int> const&) [inlined] std::__atomic_base<int>::load(this=0x00000000000000b0, __m=memory_order_relaxed) const at atomic_base.h:501:24
frame #1: 0x00007fffba4bc27f GreaseMonkey.so`int QAtomicOps<int>::loadRelaxed<int>(_q_value=0x00000000000000b0) at qatomic_cxx11.h:202:29
frame #2: 0x00007fffba4bbe72 GreaseMonkey.so`QBasicAtomicInteger<int>::loadRelaxed(this=0x00000000000000b0) const at qbasicatomic.h:36:61
frame #3: 0x00007fffba4c1154 GreaseMonkey.so`QtPrivate::RefCount::ref(this=0x00000000000000b0) at qrefcount.h:19:39
frame #4: 0x00007fffba4c3847 GreaseMonkey.so`QHash<BrowserWindow*, GM_Icon*>::QHash(this=<size=0>, other=<size=0>) at qhash.h:847:23
frame #5: 0x00007fffba4c2680 GreaseMonkey.so`QHashIterator<BrowserWindow*, GM_Icon*>::QHashIterator(this=0x00007fffffffc3d0, container=<size=0>) at qhash.h:2189:1
frame #6: 0x00007fffba4bf7f3 GreaseMonkey.so`GM_Manager::unloadPlugin(this=0x000055555a360d30) at gm_manager.cpp:147:57
frame #7: 0x00007fffba4bcde0 GreaseMonkey.so`GM_Plugin::unload(this=0x0000555558a53cd0) at gm_plugin.cpp:54:28
frame #8: 0x00007ffff7b414c6 libFalkonPrivate.so.3`Plugins::unloadPlugin(this=0x0000555555e5d590, plugin=0x00007fffffffc520) at plugins.cpp:95:29
frame #9: 0x00007ffff7bae25a libFalkonPrivate.so.3`PluginsManager::itemChanged(this=0x00005555555d78a0, item=0x00005555598b4a60) at pluginsmanager.cpp:190:38
frame #10: 0x00007ffff7bb0b17 libFalkonPrivate.so.3`QtPrivate::FunctorCall<QtPrivate::IndexesList<0>, QtPrivate::List<QListWidgetItem*>, void, void (PluginsManager::*)(QListWidgetItem*)>::call(f=(libFalkonPrivate.so.3`PluginsManager::itemChanged(QListWidgetItem*) at pluginsmanager.cpp:177:1), o=0x00005555555d78a0, arg=0x00007fffffffc820) at qobjectdefs_impl.h:145:20
frame #11: 0x00007ffff7bb0970 libFalkonPrivate.so.3`void QtPrivate::FunctionPointer<void (PluginsManager::*)(QListWidgetItem*)>::call<QtPrivate::List<QListWidgetItem*>, void>(f=(libFalkonPrivate.so.3`PluginsManager::itemChanged(QListWidgetItem*) at pluginsmanager.cpp:177:1), o=0x00005555555d78a0, arg=0x00007fffffffc820) at qobjectdefs_impl.h:182:95
frame #12: 0x00007ffff7bb0755 libFalkonPrivate.so.3`QtPrivate::QCallableObject<void (PluginsManager::*)(QListWidgetItem*), QtPrivate::List<QListWidgetItem*>, void>::impl(which=1, this_=0x00007fffd800bae0, r=0x00005555555d78a0, a=0x00007fffffffc820, ret=0x0000000000000000) at qobjectdefs_impl.h:553:53
frame #13: 0x00007fffe95e2182 libQt6Core.so.6`void doActivate<false>(QObject*, int, void**) + 1410
frame #14: 0x00007fffec0b4bc2 libQt6Widgets.so.6`QListWidget::itemChanged(QListWidgetItem*) + 66
frame #15: 0x00007fffe95e2182 libQt6Core.so.6`void doActivate<false>(QObject*, int, void**) + 1410
frame #16: 0x00007fffe97debac libQt6Core.so.6`QAbstractItemModel::dataChanged(QModelIndex const&, QModelIndex const&, QList<int> const&) + 60
frame #17: 0x00007fffec0b92f1 libQt6Widgets.so.6`QListWidgetItem::setData(int, QVariant const&) + 465
frame #18: 0x00007fffec0b45e7 libQt6Widgets.so.6`QListModel::setData(QModelIndex const&, QVariant const&, int) + 55
frame #19: 0x00007fffec0941c2 libQt6Widgets.so.6`QStyledItemDelegate::editorEvent(QEvent*, QAbstractItemModel*, QStyleOptionViewItem const&, QModelIndex const&) + 1106
frame #20: 0x00007fffec063068 libQt6Widgets.so.6`QAbstractItemViewPrivate::sendDelegateEvent(QModelIndex const&, QEvent*) const + 216
frame #21: 0x00007fffec068a8c libQt6Widgets.so.6`QAbstractItemView::edit(QModelIndex const&, QAbstractItemView::EditTrigger, QEvent*) + 284
frame #22: 0x00007fffec0635d2 libQt6Widgets.so.6`QAbstractItemView::mouseReleaseEvent(QMouseEvent*) + 1186
frame #23: 0x00007fffec0af710 libQt6Widgets.so.6`QListView::mouseReleaseEvent(QMouseEvent*) + 32
frame #24: 0x00007fffebddf5b8 libQt6Widgets.so.6`QWidget::event(QEvent*) + 648
frame #25: 0x00007fffebe757f0 libQt6Widgets.so.6`QFrame::event(QEvent*) + 48
frame #26: 0x00007fffe957eb56 libQt6Core.so.6`QCoreApplicationPrivate::sendThroughObjectEventFilters(QObject*, QEvent*) + 134
frame #27: 0x00007fffebd81e61 libQt6Widgets.so.6`QApplicationPrivate::notify_helper(QObject*, QEvent*) + 113
frame #28: 0x00007fffebd8c70d libQt6Widgets.so.6`QApplication::notify(QObject*, QEvent*) + 3405
frame #29: 0x00007fffe957ee48 libQt6Core.so.6`QCoreApplication::notifyInternal2(QObject*, QEvent*) + 392
frame #30: 0x00007fffebd8ae7a libQt6Widgets.so.6`QApplicationPrivate::sendMouseEvent(QWidget*, QMouseEvent*, QWidget*, QWidget*, QWidget**, QPointer<QWidget>&, bool, bool) + 474
frame #31: 0x00007fffebdf1e18 libQt6Widgets.so.6`QWidgetWindow::handleMouseEvent(QMouseEvent*) + 856
frame #32: 0x00007fffebdf4a40 libQt6Widgets.so.6`QWidgetWindow::event(QEvent*) + 496
frame #33: 0x00007fffebd81e71 libQt6Widgets.so.6`QApplicationPrivate::notify_helper(QObject*, QEvent*) + 129
frame #34: 0x00007fffe957ee48 libQt6Core.so.6`QCoreApplication::notifyInternal2(QObject*, QEvent*) + 392
frame #35: 0x00007fffeabca3ab libQt6Gui.so.6`QGuiApplicationPrivate::processMouseEvent(QWindowSystemInterfacePrivate::MouseEvent*) + 1915
frame #36: 0x00007fffeac2b53c libQt6Gui.so.6`QWindowSystemInterface::sendWindowSystemEvents(QFlags<QEventLoop::ProcessEventsFlag>) + 172
frame #37: 0x00007fffe501e91a libQt6XcbQpa.so.6`xcbSourceDispatch(_GSource*, int (*)(void*), void*) + 26
frame #38: 0x00007fffe7a9f449 libglib-2.0.so.0`___lldb_unnamed_symbol2330 + 249
frame #39: 0x00007fffe7afebff libglib-2.0.so.0`___lldb_unnamed_symbol2637 + 831
frame #40: 0x00007fffe7a9e9c2 libglib-2.0.so.0`g_main_context_iteration + 50
frame #41: 0x00007fffe98595af libQt6Core.so.6`QEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) + 111
frame #42: 0x00007fffe958b3ba libQt6Core.so.6`QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) + 426
frame #43: 0x00007fffe9587614 libQt6Core.so.6`QCoreApplication::exec() + 148
frame #44: 0x0000555555557895 falkon`main(argc=4, argv=0x00007fffffffdfb8) at main.cpp:74:20
frame #45: 0x00007fffe8e37d6e libc.so.6`___lldb_unnamed_symbol3261 + 126
frame #46: 0x00007fffe8e37e2a libc.so.6`__libc_start_main + 138
frame #47: 0x0000555555557375 falkon`_start + 37
Comment 1 Bug Janitor Service 2024-08-23 21:36:37 UTC
A possibly relevant merge request was started @ https://invent.kde.org/network/falkon/-/merge_requests/83
Comment 2 Juraj 2024-09-20 20:51:20 UTC
Git commit fe81fe5aaa99d81512a4d241855fd425680b6ec9 by Juraj Oravec.
Committed on 20/09/2024 at 20:50.
Pushed by jurajo into branch 'master'.

Preferences: Fix crash when un/loading of plugins
FIXED-IN: 24.12.0

Signed-off-by: Juraj Oravec <jurajoravec@mailo.com>

M  +12   -8    src/lib/preferences/pluginsmanager.cpp
M  +3    -1    src/lib/preferences/pluginsmanager.h

https://invent.kde.org/network/falkon/-/commit/fe81fe5aaa99d81512a4d241855fd425680b6ec9