SUMMARY Nothing happens when trying to load kamera in kcmshell STEPS TO REPRODUCE 1. Open Konsole and type `kcmshell6 kcm_kamera` (no camera connected) OBSERVED RESULT Kamera icon appears in taskbar, but nothing more EXPECTED RESULT Should open Kamera (as is possible in systemsettings) SOFTWARE/OS VERSIONSDistribution: openSUSE Tumbleweed 20240520 Linux: 6.9.1-1-default (64-bit) KDE Plasma Version: 6.0.4 KDE Frameworks Version: 6.2.0 Qt Version: 6.7.0 gPhoto: 2.5.28 ADDITIONAL INFORMATION I tried to look into it and I think that I understood the root cause. I set two breakpoints with GDB: Breakpoint 1at KCMultiDialogPrivate::clientChanged() Breakpoint 2 at KKameraConfig::load() When I ran kcmshell6, I noticed that KCMultiDialogPrivate::clientChanged() is called three times before is called KKameraConfig::load(). Consequently many 0s timer are lauched. The first will ultimately call KKameraConfig::load() which uses gphoto functions, which call the cancel callback, which let the event-loop run and call again the KKameraConfig::load() from inside the previous one as demonstrated in this trace: #0 KKameraConfig::load() (this=0x555555b52ed0) at /usr/src/debug/kamera-24.02.2/kcontrol/kamera.cpp:182 #1 0x00007ffff7f91930 in operator() (__closure=<optimized out>) at /usr/src/debug/kcmutils-6.2.0/src/kcmultidialog.cpp:130 #2 QtPrivate::FunctorCall<QtPrivate::IndexesList<>, QtPrivate::List<>, void, KCMultiDialogPrivate::clientChanged()::<lambda()> >::call (arg=<optimized out>, f=<optimized out>) at /usr/include/qt6/QtCore/qobjectdefs_impl.h:137 #3 QtPrivate::FunctorCallable<KCMultiDialogPrivate::clientChanged()::<lambda()> >::call<QtPrivate::List<>, void> (arg=<optimized out>, f=<optimized out>) at /usr/include/qt6/QtCore/qobjectdefs_impl.h:345 #4 QtPrivate::QCallableObject<KCMultiDialogPrivate::clientChanged()::<lambda()>, QtPrivate::List<>, void>::impl(int, QtPrivate::QSlotObjectBase *, QObject *, void **, bool *) (which=<optimized out>, this_=0x555555c3a730, r=<optimized out>, a=<optimized out>, ret=<optimized out>) at /usr/include/qt6/QtCore/qobjectdefs_impl.h:555 #5 0x00007ffff61d232e in QObject::event(QEvent*) (this=0x555555997820, e=0x555555c09d20) at /usr/src/debug/qtbase-everywhere-src-6.7.0/src/corelib/kernel/qobject.cpp:1446 #6 0x00007ffff73c2f1e in QApplicationPrivate::notify_helper(QObject*, QEvent*) () at /lib64/libQt6Widgets.so.6 #7 0x00007ffff618f060 in QCoreApplication::notifyInternal2(QObject*, QEvent*) (receiver=0x555555997820, event=0x555555c09d20) at /usr/src/debug/qtbase-everywhere-src-6.7.0/src/corelib/kernel/qcoreapplication.cpp:1134 #8 0x00007ffff618f099 in QCoreApplication::sendEvent(QObject*, QEvent*) (receiver=<optimized out>, event=<optimized out>) at /usr/src/debug/qtbase-everywhere-src-6.7.0/src/corelib/kernel/qcoreapplication.cpp:1575 #9 0x00007ffff618f3c0 in QCoreApplicationPrivate::sendPostedEvents(QObject*, int, QThreadData*) (receiver=0x0, event_type=0, data=0x555555593360) at /usr/src/debug/qtbase-everywhere-src-6.7.0/src/corelib/kernel/qcoreapplication.cpp:1932 #10 0x00007ffff63c2053 in postEventSourceDispatch(GSource*, GSourceFunc, gpointer) (s=0x555555599750) at /usr/src/debug/qtbase-everywhere-src-6.7.0/src/corelib/kernel/qeventdispatcher_glib.cpp:244 #11 0x00007ffff5b12740 in () at /lib64/libglib-2.0.so.0 #12 0x00007ffff5b14388 in () at /lib64/libglib-2.0.so.0 #13 0x00007ffff5b14a3c in g_main_context_iteration () at /lib64/libglib-2.0.so.0 #14 0x00007ffff63c0b0c in QEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) (this=0x5555555afca0, flags=...) at /usr/src/debug/qtbase-everywhere-src-6.7.0/src/corelib/kernel/qeventdispatcher_glib.cpp:394 #15 0x00007fffeb55559b in KKameraConfig::cbGPCancel(_GPContext*, void*) (data=0x555555b52ed0) at /usr/include/qt6/QtCore/qflags.h:74 #16 0x00007fffe906e856 in () at /lib64/libgphoto2.so.6 #17 0x00007fffe906e9e0 in gp_abilities_list_load_dir () at /lib64/libgphoto2.so.6 #18 0x00007fffe906ea29 in gp_abilities_list_load () at /lib64/libgphoto2.so.6 #19 0x00007fffeb55b303 in KKameraConfig::load() (this=0x555555b52ed0) at /usr/src/debug/kamera-24.02.2/kcontrol/kamera.cpp:219 #20 0x00007ffff7f91930 in operator() (__closure=<optimized out>) at /usr/src/debug/kcmutils-6.2.0/src/kcmultidialog.cpp:130 #21 QtPrivate::FunctorCall<QtPrivate::IndexesList<>, QtPrivate::List<>, void, KCMultiDialogPrivate::clientChanged()::<lambda()> >::call (arg=<optimized out>, f=<optimized out>) at /usr/include/qt6/QtCore/qobjectdefs_impl.h:137 #22 QtPrivate::FunctorCallable<KCMultiDialogPrivate::clientChanged()::<lambda()> >::call<QtPrivate::List<>, void> (arg=<optimized out>, f=<optimized out>) at /usr/include/qt6/QtCore/qobjectdefs_impl.h:345 #23 QtPrivate::QCallableObject<KCMultiDialogPrivate::clientChanged()::<lambda()>, QtPrivate::List<>, void>::impl(int, QtPrivate::QSlotObjectBase *, QObject *, void **, bool *) (which=<optimized out>, this_=0x555555b70120, r=<optimized out>, a=<optimized out>, ret=<optimized out>) at /usr/include/qt6/QtCore/qobjectdefs_impl.h:555 #24 0x00007ffff61d232e in QObject::event(QEvent*) (this=0x555555997820, e=0x555555b701b0) at /usr/src/debug/qtbase-everywhere-src-6.7.0/src/corelib/kernel/qobject.cpp:1446 #25 0x00007ffff73c2f1e in QApplicationPrivate::notify_helper(QObject*, QEvent*) () at /lib64/libQt6Widgets.so.6 #26 0x00007ffff618f060 in QCoreApplication::notifyInternal2(QObject*, QEvent*) (receiver=0x555555997820, event=0x555555b701b0) at /usr/src/debug/qtbase-everywhere-src-6.7.0/src/corelib/kernel/qcoreapplication.cpp:1134 #27 0x00007ffff618f099 in QCoreApplication::sendEvent(QObject*, QEvent*) (receiver=<optimized out>, event=<optimized out>) at /usr/src/debug/qtbase-everywhere-src-6.7.0/src/corelib/kernel/qcoreapplication.cpp:1575 #28 0x00007ffff618f3c0 in QCoreApplicationPrivate::sendPostedEvents(QObject*, int, QThreadData*) (receiver=0x0, event_type=0, data=0x555555593360) at /usr/src/debug/qtbase-everywhere-src-6.7.0/src/corelib/kernel/qcoreapplication.cpp:1932 #29 0x00007ffff63c2053 in postEventSourceDispatch(GSource*, GSourceFunc, gpointer) (s=0x555555599750) at /usr/src/debug/qtbase-everywhere-src-6.7.0/src/corelib/kernel/qeventdispatcher_glib.cpp:244 #30 0x00007ffff5b12740 in () at /lib64/libglib-2.0.so.0 #31 0x00007ffff5b14388 in () at /lib64/libglib-2.0.so.0 #32 0x00007ffff5b14a3c in g_main_context_iteration () at /lib64/libglib-2.0.so.0 #33 0x00007ffff63c0b0c in QEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) (this=0x5555555afca0, flags=...) at /usr/src/debug/qtbase-everywhere-src-6.7.0/src/corelib/kernel/qeventdispatcher_glib.cpp:394 #34 0x00007ffff61997db in QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) (this=0x7fffffffd610, flags=...) at /usr/src/debug/qtbase-everywhere-src-6.7.0/src/corelib/global/qflags.h:34 #35 0x00007ffff6192fe6 in QCoreApplication::exec() () at /usr/src/debug/qtbase-everywhere-src-6.7.0/src/corelib/global/qflags.h:74 #36 0x000055555555ae43 in main(int, char**) (argc=<optimized out>, argv=<optimized out>) at /usr/src/debug/kcmutils-6.2.0/src/kcmshell/main.cpp:236 The solution would be to ensure that the KCMultiDialogPrivate::clientChanged() does not call the load() function of the kcm module many times. This can be achieved by inverting lines 130 and 131 of kcmultidialog.cpp.
Can confirm.
A possibly relevant merge request was started @ https://invent.kde.org/frameworks/kcmutils/-/merge_requests/223
Git commit a09b7a83f916159de5fc5e619a6412a3d434de31 by Christoph Cullmann, on behalf of Pascal COMBES. Committed on 31/05/2024 at 16:45. Pushed by cullmann into branch 'master'. Ensure KCM load function is called only once Below bug was caused by Kamera KCM load function being called many times. Since there is no way to check whether the KCM load function succedded, we use `firstShow` to tell that we called it. Of course, it could be interesting to avoid deadlock in Kamera KCM as well. M +1 -1 src/kcmultidialog.cpp https://invent.kde.org/frameworks/kcmutils/-/commit/a09b7a83f916159de5fc5e619a6412a3d434de31