Bug 389176 - Juk crashed while deleting playlists
Summary: Juk crashed while deleting playlists
Status: RESOLVED FIXED
Alias: None
Product: juk
Classification: Applications
Component: general (other bugs)
Version First Reported In: unspecified
Platform: openSUSE Linux
: NOR crash
Target Milestone: ---
Assignee: Scott Wheeler
URL:
Keywords: drkonqi
Depends on:
Blocks:
 
Reported: 2018-01-18 19:47 UTC by Tony
Modified: 2018-01-19 03:23 UTC (History)
1 user (show)

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


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Tony 2018-01-18 19:47:44 UTC
Application: juk (18.03.70)

Qt Version: 5.10.0
Frameworks Version: 5.43.0
Operating System: Linux 4.14.13-1-default x86_64
Distribution: "openSUSE Tumbleweed"

-- Information about the crash:
- What I was doing when the application crashed:

Deleting around 50 to 60 playlists i had shown on the "Collections" panel of Juk. When asked if i wanted to delete them from  disk or keep them i choosed to delete them from the disk. I had all of them on a NTFS disk drive where i have all my music files.

-- Backtrace:
Application: JuK (juk), signal: Segmentation fault
Using host libthread_db library "/lib64/libthread_db.so.1".
[Current thread is 1 (Thread 0x7f7e4121f8c0 (LWP 18025))]

Thread 7 (Thread 0x7f7deffff700 (LWP 18247)):
#0  0x00007f7e3b2b1a88 in __GI___libc_read (fd=fd@entry=27, buf=buf@entry=0x7f7defffeb2e, nbytes=nbytes@entry=10) at ../sysdeps/unix/sysv/linux/read.c:26
#1  0x00007f7e34e01751 in read (__nbytes=10, __buf=0x7f7defffeb2e, __fd=27) at /usr/include/bits/unistd.h:44
#2  pa_read (fd=27, buf=buf@entry=0x7f7defffeb2e, count=count@entry=10, type=type@entry=0x5600cd26cb68) at pulsecore/core-util.c:434
#3  0x00007f7e37725dde in clear_wakeup (m=<optimized out>) at pulse/mainloop.c:781
#4  pa_mainloop_prepare (m=m@entry=0x5600cd26ca90, timeout=-1) at pulse/mainloop.c:789
#5  0x00007f7e37726850 in pa_mainloop_iterate (m=0x5600cd26ca90, block=<optimized out>, retval=0x0) at pulse/mainloop.c:923
#6  0x00007f7e37726910 in pa_mainloop_run (m=0x5600cd26ca90, retval=retval@entry=0x0) at pulse/mainloop.c:944
#7  0x00007f7e37734779 in thread (userdata=0x5600cd26dc10) at pulse/thread-mainloop.c:100
#8  0x00007f7e34e30438 in internal_thread_func (userdata=0x5600cd2853b0) at pulsecore/thread-posix.c:81
#9  0x00007f7e38f5f558 in start_thread (arg=0x7f7deffff700) at pthread_create.c:465
#10 0x00007f7e3b2c06df in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95

Thread 6 (Thread 0x7f7df73a6700 (LWP 18045)):
#0  0x00007f7e38f6582d in futex_wait_cancelable (private=<optimized out>, expected=0, futex_word=0x5600cc38fdc4) at ../sysdeps/unix/sysv/linux/futex-internal.h:88
#1  __pthread_cond_wait_common (abstime=0x0, mutex=0x5600cc38fd70, cond=0x5600cc38fd98) at pthread_cond_wait.c:502
#2  __pthread_cond_wait (cond=0x5600cc38fd98, mutex=0x5600cc38fd70) at pthread_cond_wait.c:655
#3  0x00007f7e3bf2ec2b in QWaitCondition::wait(QMutex*, unsigned long) () from /usr/lib64/libQt5Core.so.5
#4  0x00007f7e3bf2740b in QSemaphore::acquire(int) () from /usr/lib64/libQt5Core.so.5
#5  0x00007f7e3f821094 in QLibProxyWrapper::run() () from /usr/lib64/libQt5Network.so.5
#6  0x00007f7e3bf2d8d0 in QThreadPrivate::start(void*) () from /usr/lib64/libQt5Core.so.5
#7  0x00007f7e38f5f558 in start_thread (arg=0x7f7df73a6700) at pthread_create.c:465
#8  0x00007f7e3b2c06df in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95

Thread 5 (Thread 0x7f7df7ba7700 (LWP 18044)):
#0  0x00007f7e3575b6f9 in g_mutex_lock (mutex=mutex@entry=0x7f7df0000be0) at gthread-posix.c:1336
#1  0x00007f7e35715144 in g_main_context_release (context=0x7f7df0000be0) at gmain.c:3248
#2  0x00007f7e35716106 in g_main_context_iterate (context=context@entry=0x7f7df0000be0, block=block@entry=1, dispatch=dispatch@entry=1, self=<optimized out>) at gmain.c:3888
#3  0x00007f7e3571625c in g_main_context_iteration (context=0x7f7df0000be0, may_block=1) at gmain.c:3947
#4  0x00007f7e3c15a57b in QEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) () from /usr/lib64/libQt5Core.so.5
#5  0x00007f7e3c1014aa in QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) () from /usr/lib64/libQt5Core.so.5
#6  0x00007f7e3bf288da in QThread::exec() () from /usr/lib64/libQt5Core.so.5
#7  0x00007f7e3bf2d8d0 in QThreadPrivate::start(void*) () from /usr/lib64/libQt5Core.so.5
#8  0x00007f7e38f5f558 in start_thread (arg=0x7f7df7ba7700) at pthread_create.c:465
#9  0x00007f7e3b2c06df in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95

Thread 4 (Thread 0x7f7e0e90f700 (LWP 18031)):
#0  0x00007f7e3b2b1a88 in __GI___libc_read (fd=fd@entry=14, buf=buf@entry=0x7f7e0e90eb2e, nbytes=nbytes@entry=10) at ../sysdeps/unix/sysv/linux/read.c:26
#1  0x00007f7e34e01751 in read (__nbytes=10, __buf=0x7f7e0e90eb2e, __fd=14) at /usr/include/bits/unistd.h:44
#2  pa_read (fd=14, buf=buf@entry=0x7f7e0e90eb2e, count=count@entry=10, type=type@entry=0x5600c8d6cfc8) at pulsecore/core-util.c:434
#3  0x00007f7e37725dde in clear_wakeup (m=<optimized out>) at pulse/mainloop.c:781
#4  pa_mainloop_prepare (m=m@entry=0x5600c8d6cef0, timeout=-1) at pulse/mainloop.c:789
#5  0x00007f7e37726850 in pa_mainloop_iterate (m=0x5600c8d6cef0, block=<optimized out>, retval=0x0) at pulse/mainloop.c:923
#6  0x00007f7e37726910 in pa_mainloop_run (m=0x5600c8d6cef0, retval=retval@entry=0x0) at pulse/mainloop.c:944
#7  0x00007f7e37734779 in thread (userdata=0x5600c8d37920) at pulse/thread-mainloop.c:100
#8  0x00007f7e34e30438 in internal_thread_func (userdata=0x5600c8d488f0) at pulsecore/thread-posix.c:81
#9  0x00007f7e38f5f558 in start_thread (arg=0x7f7e0e90f700) at pthread_create.c:465
#10 0x00007f7e3b2c06df in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95

Thread 3 (Thread 0x7f7e1b49f700 (LWP 18029)):
#0  0x00007f7e35715774 in g_main_context_prepare (context=context@entry=0x7f7e14000be0, priority=priority@entry=0x7f7e1b49ebe0) at gmain.c:3462
#1  0x00007f7e3571607b in g_main_context_iterate (context=context@entry=0x7f7e14000be0, block=block@entry=1, dispatch=dispatch@entry=1, self=<optimized out>) at gmain.c:3866
#2  0x00007f7e3571625c in g_main_context_iteration (context=0x7f7e14000be0, may_block=1) at gmain.c:3947
#3  0x00007f7e3c15a57b in QEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) () from /usr/lib64/libQt5Core.so.5
#4  0x00007f7e3c1014aa in QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) () from /usr/lib64/libQt5Core.so.5
#5  0x00007f7e3bf288da in QThread::exec() () from /usr/lib64/libQt5Core.so.5
#6  0x00007f7e3bf2d8d0 in QThreadPrivate::start(void*) () from /usr/lib64/libQt5Core.so.5
#7  0x00007f7e38f5f558 in start_thread (arg=0x7f7e1b49f700) at pthread_create.c:465
#8  0x00007f7e3b2c06df in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95

Thread 2 (Thread 0x7f7e25857700 (LWP 18028)):
#0  0x00007f7e3b2b1a88 in __GI___libc_read (fd=6, buf=buf@entry=0x7f7e25856ad0, nbytes=nbytes@entry=16) at ../sysdeps/unix/sysv/linux/read.c:26
#1  0x00007f7e3575a3c0 in read (__nbytes=16, __buf=0x7f7e25856ad0, __fd=<optimized out>) at /usr/include/bits/unistd.h:44
#2  g_wakeup_acknowledge (wakeup=0x7f7e28001bc0) at gwakeup.c:210
#3  0x00007f7e35715c2b in g_main_context_check (context=context@entry=0x7f7e20000be0, max_priority=2147483647, fds=fds@entry=0x7f7e2000f110, n_fds=n_fds@entry=1) at gmain.c:3664
#4  0x00007f7e357160f0 in g_main_context_iterate (context=context@entry=0x7f7e20000be0, block=block@entry=1, dispatch=dispatch@entry=1, self=<optimized out>) at gmain.c:3883
#5  0x00007f7e3571625c in g_main_context_iteration (context=0x7f7e20000be0, may_block=1) at gmain.c:3947
#6  0x00007f7e3c15a57b in QEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) () from /usr/lib64/libQt5Core.so.5
#7  0x00007f7e3c1014aa in QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) () from /usr/lib64/libQt5Core.so.5
#8  0x00007f7e3bf288da in QThread::exec() () from /usr/lib64/libQt5Core.so.5
#9  0x00007f7e3c57fbd5 in QDBusConnectionManager::run() () from /usr/lib64/libQt5DBus.so.5
#10 0x00007f7e3bf2d8d0 in QThreadPrivate::start(void*) () from /usr/lib64/libQt5Core.so.5
#11 0x00007f7e38f5f558 in start_thread (arg=0x7f7e25857700) at pthread_create.c:465
#12 0x00007f7e3b2c06df in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95

Thread 1 (Thread 0x7f7e4121f8c0 (LWP 18025)):
[KCrash Handler]
#6  std::__atomic_base<int>::operator++ (this=0x680000000e) at /usr/include/c++/7/bits/atomic_base.h:296
#7  QAtomicOps<int>::ref<int> (_q_value=...) at /usr/include/qt5/QtCore/qatomic_cxx11.h:265
#8  QBasicAtomicInteger<int>::ref (this=0x680000000e) at /usr/include/qt5/QtCore/qbasicatomic.h:113
#9  QExplicitlySharedDataPointer<FileHandle::FileHandlePrivate>::QExplicitlySharedDataPointer (o=..., this=0x7ffda0efa068) at /usr/include/qt5/QtCore/qshareddata.h:168
#10 FileHandle::FileHandle (this=0x7ffda0efa068, f=...) at /usr/src/debug/juk-18.03.80git.20180111T045025~bbc8d9d/filehandle.cpp:78
#11 0x00005600c8037991 in PlaylistItem::file (this=this@entry=0x5600cc114a40) at /usr/src/debug/juk-18.03.80git.20180111T045025~bbc8d9d/playlistitem.cpp:89
#12 0x00005600c8027af8 in Playlist::createItem<PlaylistItem, PlaylistItem> (this=this@entry=0x5600cc496f90, sibling=0x5600cc114a40, after=0x5600cc729190) at /usr/src/debug/juk-18.03.80git.20180111T045025~bbc8d9d/playlist.h:755
#13 0x00005600c8027d5b in Playlist::createItems<PlaylistItem, PlaylistItem> (this=0x5600cc496f90, siblings=..., after=<optimized out>) at /usr/src/debug/juk-18.03.80git.20180111T045025~bbc8d9d/playlist.h:772
#14 0x00005600c7fe5e52 in DynamicPlaylist::slotUpdateItems (this=0x5600cc496f90) at /usr/src/debug/juk-18.03.80git.20180111T045025~bbc8d9d/dynamicplaylist.cpp:189
#15 0x00007f7e3c1317a2 in QObject::event(QEvent*) () from /usr/lib64/libQt5Core.so.5
#16 0x00007f7e3d14c813 in QWidget::event(QEvent*) () from /usr/lib64/libQt5Widgets.so.5
#17 0x00007f7e3d1e9f5e in QFrame::event(QEvent*) () from /usr/lib64/libQt5Widgets.so.5
#18 0x00007f7e3d1f2923 in QAbstractScrollArea::event(QEvent*) () from /usr/lib64/libQt5Widgets.so.5
#19 0x00007f7e3d34b7b1 in QAbstractItemView::event(QEvent*) () from /usr/lib64/libQt5Widgets.so.5
#20 0x00007f7e3d10fe6c in QApplicationPrivate::notify_helper(QObject*, QEvent*) () from /usr/lib64/libQt5Widgets.so.5
#21 0x00007f7e3d117164 in QApplication::notify(QObject*, QEvent*) () from /usr/lib64/libQt5Widgets.so.5
#22 0x00007f7e3c102c98 in QCoreApplication::notifyInternal2(QObject*, QEvent*) () from /usr/lib64/libQt5Core.so.5
#23 0x00007f7e3c105675 in QCoreApplicationPrivate::sendPostedEvents(QObject*, int, QThreadData*) () from /usr/lib64/libQt5Core.so.5
#24 0x00007f7e3c15aee3 in postEventSourceDispatch(_GSource*, int (*)(void*), void*) () from /usr/lib64/libQt5Core.so.5
#25 0x00007f7e35715f97 in g_main_dispatch (context=0x7f7e28004fc0) at gmain.c:3148
#26 g_main_context_dispatch (context=context@entry=0x7f7e28004fc0) at gmain.c:3813
#27 0x00007f7e357161d0 in g_main_context_iterate (context=context@entry=0x7f7e28004fc0, block=block@entry=1, dispatch=dispatch@entry=1, self=<optimized out>) at gmain.c:3886
#28 0x00007f7e3571625c in g_main_context_iteration (context=0x7f7e28004fc0, may_block=1) at gmain.c:3947
#29 0x00007f7e3c15a55f in QEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) () from /usr/lib64/libQt5Core.so.5
#30 0x00007f7e2fec6f61 in QPAEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) () from /usr/lib64/libQt5XcbQpa.so.5
#31 0x00007f7e3c1014aa in QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) () from /usr/lib64/libQt5Core.so.5
#32 0x00007f7e3c109fe4 in QCoreApplication::exec() () from /usr/lib64/libQt5Core.so.5
#33 0x00005600c7fc216f in main (argc=<optimized out>, argv=<optimized out>) at /usr/src/debug/juk-18.03.80git.20180111T045025~bbc8d9d/main.cpp:122

Reported using DrKonqi
Comment 1 Michael Pyne 2018-01-19 01:02:35 UTC
Thanks for the report and the detailed backtrace.

I think this is due to some kind of race condition.  It's been awhile since I have been through this code but it seems to me that when we're updating the playlists after removing some of the music tracks, the list of "siblings" in a dynamic playlist (which happens when multiple playlists are selected in JuK) can be cached (at dynamicplaylist.cpp:155) and then only when the event loop begins again will those cached siblings be used.

But the events being handled in between in the event loop may delete items in that cached list, leading to a crash later when it comes time to actually delete them.
Comment 2 Michael Pyne 2018-01-19 03:23:30 UTC
Git commit e8c2dbbfce00765335d079bca86abc7e2147f3e6 by Michael Pyne.
Committed on 19/01/2018 at 03:18.
Pushed by mpyne into branch 'Applications/17.12'.

Immediately update dynamic/search playlist items upon a change.

This is as opposed to recording the new list of PlaylistItems and then
effecting the change after draining the event loop (an attempt at
keeping GUI responsive if many updates are happening).

Otherwise it is possible to
- Generate a list of PlaylistItems to read from (when updating the
playlist) and push to end of event loop
- Delete some of those PlaylistItems due to already-queued events to
delete playlist items
- Finally try to use the list of PlaylistItems and run into a segfault
from trying to access a deleted PlaylistItem.

I think this should fix a crash when you delete multiple playlists.
FIXED-IN:17.12.2

M  +3    -5    dynamicplaylist.cpp

https://commits.kde.org/juk/e8c2dbbfce00765335d079bca86abc7e2147f3e6