hallas added a comment.

  In D19170#416120 <https://phabricator.kde.org/D19170#416120>, @hallas wrote:
  
  > 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 :)
  
  
  Ok, I have some more info, I have tried to make the following change in 
copyjob.cpp:
  
    diff --git a/src/core/copyjob.cpp b/src/core/copyjob.cpp
    index 1d2e870a..f661d5be 100644
    --- a/src/core/copyjob.cpp
    +++ b/src/core/copyjob.cpp
    @@ -1457,7 +1457,9 @@ void CopyJobPrivate::slotResultErrorCopyingFiles(KJob 
*job)
                 if (files.count() > 1) {
                     options |= SkipDialog_MultipleItems;
                 }
    +            QPointer<KJob> jobGuard(job);
                 res = q->uiDelegateExtension()->askSkip(q, options, 
job->errorString());
    +            Q_ASSERT(!jobGuard.isNull());
             }
         }
  
  and I hit the above `Q_ASSERT(!jobGuard.isNull());` - to me this means that 
while `askSkip` is blocking the job completes and is deleted, so when we return 
from the function we have essentially been destroyed. Does this make sense? And 
how should we fix it? Simply return?

REPOSITORY
  R244 KCoreAddons

REVISION DETAIL
  https://phabricator.kde.org/D19170

To: hallas, #frameworks, elvisangelaccio, dfaure
Cc: dhaumann, kde-frameworks-devel, michaelh, ngraham, bruns

Reply via email to