Bug 356964

Summary: kjobtrackerstest crashes when done (but not yet exiting)
Product: [Frameworks and Libraries] frameworks-kio Reporter: RJVB <rjvbertin>
Component: generalAssignee: David Faure <faure>
Status: RESOLVED FIXED    
Severity: crash CC: kdelibs-bugs
Priority: NOR    
Version: unspecified   
Target Milestone: ---   
Platform: Compiled Sources   
OS: All   
Latest Commit: Version Fixed In:
Sentry Crash Report:

Description RJVB 2015-12-20 19:18:01 UTC
With KIO 5.17.0, the kjobtrackerstest test crashes when it is done:

Full backtrace from the main thread (the other threads don't give any additional information):

* thread #1: tid = 0xf20883, 0x000000010125102c QtCore`QMetaObject::invokeMethod(obj=0x0000000103c4c020, member=0x00000001000734b7, type=QueuedConnection, val0=(_data = const void * = 0x0000000000000000, _name = const char * = 0x0000000000000000), val1=(_data = const void * = 0x0000000000000000, _name = const char * = 0x0000000000000000), val2=(_data = const void * = 0x0000000000000000, _name = const char * = 0x0000000000000000), val3=(_data = const void * = 0x0000000000000000, _name = const char * = 0x0000000000000000), val4=(_data = const void * = 0x0000000000000000, _name = const char * = 0x0000000000000000), val5=(_data = const void * = 0x0000000000000000, _name = const char * = 0x0000000000000000), val6=(_data = const void * = 0x0000000000000000, _name = const char * = 0x0000000000000000), val7=(_data = const void * = 0x0000000000000000, _name = const char * = 0x0000000000000000), val8=(_data = const void * = 0x0000000000000000, _name = const char * = 0x0000000000000000), val9=(_data = const void * = 0x0000000000000000, _name = const char * = 0x0000000000000000), ret=<unavailable>) + 1612 at qmetaobject.cpp:1464, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x0)
    frame #0: 0x000000010125102c QtCore`QMetaObject::invokeMethod(obj=0x0000000103c4c020, member=0x00000001000734b7, type=QueuedConnection, val0=(_data = const void * = 0x0000000000000000, _name = const char * = 0x0000000000000000), val1=(_data = const void * = 0x0000000000000000, _name = const char * = 0x0000000000000000), val2=(_data = const void * = 0x0000000000000000, _name = const char * = 0x0000000000000000), val3=(_data = const void * = 0x0000000000000000, _name = const char * = 0x0000000000000000), val4=(_data = const void * = 0x0000000000000000, _name = const char * = 0x0000000000000000), val5=(_data = const void * = 0x0000000000000000, _name = const char * = 0x0000000000000000), val6=(_data = const void * = 0x0000000000000000, _name = const char * = 0x0000000000000000), val7=(_data = const void * = 0x0000000000000000, _name = const char * = 0x0000000000000000), val8=(_data = const void * = 0x0000000000000000, _name = const char * = 0x0000000000000000), val9=(_data = const void * = 0x0000000000000000, _name = const char * = 0x0000000000000000), ret=<unavailable>) + 1612 at qmetaobject.cpp:1464
    frame #1: 0x0000000100061e31 libKF5JobWidgets.5.dylib`KDialogJobUiDelegate::Private::next() [inlined] QMetaObject::invokeMethod(obj=0x0000000103c4c020, member=<unavailable>, type=<unavailable>, val1=(_data = const void * = 0x0000000000000000, _name = const char * = 0x0000000000000000), val2=(_data = const void * = 0x0000000000000000, _name = const char * = 0x0000000000000000), val3=(_data = const void * = 0x0000000000000000, _name = const char * = 0x0000000000000000), val4=(_data = const void * = 0x0000000000000000, _name = const char * = 0x0000000000000000), val5=(_data = const void * = 0x0000000000000000, _name = const char * = 0x0000000000000000), val6=(_data = const void * = 0x0000000000000000, _name = const char * = 0x0000000000000000), val7=(_data = const void * = 0x0000000000000000, _name = const char * = 0x0000000000000000), val8=(_data = const void * = 0x0000000000000000, _name = const char * = 0x0000000000000000), val9=(_data = const void * = 0x0000000000000000, _name = const char * = 0x0000000000000000)) + 593 at qobjectdefs.h:408
  * frame #2: 0x0000000100061d8d libKF5JobWidgets.5.dylib`KDialogJobUiDelegate::Private::next(this=0x0000000103c4c020) + 429 at kdialogjobuidelegate.cpp:82
    frame #3: 0x00000001012716e3 QtCore`QObject::event(this=<unavailable>, e=<unavailable>) + 675 at qobject.cpp:1239
    frame #4: 0x000000010018453b QtWidgets`QApplicationPrivate::notify_helper(this=<unavailable>, receiver=0x0000000103c4c020, e=0x00000001102005a0) + 251 at qapplication.cpp:3716
    frame #5: 0x00000001001878f4 QtWidgets`QApplication::notify(this=<unavailable>, receiver=<unavailable>, e=<unavailable>) + 8212 at qapplication.cpp:3681
    frame #6: 0x00000001012490db QtCore`QCoreApplicationPrivate::sendPostedEvents(QObject*, int, QThreadData*) [inlined] QCoreApplication::notifyInternal(this=<unavailable>, receiver=<unavailable>, event=<unavailable>) + 95 at qcoreapplication.cpp:970
    frame #7: 0x000000010124907c QtCore`QCoreApplicationPrivate::sendPostedEvents(QObject*, int, QThreadData*) [inlined] QCoreApplication::sendEvent(receiver=<unavailable>, event=0x00000001102005a0) + 28 at qcoreapplication.h:224
    frame #8: 0x0000000101249060 QtCore`QCoreApplicationPrivate::sendPostedEvents(receiver=0x0000000000000000, event_type=0, data=0x0000000103e00a00) + 848 at qcoreapplication.cpp:1598
    frame #9: 0x0000000107f9c6ce libqcocoa.dylib`QCocoaEventDispatcherPrivate::processPostedEvents(this=0x0000000103e507c0) + 190 at qcocoaeventdispatcher.mm:885
    frame #10: 0x0000000107f9cf51 libqcocoa.dylib`QCocoaEventDispatcherPrivate::postedEventsSourceCallback(info=0x0000000103e507c0) + 33 at qcocoaeventdispatcher.mm:922
    frame #11: 0x00007fff91f0f5b1 CoreFoundation`__CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17
    frame #12: 0x00007fff91f00d29 CoreFoundation`__CFRunLoopDoSources0 + 441
    frame #13: 0x00007fff91f003ef CoreFoundation`__CFRunLoopRun + 831
    frame #14: 0x00007fff91effe75 CoreFoundation`CFRunLoopRunSpecific + 309
    frame #15: 0x00007fff94501a0d HIToolbox`RunCurrentEventLoopInMode + 226
    frame #16: 0x00007fff945017b7 HIToolbox`ReceiveNextEventCommon + 479
    frame #17: 0x00007fff945015bc HIToolbox`_BlockUntilNextEventMatchingListInModeWithFilter + 65
    frame #18: 0x00007fff8bd5d24e AppKit`_DPSNextEvent + 1434
    frame #19: 0x00007fff8bd5c89b AppKit`-[NSApplication nextEventMatchingMask:untilDate:inMode:dequeue:] + 122
    frame #20: 0x00007fff8bd5099c AppKit`-[NSApplication run] + 553
    frame #21: 0x0000000107f9be3d libqcocoa.dylib`QCocoaEventDispatcher::processEvents(this=0x0000000103e4e890, flags=<unavailable>) + 2189 at qcocoaeventdispatcher.mm:418
    frame #22: 0x0000000101245b5d QtCore`QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) [inlined] QEventLoop::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) + 381 at qeventloop.cpp:128
    frame #23: 0x0000000101245b44 QtCore`QEventLoop::exec(this=0x00007fff5fbfed70, flags=<unavailable>) + 356 at qeventloop.cpp:204
    frame #24: 0x00000001012489d5 QtCore`QCoreApplication::exec() + 325 at qcoreapplication.cpp:1234
    frame #25: 0x000000010000453b kjobtrackerstest`main(argc=1, argv=<unavailable>) + 603 at kjobtrackerstest.cpp:181


The contents of 'this' in frame 2 (frame 3 on Linux):

(lldb) f 2
frame #2: 0x0000000100061d8d libKF5JobWidgets.5.dylib`KDialogJobUiDelegate::Private::next(this=0x0000000103c4c020) + 429 at kdialogjobuidelegate.cpp:82
   79       QSharedPointer<MessageBoxData> data = queue.dequeue();
   80       KMessageBox::messageBox(data->widget, data->type, data->msg);
   81   
-> 82       QMetaObject::invokeMethod(this, "next", Qt::QueuedConnection);
   83   }
   84   
   85   void KDialogJobUiDelegate::Private::queuedMessageBox(QWidget *widget, KMessageBox::DialogType type, const QString &msg)
(lldb) p *this
(KDialogJobUiDelegate::Private) $2 = {
  QObject = {
    d_ptr = {
      d = 0x0000000103c95400
    }
  }
  window = 0x0000000000000000
  running = false
  queue = {
    QList<QSharedPointer<MessageBoxData> > = {
       = {
        p = {
          d = 0x4060200000000000
        }
        d = 0x4060200000000000
      }
    }
  }
}


Reproducible: Always

Steps to Reproduce:
1. build KIO
2. start tests/kjobtrackerstest.app/Contents/MacOS/kjobtrackerstest (or tests/kjobtrackerstest on Linux)
3. let it run and then close the information dialog that says 'dir0'

Actual Results:  
crash

Expected Results:  
no crash ...

This looks like an event coming in for an already object corresponding to in already delete instance, IOW something that should be deleted with QObject::deleteLater().
Comment 1 David Edmundson 2016-02-08 15:13:12 UTC
Git commit e984dab0a6cd9541ae178c104f0228ae264284a6 by David Edmundson.
Committed on 08/02/2016 at 15:13.
Pushed by davidedmundson into branch 'master'.

Fix crash in KJob dialogs.

Guard "this" being deleted whilst running new eventloop

KMessageBox spawns a new event loop, during which the parent kjob can be
completed and deleted, deleting the UIDelegate with it.
Related: bug 356321, bug 355052, bug 355525, bug 353462, bug 358954, bug 346215
REVIEW: 126999

M  +9    -0    src/kdialogjobuidelegate.cpp

http://commits.kde.org/kjobwidgets/e984dab0a6cd9541ae178c104f0228ae264284a6