Review Request 125613: Race condition and error notification loss in ListJob

Thomas Lübking thomas.luebking at gmail.com
Wed Oct 28 17:12:53 GMT 2015



> On Okt. 26, 2015, 5:27 nachm., Aleix Pol Gonzalez wrote:
> > This patch introduced a crash here. Could you maybe look into it? Here's a backtrace.
> > 
> > It happens on some (not all) programs when the open dialog is displayed. I can reproduce it with ksnapshot and kdevelop, but not with Kate.
> > 
> > ```
> > (gdb) where
> > #0  0x00007ffff22925f8 in raise () from /usr/lib/libc.so.6
> > #1  0x00007ffff2293a7a in abort () from /usr/lib/libc.so.6
> > #2  0x00007ffff2f3205e in qt_message_fatal (context=..., message=<synthetic pointer>) at /home/kde-devel/frameworks/qt5/qtbase/src/corelib/global/qlogging.cpp:1610
> > #3  QMessageLogger::fatal (this=this at entry=0x7fffffffc070, msg=msg at entry=0x7ffff31e57f0 "ASSERT: \"%s\" in file %s, line %d") at /home/kde-devel/frameworks/qt5/qtbase/src/corelib/global/qlogging.cpp:784
> > #4  0x00007ffff2f2d5de in qt_assert (assertion=<optimized out>, file=<optimized out>, line=<optimized out>) at /home/kde-devel/frameworks/qt5/qtbase/src/corelib/global/qglobal.cpp:3046
> > #5  0x00007ffff63fb097 in KCoreDirListerCache::slotResult (this=0x7ffff669b840 <(anonymous namespace)::Q_QGS_kDirListerCache::innerFunction()::holder>, j=0xe972b0) at /home/kde-devel/frameworks/kio/src/core/kcoredirlister.cpp:1310
> > #6  0x00007ffff6404e41 in KCoreDirListerCache::qt_static_metacall (_o=0x7ffff669b840 <(anonymous namespace)::Q_QGS_kDirListerCache::innerFunction()::holder>, _c=QMetaObject::InvokeMetaMethod, _id=8, _a=0x7fffffffc390) at src/core/moc_kcoredirlister_p.cpp:133
> > #7  0x00007ffff314ae6a in QMetaObject::activate (sender=0xe972b0, signalOffset=<optimized out>, local_signal_index=<optimized out>, argv=<optimized out>) at /home/kde-devel/frameworks/qt5/qtbase/src/corelib/kernel/qobject.cpp:3730
> > #8  0x00007ffff4742f9b in KJob::result (this=0xe972b0, _t1=0xe972b0) at src/lib/moc_kjob.cpp:555
> > #9  0x00007ffff47419f1 in KJob::emitResult (this=0xe972b0) at /home/kde-devel/frameworks/kcoreaddons/src/lib/jobs/kjob.cpp:294
> > #10 0x00007ffff47412e4 in KJob::kill (this=0xe972b0, verbosity=KJob::EmitResult) at /home/kde-devel/frameworks/kcoreaddons/src/lib/jobs/kjob.cpp:103
> > #11 0x00007ffff63f6473 in KCoreDirListerCache::stopListJob (this=0x7ffff669b840 <(anonymous namespace)::Q_QGS_kDirListerCache::innerFunction()::holder>, url="file:///home/apol/Documents", silent=true) at /home/kde-devel/frameworks/kio/src/core/kcoredirlister.cpp:493
> > Python Exception <class 'gdb.error'> cannot resolve overloaded method `data': no arguments supplied: 
> > #12 0x00007ffff63f6364 in KCoreDirListerCache::stopListingUrl (this=0x7ffff669b840 <(anonymous namespace)::Q_QGS_kDirListerCache::innerFunction()::holder>, lister=0x9ef910, _u=, silent=true) at /home/kde-devel/frameworks/kio/src/core/kcoredirlister.cpp:463
> > #13 0x00007ffff63f613a in KCoreDirListerCache::stop (this=0x7ffff669b840 <(anonymous namespace)::Q_QGS_kDirListerCache::innerFunction()::holder>, lister=0x9ef910, silent=true) at /home/kde-devel/frameworks/kio/src/core/kcoredirlister.cpp:421
> > Python Exception <class 'gdb.error'> cannot resolve overloaded method `data': no arguments supplied: 
> > #14 0x00007ffff63f4ea1 in KCoreDirListerCache::listDir (this=0x7ffff669b840 <(anonymous namespace)::Q_QGS_kDirListerCache::innerFunction()::holder>, lister=0x9ef910, _u=, _keep=false, _reload=false) at /home/kde-devel/frameworks/kio/src/core/kcoredirlister.cpp:143
> > Python Exception <class 'gdb.error'> cannot resolve overloaded method `data': no arguments supplied: 
> > #15 0x00007ffff6400fa0 in KCoreDirLister::openUrl (this=0x9ef910, _url=, _flags=...) at /home/kde-devel/frameworks/kio/src/core/kcoredirlister.cpp:2151
> > Python Exception <class 'gdb.error'> cannot resolve overloaded method `data': no arguments supplied: 
> > #16 0x00007fffe61e1342 in KDirOperator::Private::openUrl (this=0x9f2ff0, url=, flags=...) at /home/kde-devel/frameworks/kio/src/filewidgets/kdiroperator.cpp:1069
> > Python Exception <class 'gdb.error'> cannot resolve overloaded method `data': no arguments supplied: 
> > #17 0x00007fffe61e1218 in KDirOperator::setUrl (this=0x9ee560, _newurl=, clearforward=true) at /home/kde-devel/frameworks/kio/src/filewidgets/kdiroperator.cpp:1051
> > Python Exception <class 'gdb.error'> cannot resolve overloaded method `data': no arguments supplied: 
> > #18 0x00007fffe6204b8c in KFileWidget::setUrl (this=0x89a500, url=, clearforward=true) at /home/kde-devel/frameworks/kio/src/filewidgets/kfilewidget.cpp:1460
> > Python Exception <class 'gdb.error'> cannot resolve overloaded method `data': no arguments supplied: 
> > #19 0x00007fffe64a82c8 in KDEPlatformFileDialog::setDirectory (this=0x869a90, directory=) at /home/kde-devel/frameworks/frameworkintegration/src/platformtheme/kdeplatformfiledialoghelper.cpp:189
> > Python Exception <class 'gdb.error'> cannot resolve overloaded method `data': no arguments supplied: 
> > #20 0x00007fffe64a933e in KDEPlatformFileDialogHelper::setDirectory (this=0x877040, directory=) at /home/kde-devel/frameworks/frameworkintegration/src/platformtheme/kdeplatformfiledialoghelper.cpp:352
> > Python Exception <class 'gdb.error'> cannot resolve overloaded method `data': no arguments supplied: 
> > #21 0x00007ffff3c8978b in QFileDialogPrivate::setDirectory_sys (directory=, this=<optimized out>) at /home/kde-devel/frameworks/qt5/qtbase/src/widgets/dialogs/qfiledialog_p.h:368
> > Python Exception <class 'gdb.error'> cannot resolve overloaded method `data': no arguments supplied: 
> > #22 QFileDialog::setDirectoryUrl (this=this at entry=0x7fffffffccb0, directory=) at /home/kde-devel/frameworks/qt5/qtbase/src/widgets/dialogs/qfiledialog.cpp:976
> > Python Exception <class 'gdb.error'> cannot resolve overloaded method `data': no arguments supplied: 
> > #23 0x00007ffff3c96988 in QFileDialogPrivate::init (this=0x87caf0, directory=, 
> >     nameFilter=";;Windows BMP image (*.bmp *.dib);;JPEG-2000 image (*.jp2 *.jpx *.jpf);;JPEG Image (*.jpeg *.jpg *.jpe *.jfif);;PNG image (*.png);;TIFF image (*.tif *.tiff);;Windows icon (*.ico);;WBMP image (*.wbmp);;"..., caption="Save Snapshot As")
> >     at /home/kde-devel/frameworks/qt5/qtbase/src/widgets/dialogs/qfiledialog.cpp:2804
> > #24 0x00007ffff3c96e66 in QFileDialog::QFileDialog (this=0x7fffffffccb0, args=...) at /home/kde-devel/frameworks/qt5/qtbase/src/widgets/dialogs/qfiledialog.cpp:373
> > Python Exception <class 'gdb.error'> cannot resolve overloaded method `data': no arguments supplied: 
> > #25 0x00007ffff3c9789b in QFileDialog::getSaveFileUrl (parent=0x7fffffffdce0, caption="Save Snapshot As", dir=, 
> >     filter=";;Windows BMP image (*.bmp *.dib);;JPEG-2000 image (*.jp2 *.jpx *.jpf);;JPEG Image (*.jpeg *.jpg *.jpe *.jfif);;PNG image (*.png);;TIFF image (*.tif *.tiff);;Windows icon (*.ico);;WBMP image (*.wbmp);;"..., selectedFilter=0x7fffffffcd90, options=..., 
> >     supportedSchemes=empty QStringList<QString>) at /home/kde-devel/frameworks/qt5/qtbase/src/widgets/dialogs/qfiledialog.cpp:2387
> > #26 0x000000000043995d in KSnapshot::slotSaveAs (this=0x7fffffffdce0) at /home/kde-devel/frameworks/ksnapshot/ksnapshot.cpp:347
> > #27 0x0000000000443ca3 in QtPrivate::FunctorCall<QtPrivate::IndexesList<>, QtPrivate::List<>, void, void (KSnapshot::*)()>::call(void (KSnapshot::*)(), KSnapshot*, void**) (f=(void (KSnapshot::*)(KSnapshot * const)) 0x4396ac <KSnapshot::slotSaveAs()>, o=0x7fffffffdce0, 
> >     arg=0x7fffffffd050) at /home/kde-devel/kde5/include/QtCore/qobjectdefs_impl.h:501
> > #28 0x0000000000443623 in QtPrivate::FunctionPointer<void (KSnapshot::*)()>::call<QtPrivate::List<>, void>(void (KSnapshot::*)(), KSnapshot*, void**) (f=(void (KSnapshot::*)(KSnapshot * const)) 0x4396ac <KSnapshot::slotSaveAs()>, o=0x7fffffffdce0, arg=0x7fffffffd050)
> >     at /home/kde-devel/kde5/include/QtCore/qobjectdefs_impl.h:520
> > #29 0x0000000000442b03 in QtPrivate::QSlotObject<void (KSnapshot::*)(), QtPrivate::List<>, void>::impl(int, QtPrivate::QSlotObjectBase*, QObject*, void**, bool*) (which=1, this_=0x8c4c10, r=0x7fffffffdce0, a=0x7fffffffd050, ret=0x0)
> >     at /home/kde-devel/kde5/include/QtCore/qobject_impl.h:143
> > #30 0x00007ffff314acf7 in QtPrivate::QSlotObjectBase::call (a=0x7fffffffd050, r=0x7fffffffdce0, this=<optimized out>) at ../../include/QtCore/../../../../frameworks/qt5/qtbase/src/corelib/kernel/qobject_impl.h:124
> > #31 QMetaObject::activate (sender=sender at entry=0x8c1fc0, signalOffset=<optimized out>, local_signal_index=local_signal_index at entry=2, argv=argv at entry=0x7fffffffd050) at /home/kde-devel/frameworks/qt5/qtbase/src/corelib/kernel/qobject.cpp:3715
> > #32 0x00007ffff314b667 in QMetaObject::activate (sender=sender at entry=0x8c1fc0, m=m at entry=0x7ffff3f99000 <QAbstractButton::staticMetaObject>, local_signal_index=local_signal_index at entry=2, argv=argv at entry=0x7fffffffd050)
> >     at /home/kde-devel/frameworks/qt5/qtbase/src/corelib/kernel/qobject.cpp:3595
> > #33 0x00007ffff3e0f372 in QAbstractButton::clicked (this=this at entry=0x8c1fc0, _t1=false) at .moc/moc_qabstractbutton.cpp:303
> > #34 0x00007ffff3b8e654 in QAbstractButtonPrivate::emitClicked (this=0x8c27e0) at /home/kde-devel/frameworks/qt5/qtbase/src/widgets/widgets/qabstractbutton.cpp:533
> > #35 0x00007ffff3b8fb29 in QAbstractButtonPrivate::click (this=0x8c27e0) at /home/kde-devel/frameworks/qt5/qtbase/src/widgets/widgets/qabstractbutton.cpp:526
> > #36 0x00007ffff3b8fc7c in QAbstractButton::mouseReleaseEvent (this=0x8c1fc0, e=0x7fffffffd4e0) at /home/kde-devel/frameworks/qt5/qtbase/src/widgets/widgets/qabstractbutton.cpp:1131
> > #37 0x00007ffff3af3588 in QWidget::event (this=0x8c1fc0, event=0x7fffffffd4e0) at /home/kde-devel/frameworks/qt5/qtbase/src/widgets/kernel/qwidget.cpp:9064
> > #38 0x00007ffff3ab2dcc in QApplicationPrivate::notify_helper (this=<optimized out>, receiver=0x8c1fc0, e=0x7fffffffd4e0) at /home/kde-devel/frameworks/qt5/qtbase/src/widgets/kernel/qapplication.cpp:3717
> > #39 0x00007ffff3ab88ce in QApplication::notify (this=<optimized out>, receiver=0x8c1fc0, e=0x7fffffffd4e0) at /home/kde-devel/frameworks/qt5/qtbase/src/widgets/kernel/qapplication.cpp:3275
> > #40 0x00007ffff311d2d8 in QCoreApplication::notifyInternal2 (receiver=receiver at entry=0x8c1fc0, event=event at entry=0x7fffffffd4e0) at /home/kde-devel/frameworks/qt5/qtbase/src/corelib/kernel/qcoreapplication.cpp:1002
> > #41 0x00007ffff3ab745e in QCoreApplication::sendSpontaneousEvent (event=0x7fffffffd4e0, receiver=0x8c1fc0) at ../../include/QtCore/../../../../frameworks/qt5/qtbase/src/corelib/kernel/qcoreapplication.h:230
> > #42 QApplicationPrivate::sendMouseEvent (receiver=receiver at entry=0x8c1fc0, event=event at entry=0x7fffffffd4e0, alienWidget=alienWidget at entry=0x8c1fc0, nativeWidget=0x7fffffffdce0, buttonDown=buttonDown at entry=0x7ffff3fa4ba0 <qt_button_down>, lastMouseReceiver=..., 
> >     spontaneous=true) at /home/kde-devel/frameworks/qt5/qtbase/src/widgets/kernel/qapplication.cpp:2770
> > #43 0x00007ffff3b0daa1 in QWidgetWindow::handleMouseEvent (this=this at entry=0x7be360, event=event at entry=0x7fffffffd8f0) at /home/kde-devel/frameworks/qt5/qtbase/src/widgets/kernel/qwidgetwindow.cpp:554
> > #44 0x00007ffff3b0fe7b in QWidgetWindow::event (this=0x7be360, event=0x7fffffffd8f0) at /home/kde-devel/frameworks/qt5/qtbase/src/widgets/kernel/qwidgetwindow.cpp:210
> > #45 0x00007ffff3ab2dcc in QApplicationPrivate::notify_helper (this=<optimized out>, receiver=0x7be360, e=0x7fffffffd8f0) at /home/kde-devel/frameworks/qt5/qtbase/src/widgets/kernel/qapplication.cpp:3717
> > #46 0x00007ffff3ab7d96 in QApplication::notify (this=0x7fffffffde80, receiver=0x7be360, e=0x7fffffffd8f0) at /home/kde-devel/frameworks/qt5/qtbase/src/widgets/kernel/qapplication.cpp:3498
> > ```
> 
> Alberto Jiménez Ruiz wrote:
>     Can't reproduce on Kubuntu 15.10.
> 
> Thomas Lübking wrote:
>     Smells like a corrupted stack or threading issue.
>     
>         if (dirData.listersCurrentlyListing.isEmpty()) {
>             qWarning() << "OOOOPS, nothing in directoryData.listersCurrentlyListing for" << jobUrlStr;
>             // We're about to assert; dump the current state...
>     #ifndef NDEBUG
>             printDebug();
>     #endif
>             Q_ASSERT(!dirData.listersCurrentlyListing.isEmpty());
>         }
>         
>     unless printDebug() is capable of polluting dirData.listersCurrentlyListing (it actually looks like that, but you must undefine NDEBUG), either the stack is junk or dirData.listersCurrentlyListing got some elements while we were printing the debug info from some other thread.
>     
>     I'm no way sure what that code is supposed to do but testing
>     if (b)
>        Q_ASSERT(!b);
>     looks insane.
>     
>     In doubt there should be some mutex somewhere or the entire thing doesn't make much sense.
>     
>     It would seem the stricter test to emitResult() causes a later emit and ultimately triggers this.
>     kate will be KF5 - and you need to build debug enabled to be Q_ASSERT != NOOP (so just watch out whether you get the warning)
>     
>     Aleix, if you can reproduce this at will, I suggest to check whether indeed at some point ::printDebug() manipulates dirData.listersCurrentlyListing - eg. add a global reference and test it in each loop in ::printDebug()
> 
> David Faure wrote:
>     if (b) {
>            // some debug output
>            Q_ASSERT(!b);
>         }
>     is definitely not insane, it's the way to print out more information about the problem before aborting.
>     Much more useful than just Q_ASSERT(!b).
>     I wager that this is neither a corrupted stack nor a threading issue, but a plain old bug.

Ah, it's actually meant to be
   "if (b) qDebug() << "bad"; Q_ASSERT(false); // bye"
I thought the value was actually meant to be tested. Sorry for the noise then.


- Thomas


-----------------------------------------------------------
This is an automatically generated e-mail. To reply, visit:
https://git.reviewboard.kde.org/r/125613/#review87445
-----------------------------------------------------------


On Okt. 24, 2015, 5:54 nachm., Alberto Jiménez Ruiz wrote:
> 
> -----------------------------------------------------------
> This is an automatically generated e-mail. To reply, visit:
> https://git.reviewboard.kde.org/r/125613/
> -----------------------------------------------------------
> 
> (Updated Okt. 24, 2015, 5:54 nachm.)
> 
> 
> Review request for kdelibs, Albert Astals Cid and David Faure.
> 
> 
> Bugs: 333436
>     http://bugs.kde.org/show_bug.cgi?id=333436
> 
> 
> Repository: kdelibs
> 
> 
> Description
> -------
> 
> Race condition and error notification loss in ListJob
> 
> 
> Diffs
> -----
> 
>   kio/kio/job.cpp 91712e3 
>   kio/kio/jobclasses.h d771cfe 
>   kio/tests/jobtest.h d3c552e 
>   kio/tests/jobtest.cpp ee2677a 
> 
> Diff: https://git.reviewboard.kde.org/r/125613/diff/
> 
> 
> Testing
> -------
> 
> Update 1, added unittest
> Changed condition of listjob slotresult finishing (When executed as a synchronous job, gets stuck in a eventloop)
> Added setError to copyjob.
> 
> 
> Tests done on Kubuntu 15.10:
> 
> With this folder structure in ~:
> src
> ######c (Folder)
> ##############b (Folder chmod'ed to 700 and owned by root)
> #######################d (10MB file made of /dev/urandom data)
> ##############a (10MB file made of /dev/urandom data)
> 
> Then, (as a normal user execute: "kioclient ~/src ~/dst")
> 
> Expected result: Notification that some files were not able to be copied (Cannot access "b" folder)
> Result with latest kdelibs: Silent copying where b folder is owned by user but nothing inside.
> ---When all kdebugdialog flags are set, a backtrace is also seen.
>       
> subError notifications for listjob subjobs are lost, Copyjob uses this signal to skip data.
> 
> Also, this fix prevents a race condition. 
> 
> ListJob has another ListJob as a subjob.
> 
> Chaild fails for whatever reason and calls error, which calls slotError, which calls slotsFinished and emitResult.
> The result of the child gets collected by parent. slotResult of parent gets called, removes subjob and emitsresult because there are no subjobs left.
> ---That's fine as long as the slave associated with the parent emits finished before the child fails. If it doesn't, parent calls emitsResult twice.
> 
> 
> Result after patch: kioclient shows a MessageBox telling the copy operation could not be completed.
> 
> 
> Thanks,
> 
> Alberto Jiménez Ruiz
> 
>

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.kde.org/pipermail/kde-core-devel/attachments/20151028/38f85727/attachment.htm>


More information about the kde-core-devel mailing list