Details
-
Bug
-
Resolution: Out of scope
-
P3: Somewhat important
-
4.5.2
-
None
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")
protected:
void timerEvent(QTimerEvent *)
};
#include "test.moc"
int main(int argc, char **argv)
{
QApplication a(argc, argv);
MyWidget w;
w.show();
return a.exec();
}