Uploaded image for project: 'Qt'
  1. Qt
  2. QTBUG-4291

Q3FileDialog Drag and Drop crash

    XMLWordPrintable

Details

    Description

      The crash occurrs when doing a drag&drop operating while other events are
      being processed in the background. I had already tracked it down to some
      unprotected resources in Q3ListView in 2007. Dangling pointer or so. The
      attached example can be used to reproduce it

      1) start example
      2) drag&drop a file into a sub-directory
      3) perform step 2 again

      Here is the backtrace (from 2007):

      (gdb) bt
      #0 0xffffe410 in ?? ()
      #1 0xbfffc76c in ?? ()
      #2 0x00000006 in ?? ()
      #3 0x00002b0a in ?? ()
      #4 0x412bc501 in raise () from /lib/tls/libc.so.6
      #5 0x412bdcd9 in abort () from /lib/tls/libc.so.6
      #6 0x40fc911f in qt_message_output (msgType=QtFatalMsg,
      buf=0xbfffc8e0 "ASSERT failure in QVector<T>::operator[]: \"index out of
      range\", file ../../src/corelib/tools/qvector.h, line 292")
      at global/qglobal.cpp:2145
      #7 0x40fc94af in qFatal (
      msg=0x410be730 "ASSERT failure in %s: \"%s\", file %s, line %d")
      at global/qglobal.cpp:2376
      #8 0x40fc8d18 in qt_assert_x (where=0x402e797d "QVector<T>::operator[]",
      what=0x402e796a "index out of range",
      file=0x402e7948 "../../src/corelib/tools/qvector.h", line=292)
      at global/qglobal.cpp:1912
      #9 0x40175b51 in QVector<int>::operator[] (this=0x8122070, i=-1)
      at qvector.h:292
      #10 0x401737e2 in Q3ListBox::itemRect (this=0x81e4a68, item=0x81e1368)
      at itemviews/q3listbox.cpp:3730
      #11 0x40200efe in QFileListBox::viewportMouseMoveEvent (this=0x81e4a68,
      e=0xbfffeea0) at dialogs/q3filedialog.cpp:1279
      #12 0x401e7d02 in Q3ScrollView::eventFilter (this=0x81e4a68,
      obj=0x81e1d78,
      e=0xbfffeea0) at widgets/q3scrollview.cpp:1495
      #13 0x4016fd04 in Q3ListBox::eventFilter (this=0x81e4a68, o=0x81e1d78,
      e=0xbfffeea0) at itemviews/q3listbox.cpp:2521
      #14 0x406f7636 in QApplicationPrivate::notify_helper (this=0x804c198,
      receiver=0x81e1d78, e=0xbfffeea0) at kernel/qapplication.cpp:3530

      The problem is repored to still be present in 4.5.1. I noticed it's not
      always immediately reproducable. Likely influenced by CPU power, system
      load and exact timing.

      It's completely unreliable which confirms my believe that something is broken in the
      implementation. Try to drop a file on a directory several times. Circle
      around. My best success is when I move the dragged file into the list view
      from the top onto a directory. You'll see the cursor changing.

      It took me 5 more minutes and dozens of tries to reproduce the crash.
      Luckily I had Valgrind running - a different timing can be helpful. Here
      is the log:

      ==22344== Invalid write of size 4
      ==22344== at 0x5D3AB5F: QDrag::exec(QFlags<Qt::DropAction>, Qt::DropAction) (qdrag.cpp:282)
      ==22344== by 0x4F37274: Q3DragObject::drag(Q3DragObject::DragMode) (in /home/porten/obj/qt45/lib/libQt3Support.so.4.5.2)
      ==22344== by 0x4F3456E: Q3DragObject::drag() (in /home/porten/obj/qt45/lib/libQt3Support.so.4.5.2)
      ==22344== by 0x5004B1D: QFileListBox::viewportMouseMoveEvent(QMouseEvent*) (in /home/porten/obj/qt45/lib/libQt3Support.so.4.5.2)
      ==22344== by 0x4FDF71C: Q3ScrollView::eventFilter(QObject*, QEvent*) (in /home/porten/obj/qt45/lib/libQt3Support.so.4.5.2)
      ==22344== by 0x4F675AE: Q3ListBox::eventFilter(QObject*, QEvent*) (in /home/porten/obj/qt45/lib/libQt3Support.so.4.5.2)
      ==22344== by 0x7DCD356: QCoreApplicationPrivate::sendThroughObjectEventFilters(QObject*, QEvent*) (qcoreapplication.cpp:726)
      ==22344== by 0x5D24184: QApplicationPrivate::notify_helper(QObject*, QEvent*) (qapplication.cpp:4054)
      ==22344== by 0x5D24F5F: QApplication::notify(QObject*, QEvent*) (qapplication.cpp:3760)
      ==22344== by 0x7DCED86: QCoreApplication::notifyInternal(QObject*, QEvent*) (qcoreapplication.cpp:606)
      ==22344== by 0x4F3D1FA: QCoreApplication::sendSpontaneousEvent(QObject*, QEvent*) (in /home/porten/obj/qt45/lib/libQt3Support.so.4.5.2)
      ==22344== by 0x5D28DA2: QApplicationPrivate::sendMouseEvent(QWidget*, QMouseEvent*, QWidget*, QWidget*, QWidget**, QPointer<QWidget>&) (qapplication.cpp:2924)
      ==22344== Address 0xc79da24 is 188 bytes inside a block of size 208 free'd
      ==22344== at 0x4C2211D: operator delete(void*) (vg_replace_malloc.c:342)
      ==22344== by 0x5D3B7F8: QDragPrivate::~QDragPrivate() (qdnd_p.h:174)
      ==22344== by 0x7DE6416: QObject::~QObject() (qobject.cpp:857)
      ==22344== by 0x5D3AC3B: QDrag::~QDrag() (qdrag.cpp:133)
      ==22344== by 0x7DDEADF: qDeleteInEventHandler(QObject*) (qobject.cpp:3806)
      ==22344== by 0x7DE2E3D: QObject::event(QEvent*) (qobject.cpp:1085)
      ==22344== by 0x5D241A6: QApplicationPrivate::notify_helper(QObject*, QEvent*) (qapplication.cpp:4058)
      ==22344== by 0x5D2455D: QApplication::notify(QObject*, QEvent*) (qapplication.cpp:3605)
      ==22344== by 0x7DCED86: QCoreApplication::notifyInternal(QObject*, QEvent*) (qcoreapplication.cpp:606)
      ==22344== by 0x4F3D1A0: QCoreApplication::sendEvent(QObject*, QEvent*) (in /home/porten/obj/qt45/lib/libQt3Support.so.4.5.2)
      ==22344== by 0x7DCF2D8: QCoreApplicationPrivate::sendPostedEvents(QObject*, int, QThreadData*) (qcoreapplication.cpp:1244)
      ==22344== by 0x7DCF4AF: QCoreApplication::sendPostedEvents(QObject*, int) (qcoreapplication.cpp:1140)

      [several more read access errors until the crash]

      ==22344==
      ==22344== Process terminating with default action of signal 11 (SIGSEGV)
      ==22344== Access not within mapped region at address 0x88
      ==22344== at 0x5D3A85B: QDrag::target() const (qdrag.cpp:219)
      ==22344== by 0x4F37286: Q3DragObject::drag(Q3DragObject::DragMode) (in /home/porten/obj/qt45/lib/libQt3Support.so.4.5.2)
      ==22344== by 0x4F3456E: Q3DragObject::drag() (in /home/porten/obj/qt45/lib/libQt3Support.so.4.5.2)
      ==22344== by 0x5004B1D: QFileListBox::viewportMouseMoveEvent(QMouseEvent*) (in /home/porten/obj/qt45/lib/libQt3Support.so.4.5.2)
      ==22344== by 0x4FDF71C: Q3ScrollView::eventFilter(QObject*, QEvent*) (in /home/porten/obj/qt45/lib/libQt3Support.so.4.5.2)
      ==22344== by 0x4F675AE: Q3ListBox::eventFilter(QObject*, QEvent*) (in /home/porten/obj/qt45/lib/libQt3Support.so.4.5.2)
      ==22344== by 0x7DCD356: QCoreApplicationPrivate::sendThroughObjectEventFilters(QObject*, QEvent*) (qcoreapplication.cpp:726)
      ==22344== by 0x5D24184: QApplicationPrivate::notify_helper(QObject*, QEvent*) (qapplication.cpp:4054)
      ==22344== by 0x5D24F5F: QApplication::notify(QObject*, QEvent*) (qapplication.cpp:3760)
      ==22344== by 0x7DCED86: QCoreApplication::notifyInternal(QObject*, QEvent*) (qcoreapplication.cpp:606)
      ==22344== by 0x4F3D1FA: QCoreApplication::sendSpontaneousEvent(QObject*, QEvent*) (in /home/porten/obj/qt45/lib/libQt3Support.so.4.5.2)
      ==22344== by 0x5D28DA2: QApplicationPrivate::sendMouseEvent(QWidget*, QMouseEvent*, QWidget*, QWidget*, QWidget**, QPointer<QWidget>&) (qapplication.cpp:2924)

      The use QApplication::processEvent() is admittingly a bit mean. But
      sometimes it cannot be avoided. I understand it's the developers
      responsibility to protect recurses against recursive calls but in this
      cases the problem is somewhere in Q3ListBox and Q3DragObject and therefore
      not fixable for us or our clients. And given how unreliable DnD works
      event without processEvents() I suspect something is fishy anyway.

      example code to reproduce:

      #include <QApplication>
      #include <QLabel>
      #include <Q3FileDialog>

      class MyWidget : public QLabel
      {
      Q_OBJECT
      public:
      MyWidget() : QLabel("Drag a file into a directory")

      { startTimer(100); Q3FileDialog *fd = new Q3FileDialog(this); fd->exec(); }

      protected:
      void timerEvent(QTimerEvent *)

      { qApp->processEvents(); }

      };

      #include "test.moc"

      int main(int argc, char **argv)
      {
      QApplication a(argc, argv);
      MyWidget w;

      w.show();

      return a.exec();
      }

      Attachments

        No reviews matched the request. Check your Options in the drop-down menu of this sections header.

        Activity

          People

            Unassigned Unassigned
            janichol Andy Nichols
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved:

              Gerrit Reviews

                There are no open Gerrit changes