Bug 452237 - kTimeTracker crashes when Continue or Revert buttons are pressed
Summary: kTimeTracker crashes when Continue or Revert buttons are pressed
Status: RESOLVED WORKSFORME
Alias: None
Product: ktimetracker
Classification: Applications
Component: general (other bugs)
Version First Reported In: 5.0.1
Platform: openSUSE Linux
: NOR crash
Target Milestone: ---
Assignee: Alexander Potashev
URL:
Keywords: drkonqi
: 460264 (view as bug list)
Depends on:
Blocks:
 
Reported: 2022-04-03 19:49 UTC by Mike M
Modified: 2023-03-12 16:41 UTC (History)
1 user (show)

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


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Mike M 2022-04-03 19:49:06 UTC
Application: ktimetracker (5.0.1)

Qt Version: 5.15.2
Frameworks Version: 5.92.0
Operating System: Linux 5.17.1-1-default x86_64
Windowing System: X11
Distribution: openSUSE Tumbleweed
DrKonqi: 5.24.4 [KCrashBackend]

-- Information about the crash:
The issue is when the desktop goes from idle to active. KTimeTracker asks if time should be continued or reverted. The application crashes when either button is pressed.

The crash can be reproduced every time.

-- Backtrace:
Application: KTimeTracker (ktimetracker), signal: Segmentation fault

[KCrash Handler]
#4  QHashData::nextNode (node=node@entry=0x5589e7f59c80) at tools/qhash.cpp:591
#5  0x00007f676ed6a9a0 in QHash<int, int>::const_iterator::operator++ (this=<synthetic pointer>) at /usr/include/qt5/QtCore/qhash.h:425
#6  KIdleTimePrivate::timeoutReached (msec=<optimized out>, this=0x5589e3b8ecf0) at /usr/src/debug/kidletime-5.92.0-1.1.x86_64/src/kidletime.cpp:291
#7  operator() (msec=<optimized out>, __closure=<optimized out>) at /usr/src/debug/kidletime-5.92.0-1.1.x86_64/src/kidletime.cpp:88
#8  QtPrivate::FunctorCall<QtPrivate::IndexesList<0>, QtPrivate::List<int>, void, KIdleTime::KIdleTime()::<lambda(int)> >::call (arg=<optimized out>, f=...) at /usr/include/qt5/QtCore/qobjectdefs_impl.h:146
#9  QtPrivate::Functor<KIdleTime::KIdleTime()::<lambda(int)>, 1>::call<QtPrivate::List<int>, void> (arg=<optimized out>, f=...) at /usr/include/qt5/QtCore/qobjectdefs_impl.h:256
#10 QtPrivate::QFunctorSlotObject<KIdleTime::KIdleTime()::<lambda(int)>, 1, QtPrivate::List<int>, void>::impl (which=<optimized out>, r=<optimized out>, ret=<optimized out>, a=<optimized out>, this_=<optimized out>) at /usr/include/qt5/QtCore/qobjectdefs_impl.h:443
#11 QtPrivate::QFunctorSlotObject<KIdleTime::KIdleTime()::<lambda(int)>, 1, QtPrivate::List<int>, void>::impl(int, QtPrivate::QSlotObjectBase *, QObject *, void **, bool *) (which=<optimized out>, this_=<optimized out>, r=<optimized out>, a=<optimized out>, ret=<optimized out>) at /usr/include/qt5/QtCore/qobjectdefs_impl.h:436
#12 0x00007f676d754503 in QtPrivate::QSlotObjectBase::call (a=0x7ffc8bb49480, r=0x5589e3ab29e0, this=0x5589e3aef300) at ../../include/QtCore/../../src/corelib/kernel/qobjectdefs_impl.h:398
#13 doActivate<false> (sender=0x5589e3ad79f0, signal_index=4, argv=0x7ffc8bb49480) at kernel/qobject.cpp:3886
#14 0x00007f676d74d9cf in QMetaObject::activate (sender=sender@entry=0x5589e3ad79f0, m=m@entry=0x7f676ed71d00 <AbstractSystemPoller::staticMetaObject>, local_signal_index=local_signal_index@entry=1, argv=argv@entry=0x7ffc8bb49480) at kernel/qobject.cpp:3946
#15 0x00007f676ed6a741 in AbstractSystemPoller::timeoutReached (this=this@entry=0x5589e3ad79f0, _t1=<optimized out>) at /usr/src/debug/kidletime-5.92.0-1.1.x86_64/build/src/KF5IdleTime_autogen/EWIEGA46WW/moc_abstractsystempoller.cpp:189
#16 0x00007f676204aa5b in XSyncBasedPoller::xcbEvent (event=0x7f676401aff0, this=0x5589e3ad79f0) at /usr/src/debug/kidletime-5.92.0-1.1.x86_64/src/plugins/xsync/xsyncbasedpoller.cpp:295
#17 XSyncBasedPoller::xcbEvent (event=0x7f676401aff0, this=0x5589e3ad79f0) at /usr/src/debug/kidletime-5.92.0-1.1.x86_64/src/plugins/xsync/xsyncbasedpoller.cpp:279
#18 XSyncBasedPollerHelper::nativeEventFilter (result=<optimized out>, message=0x7f676401aff0, eventType=..., this=0x7f676204f240 <(anonymous namespace)::Q_QGS_s_globalXSyncBasedPoller::innerFunction()::holder>) at /usr/src/debug/kidletime-5.92.0-1.1.x86_64/src/plugins/xsync/xsyncbasedpoller.cpp:44
#19 XSyncBasedPollerHelper::nativeEventFilter (this=0x7f676204f240 <(anonymous namespace)::Q_QGS_s_globalXSyncBasedPoller::innerFunction()::holder>, eventType=..., message=0x7f676401aff0, result=<optimized out>) at /usr/src/debug/kidletime-5.92.0-1.1.x86_64/src/plugins/xsync/xsyncbasedpoller.cpp:39
#20 0x00007f676d71b3cf in QAbstractEventDispatcher::filterNativeEvent (this=<optimized out>, eventType=..., message=message@entry=0x7f676401aff0, result=result@entry=0x7ffc8bb49518) at kernel/qabstracteventdispatcher.cpp:495
#21 0x00007f6768fb1491 in QXcbConnection::handleXcbEvent (this=this@entry=0x5589e3822c40, event=event@entry=0x7f676401aff0) at qxcbconnection.cpp:536
#22 0x00007f6768fb2b96 in QXcbConnection::processXcbEvents (this=0x5589e3822c40, flags=...) at qxcbconnection.cpp:1020
#23 0x00007f6768fd8e03 in xcbSourceDispatch (source=<optimized out>) at qxcbeventdispatcher.cpp:103
#24 0x00007f676bcee122 in g_main_context_dispatch () from /lib64/libglib-2.0.so.0
#25 0x00007f676bcee4b8 in ?? () from /lib64/libglib-2.0.so.0
#26 0x00007f676bcee56f in g_main_context_iteration () from /lib64/libglib-2.0.so.0
#27 0x00007f676d775384 in QEventDispatcherGlib::processEvents (this=0x5589e39b1080, flags=...) at kernel/qeventdispatcher_glib.cpp:423
#28 0x00007f676d71c83b in QEventLoop::exec (this=this@entry=0x7ffc8bb497a0, flags=..., flags@entry=...) at ../../include/QtCore/../../src/corelib/global/qflags.h:69
#29 0x00007f676d724b10 in QCoreApplication::exec () at ../../include/QtCore/../../src/corelib/global/qflags.h:121
#30 0x00005589e27ecea2 in main (argc=<optimized out>, argv=<optimized out>) at /usr/src/debug/ktimetracker-5.0.1-1.15.x86_64/src/main.cpp:169
[Inferior 1 (process 17572) detached]

Possible duplicates by query: bug 401450, bug 391363, bug 390214, bug 373054, bug 284337.

Reported using DrKonqi
Comment 1 Christof Kaufmann 2022-11-15 08:23:49 UTC
*** Bug 460264 has been marked as a duplicate of this bug. ***
Comment 2 Christof Kaufmann 2022-11-15 08:45:11 UTC
I can confirm this bug and investigated why it occurs. I like to share my findings.

This bug also occurs on Ubuntu 22.04 and generally when using Frameworks versions 5.92 and probably also 5.93. It is independent on the version of KTimeTracker. The bug hides in KIdleTime and has been resolved before 5.94 in this commit: https://invent.kde.org/frameworks/kidletime/-/commit/cd5040684723b87c7ba5b7cc1b1a63402902a641

It is triggered, when the IdleTimeDetector::timeoutReached method returns, because it removes the timeout within the timeoutReached event: https://invent.kde.org/pim/ktimetracker/-/blob/master/src/idletimedetector.cpp#L67
This invalidates the iterators of the loop that iterates the timeouts: https://invent.kde.org/frameworks/kidletime/-/commit/cd5040684723b87c7ba5b7cc1b1a63402902a641#6d37565e8c6a5cca30eb46326cb4141a54de39df_291_291
A valgrind backtrace is "appended" below

Though it has been fixed upstream, I like to discuss how to workaround the issue. The proper solution is to update Frameworks (including KIdleTime), but for Ubuntu this requires to update from 22.04 (LTS) to 22.10 (non-LTS). A backport seems not to be available. What's the best way to avoid that bug?

valgrind backtrace:
Invalid read of size 8
   at: QHashData::nextNode(QHashData::Node*) (qhash.cpp:589)
   by: QtPrivate::QFunctorSlotObject<KIdleTime::KIdleTime()::{lambda(int)#2}, 1, QtPrivate::List<int>, void>::impl(int, QtPrivate::QSlotObjectBase*, QObject*, void**, bool*) (qhash.h:426)
   by: call (qobjectdefs_impl.h:398)
   by: void doActivate<false>(QObject*, int, void**) (qobject.cpp:3886)
   by: AbstractSystemPoller::timeoutReached(int) (moc_abstractsystempoller.cpp:189)
   by: UnknownInlinedFun (xsyncbasedpoller.cpp:295)
   by: UnknownInlinedFun (xsyncbasedpoller.cpp:279)
   by: UnknownInlinedFun (xsyncbasedpoller.cpp:44)
   by: XSyncBasedPollerHelper::nativeEventFilter(QByteArray const&, void*, long*) (xsyncbasedpoller.cpp:39)
   by: QAbstractEventDispatcher::filterNativeEvent(QByteArray const&, void*, long*) (qabstracteventdispatcher.cpp:495)
   by: QXcbConnection::handleXcbEvent(xcb_generic_event_t*) (qxcbconnection.cpp:536)
   by: QXcbConnection::processXcbEvents(QFlags<QEventLoop::ProcessEventsFlag>) (qxcbconnection.cpp:1014)
   by: xcbSourceDispatch(_GSource*, int (*)(void*), void*) (qxcbeventdispatcher.cpp:103)
   by: g_main_context_dispatch (in /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.7200.1)
   by: ??? (in /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.7200.1)
   by: g_main_context_iteration (in /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.7200.1)
 Address 0xb9de0a0 is 0 bytes inside a block of size 24 free'd
   atF: free (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
   by: UnknownInlinedFun (qhash.h:586)
   by: UnknownInlinedFun (qhash.h:886)
   by: KIdleTime::removeIdleTimeout(int) (kidletime.cpp:144)
   by: IdleTimeDetector::stopIdleDetection() (idletimedetector.cpp:129)
   by: IdleTimeDetector::timeoutReached(int, int) (idletimedetector.cpp:67)
   by: QtPrivate::FunctorCall<QtPrivate::IndexesList<0, 1>, QtPrivate::List<int, int>, void, void (IdleTimeDetector::*)(int, int)>::call(void (IdleTimeDetector::*)(int, int), IdleTimeDetector*, void**) (qobjectdefs_impl.h:152)
   by: void QtPrivate::FunctionPointer<void (IdleTimeDetector::*)(int, int)>::call<QtPrivate::List<int, int>, void>(void (IdleTimeDetector::*)(int, int), IdleTimeDetector*, void**) (qobjectdefs_impl.h:185)
   by: QtPrivate::QSlotObject<void (IdleTimeDetector::*)(int, int), QtPrivate::List<int, int>, void>::impl(int, QtPrivate::QSlotObjectBase*, QObject*, void**, bool*) (qobjectdefs_impl.h:418)
   by: call (qobjectdefs_impl.h:398)
   by: void doActivate<false>(QObject*, int, void**) (qobject.cpp:3886)
   by: KIdleTime::timeoutReached(int, int) (moc_kidletime.cpp:195)
   by: QtPrivate::QFunctorSlotObject<KIdleTime::KIdleTime()::{lambda(int)#2}, 1, QtPrivate::List<int>, void>::impl(int, QtPrivate::QSlotObjectBase*, QObject*, void**, bool*) (kidletime.cpp:296)
   by: call (qobjectdefs_impl.h:398)
   by: void doActivate<false>(QObject*, int, void**) (qobject.cpp:3886)
   by: AbstractSystemPoller::timeoutReached(int) (moc_abstractsystempoller.cpp:189)
 Block was alloc'd at
   at: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
   by: QHashData::allocateNode(int) (qhash.cpp:479)
   by: UnknownInlinedFun (qhash.h:610)
   by: UnknownInlinedFun (qhash.h:761)
   by: KIdleTime::addIdleTimeout(int) (kidletime.cpp:128)
   by: IdleTimeDetector::startIdleDetection() (idletimedetector.cpp:122)
   by: TaskView::startTimerFor(Task*, QDateTime const&) (taskview.cpp:268)
   by: TaskView::startTimerForNow(Task*) (taskview.cpp:284)
   by: TaskView::startCurrentTimer() (taskview.cpp:257)
   by: TaskView::onTaskDoubleClicked(Task*) (taskview.cpp:612)
   by: QtPrivate::FunctorCall<QtPrivate::IndexesList<0>, QtPrivate::List<Task*>, void, void (TaskView::*)(Task*)>::call(void (TaskView::*)(Task*), TaskView*, void**) (qobjectdefs_impl.h:152)
   by: void QtPrivate::FunctionPointer<void (TaskView::*)(Task*)>::call<QtPrivate::List<Task*>, void>(void (TaskView::*)(Task*), TaskView*, void**) (qobjectdefs_impl.h:185)
   by: QtPrivate::QSlotObject<void (TaskView::*)(Task*), QtPrivate::List<Task*>, void>::impl(int, QtPrivate::QSlotObjectBase*, QObject*, void**, bool*) (qobjectdefs_impl.h:418)
   by: call (qobjectdefs_impl.h:398)
   by: void doActivate<false>(QObject*, int, void**) (qobject.cpp:3886)

Invalid read of size 4
   at: QHashData::nextNode(QHashData::Node*) (qhash.cpp:594)
   by: QtPrivate::QFunctorSlotObject<KIdleTime::KIdleTime()::{lambda(int)#2}, 1, QtPrivate::List<int>, void>::impl(int, QtPrivate::QSlotObjectBase*, QObject*, void**, bool*) (qhash.h:426)
   by: call (qobjectdefs_impl.h:398)
   by: void doActivate<false>(QObject*, int, void**) (qobject.cpp:3886)
   by: AbstractSystemPoller::timeoutReached(int) (moc_abstractsystempoller.cpp:189)
   by: UnknownInlinedFun (xsyncbasedpoller.cpp:295)
   by: UnknownInlinedFun (xsyncbasedpoller.cpp:279)
   by: UnknownInlinedFun (xsyncbasedpoller.cpp:44)
   by: XSyncBasedPollerHelper::nativeEventFilter(QByteArray const&, void*, long*) (xsyncbasedpoller.cpp:39)
   by: QAbstractEventDispatcher::filterNativeEvent(QByteArray const&, void*, long*) (qabstracteventdispatcher.cpp:495)
   by: QXcbConnection::handleXcbEvent(xcb_generic_event_t*) (qxcbconnection.cpp:536)
   by: QXcbConnection::processXcbEvents(QFlags<QEventLoop::ProcessEventsFlag>) (qxcbconnection.cpp:1014)
   by: xcbSourceDispatch(_GSource*, int (*)(void*), void*) (qxcbeventdispatcher.cpp:103)
   by: g_main_context_dispatch (in /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.7200.1)
   by: ??? (in /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.7200.1)
   by: g_main_context_iteration (in /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.7200.1)
 Address 0xb9de0a8 is 8 bytes inside a block of size 24 free'd
   at: free (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
   by: UnknownInlinedFun (qhash.h:586)
   by: UnknownInlinedFun (qhash.h:886)
   by: KIdleTime::removeIdleTimeout(int) (kidletime.cpp:144)
   by: IdleTimeDetector::stopIdleDetection() (idletimedetector.cpp:129)
   by: IdleTimeDetector::timeoutReached(int, int) (idletimedetector.cpp:67)
   by: QtPrivate::FunctorCall<QtPrivate::IndexesList<0, 1>, QtPrivate::List<int, int>, void, void (IdleTimeDetector::*)(int, int)>::call(void (IdleTimeDetector::*)(int, int), IdleTimeDetector*, void**) (qobjectdefs_impl.h:152)
   by: void QtPrivate::FunctionPointer<void (IdleTimeDetector::*)(int, int)>::call<QtPrivate::List<int, int>, void>(void (IdleTimeDetector::*)(int, int), IdleTimeDetector*, void**) (qobjectdefs_impl.h:185)
   by: QtPrivate::QSlotObject<void (IdleTimeDetector::*)(int, int), QtPrivate::List<int, int>, void>::impl(int, QtPrivate::QSlotObjectBase*, QObject*, void**, bool*) (qobjectdefs_impl.h:418)
   by: call (qobjectdefs_impl.h:398)
   by: void doActivate<false>(QObject*, int, void**) (qobject.cpp:3886)
   by: KIdleTime::timeoutReached(int, int) (moc_kidletime.cpp:195)
   by: QtPrivate::QFunctorSlotObject<KIdleTime::KIdleTime()::{lambda(int)#2}, 1, QtPrivate::List<int>, void>::impl(int, QtPrivate::QSlotObjectBase*, QObject*, void**, bool*) (kidletime.cpp:296)
   by: call (qobjectdefs_impl.h:398)
   by: void doActivate<false>(QObject*, int, void**) (qobject.cpp:3886)
   by: AbstractSystemPoller::timeoutReached(int) (moc_abstractsystempoller.cpp:189)
 Block was alloc'd at
   at: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
   by: QHashData::allocateNode(int) (qhash.cpp:479)
   by: UnknownInlinedFun (qhash.h:610)
   by: UnknownInlinedFun (qhash.h:761)
   by: KIdleTime::addIdleTimeout(int) (kidletime.cpp:128)
   by: IdleTimeDetector::startIdleDetection() (idletimedetector.cpp:122)
   by: TaskView::startTimerFor(Task*, QDateTime const&) (taskview.cpp:268)
   by: TaskView::startTimerForNow(Task*) (taskview.cpp:284)
   by: TaskView::startCurrentTimer() (taskview.cpp:257)
   by: TaskView::onTaskDoubleClicked(Task*) (taskview.cpp:612)
   by: QtPrivate::FunctorCall<QtPrivate::IndexesList<0>, QtPrivate::List<Task*>, void, void (TaskView::*)(Task*)>::call(void (TaskView::*)(Task*), TaskView*, void**) (qobjectdefs_impl.h:152)
   by: void QtPrivate::FunctionPointer<void (TaskView::*)(Task*)>::call<QtPrivate::List<Task*>, void>(void (TaskView::*)(Task*), TaskView*, void**) (qobjectdefs_impl.h:185)
   by: QtPrivate::QSlotObject<void (TaskView::*)(Task*), QtPrivate::List<Task*>, void>::impl(int, QtPrivate::QSlotObjectBase*, QObject*, void**, bool*) (qobjectdefs_impl.h:418)
   by: call (qobjectdefs_impl.h:398)
   by: void doActivate<false>(QObject*, int, void**) (qobject.cpp:3886)
Comment 3 Christof Kaufmann 2022-11-15 09:48:16 UTC
I made a workaround in my fork of the KTimeTracker code, for anyone, who can compile the code:
https://invent.kde.org/ckaufmann/ktimetracker/-/tree/workaround_idle_crash

However, I do not plan to pose a merge request from it. I still hope for more convenient ways to workaround the issue.
Comment 4 Alexander Potashev 2023-03-12 16:41:20 UTC
Thanks for investigating!

The bugfix commit https://invent.kde.org/frameworks/kidletime/-/commit/cd5040684723b87c7ba5b7cc1b1a63402902a641 was included in 5.93.0. Update KF5 minimum version to 5.93.0.