D19170: Fix crash while moving files
David Hallas
noreply at phabricator.kde.org
Wed Feb 20 14:52:12 GMT 2019
hallas added a comment.
In D19170#416067 <https://phabricator.kde.org/D19170#416067>, @hallas wrote:
> In D19170#415760 <https://phabricator.kde.org/D19170#415760>, @dfaure wrote:
>
> > If some code is deleting this job from a slot connected to it, that code needs to be fixed. This hack isn't a fix, it will only create more problems..
> >
> > E.g. if some other bad code runs the event loop in the slot connected to finished, it will now delete the job, and we'll get the exact same crash but on `if (emitResult)` this time.
> >
> > This is a big no from me. The emitter of a signal MUST NOT be deleted in slots connected to it.
> >
> > The bug needs proper analysis.
>
>
> Hi David,
>
> thanks for the reply :) I completely agree with you that this is a hack and shouldn't go in, it was merely meant as an aid in doing proper analysis of the bug. I hope one of the people who can actually reproduce the problem can try with this patch enabled and see if it goes away. If it does then I think we can be pretty certain that someone is deleting jobs that they shouldn't. Otherwise I don't have much to go on. I have tried to reproduce the problem in various ways, copying to/from an NTFS drive and also copying to/from SMB but I can't get it to crash. I have been looking some more into the code and I still cannot figure out how the KJob instance can get invalidated. Have you looked at the backtraces? Do you have any ideas or pointers to where to look?
>
> Appreciate the feedback
Ok, I think I just found a way to reproduce the problem:
- Move a directory with a bunch of files to a NTFS USB Drive
- While it is moving the files, move them back
- Sometimes I have to have more then one move back and forth running for it to crash
I have now built KIO with address sanitizer and I get the following info:
==7539==ERROR: AddressSanitizer: heap-use-after-free on address 0x6120002e3de0 at pc 0x7f2cdbbed173 bp 0x7ffec26c5050 sp 0x7ffec26c5040
READ of size 8 at 0x6120002e3de0 thread T0
#0 0x7f2cdbbed172 in KIO::CopyJobPrivate::slotResultErrorCopyingFiles(KJob*) ../src/core/copyjob.cpp:1464
#1 0x7f2cdbbeb26f in KIO::CopyJobPrivate::slotResultCopyingFiles(KJob*) ../src/core/copyjob.cpp:1333
#2 0x7f2cdbbfba35 in KIO::CopyJob::slotResult(KJob*) ../src/core/copyjob.cpp:2160
#3 0x7f2cd612a986 in QMetaObject::activate(QObject*, int, int, void**) (/usr/lib64/libQt5Core.so.5+0x264986)
#4 0x7f2cd7e6e18b in KJob::result(KJob*, KJob::QPrivateSignal) (/usr/lib64/libKF5CoreAddons.so.5+0x3d18b)
#5 0x7f2cd7e6ecc0 in KJob::finishJob(bool) (/usr/lib64/libKF5CoreAddons.so.5+0x3dcc0)
#6 0x7f2cdbc95d8b in KIO::FileCopyJob::slotResult(KJob*) ../src/core/filecopyjob.cpp:497
#7 0x7f2cd612a986 in QMetaObject::activate(QObject*, int, int, void**) (/usr/lib64/libQt5Core.so.5+0x264986)
#8 0x7f2cd7e6e18b in KJob::result(KJob*, KJob::QPrivateSignal) (/usr/lib64/libKF5CoreAddons.so.5+0x3d18b)
#9 0x7f2cd7e6ecc0 in KJob::finishJob(bool) (/usr/lib64/libKF5CoreAddons.so.5+0x3dcc0)
#10 0x7f2cdbcb2267 in KIO::SimpleJob::slotFinished() ../src/core/simplejob.cpp:232
#11 0x7f2cdbcb265d in KIO::SimpleJob::slotError(int, QString const&) ../src/core/simplejob.cpp:245
#12 0x7f2cdbcb8e49 in QtPrivate::FunctorCall<QtPrivate::IndexesList<0, 1>, QtPrivate::List<int, QString const&>, void, void (KIO::SimpleJob::*)(int, QString const&)>::call(void (KIO::SimpleJob::*)(int, QString const&), KIO::SimpleJob*, void**) /usr/include/qt5/QtCore/qobjectdefs_impl.h:134
#13 0x7f2cdbcb88ea in void QtPrivate::FunctionPointer<void (KIO::SimpleJob::*)(int, QString const&)>::call<QtPrivate::List<int, QString const&>, void>(void (KIO::SimpleJob::*)(int, QString const&), KIO::SimpleJob*, void**) /usr/include/qt5/QtCore/qobjectdefs_impl.h:167
#14 0x7f2cdbcb83a7 in QtPrivate::QSlotObject<void (KIO::SimpleJob::*)(int, QString const&), QtPrivate::List<int, QString const&>, void>::impl(int, QtPrivate::QSlotObjectBase*, QObject*, void**, bool*) /usr/include/qt5/QtCore/qobjectdefs_impl.h:396
#15 0x7f2cd612a986 in QMetaObject::activate(QObject*, int, int, void**) (/usr/lib64/libQt5Core.so.5+0x264986)
#16 0x7f2cdbc63a91 in KIO::SlaveInterface::error(int, QString const&) src/core/KF5KIOCore_autogen/include/moc_slaveinterface.cpp:425
#17 0x7f2cdbc5da14 in KIO::SlaveInterface::dispatch(int, QByteArray const&) ../src/core/slaveinterface.cpp:192
#18 0x7f2cdbc5cac7 in KIO::SlaveInterface::dispatch() ../src/core/slaveinterface.cpp:89
#19 0x7f2cdbc69a74 in KIO::Slave::gotInput() ../src/core/slave.cpp:406
#20 0x7f2cdbc71d88 in QtPrivate::FunctorCall<QtPrivate::IndexesList<>, QtPrivate::List<>, void, void (KIO::Slave::*)()>::call(void (KIO::Slave::*)(), KIO::Slave*, void**) /usr/include/qt5/QtCore/qobjectdefs_impl.h:134
#21 0x7f2cdbc719cb in void QtPrivate::FunctionPointer<void (KIO::Slave::*)()>::call<QtPrivate::List<>, void>(void (KIO::Slave::*)(), KIO::Slave*, void**) /usr/include/qt5/QtCore/qobjectdefs_impl.h:167
#22 0x7f2cdbc7118b in QtPrivate::QSlotObject<void (KIO::Slave::*)(), QtPrivate::List<>, void>::impl(int, QtPrivate::QSlotObjectBase*, QObject*, void**, bool*) /usr/include/qt5/QtCore/qobjectdefs_impl.h:396
#23 0x7f2cd612a986 in QMetaObject::activate(QObject*, int, int, void**) (/usr/lib64/libQt5Core.so.5+0x264986)
#24 0x7f2cdbb5fdaa in KIO::Connection::readyRead() src/core/KF5KIOCore_autogen/include/moc_connection_p.cpp:143
#25 0x7f2cdbb5c1a0 in KIO::ConnectionPrivate::dequeue() ../src/core/connection.cpp:46
#26 0x7f2cdbb5f9ae in KIO::Connection::qt_static_metacall(QObject*, QMetaObject::Call, int, void**) src/core/KF5KIOCore_autogen/include/moc_connection_p.cpp:87
#27 0x7f2cd612b5a9 in QObject::event(QEvent*) (/usr/lib64/libQt5Core.so.5+0x2655a9)
#28 0x7f2cd727ad8b in QApplicationPrivate::notify_helper(QObject*, QEvent*) (/usr/lib64/libQt5Widgets.so.5+0x15ad8b)
#29 0x7f2cd728234e in QApplication::notify(QObject*, QEvent*) (/usr/lib64/libQt5Widgets.so.5+0x16234e)
#30 0x7f2cd6101366 in QCoreApplication::notifyInternal2(QObject*, QEvent*) (/usr/lib64/libQt5Core.so.5+0x23b366)
#31 0x7f2cd61041c0 in QCoreApplicationPrivate::sendPostedEvents(QObject*, int, QThreadData*) (/usr/lib64/libQt5Core.so.5+0x23e1c0)
#32 0x7f2cd6154362 (/usr/lib64/libQt5Core.so.5+0x28e362)
#33 0x7f2ccfecfe26 in g_main_context_dispatch (/usr/lib64/libglib-2.0.so.0+0x4be26)
#34 0x7f2ccfed005f (/usr/lib64/libglib-2.0.so.0+0x4c05f)
#35 0x7f2ccfed00eb in g_main_context_iteration (/usr/lib64/libglib-2.0.so.0+0x4c0eb)
#36 0x7f2cd615414e in QEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) (/usr/lib64/libQt5Core.so.5+0x28e14e)
#37 0x7f2cc57ad740 (/usr/lib64/libQt5XcbQpa.so.5+0xcc740)
#38 0x7f2cd6100159 in QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) (/usr/lib64/libQt5Core.so.5+0x23a159)
#39 0x7f2cd7469cc6 in QDialog::exec() (/usr/lib64/libQt5Widgets.so.5+0x349cc6)
#40 0x7f2cd9300ed8 in KMessageBox::createKMessageBox(QDialog*, QDialogButtonBox*, QIcon const&, QString const&, QStringList const&, QString const&, bool*, QFlags<KMessageBox::Option>, QString const&, QMessageBox::Icon) (/usr/lib64/libKF5WidgetsAddons.so.5+0xbeed8)
#41 0x7f2cd930108d in KMessageBox::createKMessageBox(QDialog*, QDialogButtonBox*, QMessageBox::Icon, QString const&, QStringList const&, QString const&, bool*, QFlags<KMessageBox::Option>, QString const&) (/usr/lib64/libKF5WidgetsAddons.so.5+0xbf08d)
#42 0x7f2cd9304a79 (/usr/lib64/libKF5WidgetsAddons.so.5+0xc2a79)
#43 0x7f2cd9304f5e (/usr/lib64/libKF5WidgetsAddons.so.5+0xc2f5e)
#44 0x7f2cdc3978ec (/usr/lib64/libKF5JobWidgets.so.5+0xd8ec)
#45 0x7f2cd612b5a9 in QObject::event(QEvent*) (/usr/lib64/libQt5Core.so.5+0x2655a9)
#46 0x7f2cd727ad8b in QApplicationPrivate::notify_helper(QObject*, QEvent*) (/usr/lib64/libQt5Widgets.so.5+0x15ad8b)
#47 0x7f2cd728234e in QApplication::notify(QObject*, QEvent*) (/usr/lib64/libQt5Widgets.so.5+0x16234e)
#48 0x7f2cd6101366 in QCoreApplication::notifyInternal2(QObject*, QEvent*) (/usr/lib64/libQt5Core.so.5+0x23b366)
#49 0x7f2cd61041c0 in QCoreApplicationPrivate::sendPostedEvents(QObject*, int, QThreadData*) (/usr/lib64/libQt5Core.so.5+0x23e1c0)
#50 0x7f2cd6154362 (/usr/lib64/libQt5Core.so.5+0x28e362)
#51 0x7f2ccfecfe26 in g_main_context_dispatch (/usr/lib64/libglib-2.0.so.0+0x4be26)
#52 0x7f2ccfed005f (/usr/lib64/libglib-2.0.so.0+0x4c05f)
#53 0x7f2ccfed00eb in g_main_context_iteration (/usr/lib64/libglib-2.0.so.0+0x4c0eb)
#54 0x7f2cd615414e in QEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) (/usr/lib64/libQt5Core.so.5+0x28e14e)
#55 0x7f2cc57ad740 (/usr/lib64/libQt5XcbQpa.so.5+0xcc740)
#56 0x7f2cd6100159 in QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) (/usr/lib64/libQt5Core.so.5+0x23a159)
#57 0x7f2cd6108b3f in QCoreApplication::exec() (/usr/lib64/libQt5Core.so.5+0x242b3f)
#58 0x7f2cdf3aa336 in kdemain ../src/main.cpp:168
#59 0x5614d66ce86b in main src/dolphin_dummy.cpp:3
#60 0x7f2cde617ae6 in __libc_start_main (/lib64/libc.so.6+0x21ae6)
#61 0x5614d66ce749 in _start (/home/dha/workspace/kde/install/bin/dolphin+0x749)
0x6120002e3de0 is located 288 bytes inside of 320-byte region [0x6120002e3cc0,0x6120002e3e00)
freed by thread T0 here:
#0 0x7f2cdf7774b0 in operator delete(void*) (/usr/lib/gcc/x86_64-pc-linux-gnu/7.3.0/libasan.so+0xe14b0)
#1 0x7f2cdbc0912b in KIO::CopyJobPrivate::~CopyJobPrivate() ../src/core/copyjob.cpp:120
#2 0x7f2cdbc8633d in KIO::Job::~Job() ../src/core/job.cpp:55
#3 0x7f2cdbbd7638 in KIO::CopyJob::~CopyJob() ../src/core/copyjob.cpp:304
#4 0x7f2cdbbd7653 in KIO::CopyJob::~CopyJob() ../src/core/copyjob.cpp:306
#5 0x7f2cd612b5c7 in QObject::event(QEvent*) (/usr/lib64/libQt5Core.so.5+0x2655c7)
#6 0x7f2cd727ad8b in QApplicationPrivate::notify_helper(QObject*, QEvent*) (/usr/lib64/libQt5Widgets.so.5+0x15ad8b)
previously allocated by thread T0 here:
#0 0x7f2cdf776638 in operator new(unsigned long) (/usr/lib/gcc/x86_64-pc-linux-gnu/7.3.0/libasan.so+0xe0638)
#1 0x7f2cdbc04c0b in KIO::CopyJobPrivate::newJob(QList<QUrl> const&, QUrl const&, KIO::CopyJob::CopyMode, bool, QFlags<KIO::JobFlag>) (/home/dha/workspace/kde/install/lib64/libKF5KIOCore.so.5+0x151c0b)
#2 0x7f2cdbbfd8d3 in KIO::move(QList<QUrl> const&, QUrl const&, QFlags<KIO::JobFlag>) ../src/core/copyjob.cpp:2252
#3 0x7f2cdc818bc4 in KIO::DropJobPrivate::doCopyToDirectory() ../src/widgets/dropjob.cpp:486
#4 0x7f2cdc817e44 in KIO::DropJobPrivate::slotTriggered(QAction*) ../src/widgets/dropjob.cpp:431
#5 0x7f2cdc8180b8 in operator() ../src/widgets/dropjob.cpp:464
#6 0x7f2cdc81c95e in call /usr/include/qt5/QtCore/qobjectdefs_impl.h:128
#7 0x7f2cdc81c68e in call<QtPrivate::List<QAction*>, void> /usr/include/qt5/QtCore/qobjectdefs_impl.h:238
#8 0x7f2cdc81c41a in impl /usr/include/qt5/QtCore/qobjectdefs_impl.h:421
#9 0x7f2cd612a986 in QMetaObject::activate(QObject*, int, int, void**) (/usr/lib64/libQt5Core.so.5+0x264986)
#10 0x7f2cd73e8b01 in QMenu::triggered(QAction*) (/usr/lib64/libQt5Widgets.so.5+0x2c8b01)
SUMMARY: AddressSanitizer: heap-use-after-free ../src/core/copyjob.cpp:1464 in KIO::CopyJobPrivate::slotResultErrorCopyingFiles(KJob*)
Shadow bytes around the buggy address:
0x0c2480054760: fa fa fa fa fa fa fa fa fd fd fd fd fd fd fd fd
0x0c2480054770: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
0x0c2480054780: fd fd fd fd fd fd fd fd fd fd fd fd fa fa fa fa
0x0c2480054790: fa fa fa fa fa fa fa fa fd fd fd fd fd fd fd fd
0x0c24800547a0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
=>0x0c24800547b0: fd fd fd fd fd fd fd fd fd fd fd fd[fd]fd fd fd
0x0c24800547c0: fa fa fa fa fa fa fa fa fd fd fd fd fd fd fd fd
0x0c24800547d0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
0x0c24800547e0: fd fd fd fd fd fd fd fd fd fd fd fa fa fa fa fa
0x0c24800547f0: fa fa fa fa fa fa fa fa fd fd fd fd fd fd fd fd
0x0c2480054800: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
Shadow byte legend (one shadow byte represents 8 application bytes):
Addressable: 00
Partially addressable: 01 02 03 04 05 06 07
Heap left redzone: fa
Freed heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
Stack after return: f5
Stack use after scope: f8
Global redzone: f9
Global init order: f6
Poisoned by user: f7
Container overflow: fc
Array cookie: ac
Intra object redzone: bb
ASan internal: fe
Left alloca redzone: ca
Right alloca redzone: cb
==7539==ABORTING
I haven't figured out what's going on though. But the stack from where the object was freed looks like it was freed directly off an eventloop meaning it is most likely a result of a `deleteLater` call, but why would a slot still be connected to it? Or could it be caused by the fact that more then one `QEventLoop` is active since there is a `KMessageBox::exec` call involved? I will keep looking, but please comment if you have any pointers :)
REPOSITORY
R244 KCoreAddons
REVISION DETAIL
https://phabricator.kde.org/D19170
To: hallas, #frameworks, elvisangelaccio, dfaure
Cc: dhaumann, kde-frameworks-devel, michaelh, ngraham, bruns
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.kde.org/pipermail/kde-frameworks-devel/attachments/20190220/aed89b35/attachment-0001.html>
More information about the Kde-frameworks-devel
mailing list