Details
-
Bug
-
Resolution: Incomplete
-
P1: Critical
-
6.5.0
-
None
-
d548077d2 (dev), 1faaefe3b (6.7), f18e14764 (6.6), 4ddb62e5d (tqtc/lts-6.5)
Description
When you have a QtQuick Text element that has an onLineLaidOut signal handler defined and you access/modify the properties of the passed line parameter (QQuickTextLine), you sometimes hit a crash.
It seems this is a duplicated of QTBUG-106517 which was closed as 'can not reproduce', maybe my investigations can help to find a minimal test case:
I added debug output before and after the place where the lineLaidOut signal is emitted in QQuickTextPrivate::setupCustomLineGeometry
void QQuickTextPrivate::setupCustomLineGeometry(QTextLine &line, qreal &height, int fullLayoutTextLength, int lineOffset) { .... textLine->setLine(&line); .... qCritical("before lineLaidOut"); emit q->lineLaidOut(textLine); qCritical("after lineLaidOut"); .... }
and in addition added debug output to the signal handler
Text { .... onLineLaidOut: (line) => { console.log("text='"+label.text+"' number=" + line.number); if (line.number > 0) line.y -= 2; } }
when I run the application now, most of the time you see the 'before' message, followed by the 'text=...' message and concluded by the 'after' message, so the signal handler is invoked immediately on emit call.
But sometimes (and I cannot figure out why or reproduce when), you see 'before' followed by 'after' message and only later on the 'text=' message is printed. So the signal handler is executed much later by the QML runtime, after the QQuickTextPrivate::setupCustomLineGeometry function has already been left.
And exactly that is the problem, because the 'm_line' property of QQuickTextLine was initialized with a pointer to the 'local' line parameter of QQuickTextPrivate::setupCustomLineGeometry, so at the time the signal handler is invoked it might point to some arbitrary piece in the stack.
The backtrace looks like the following in that case
Thread 1 "tnx" received signal SIGSEGV, Segmentation fault. 0x00007ffff60bbc8f in QFixed::toReal (this=0x75c0855f5e0005e8) at /mnt/archive/src/qt5/build-pwd-6/qtbase/include/QtGui/6.5.0/QtGui/private/../../../../../../../src-pwd-6/qtbase/src/gui/painting/qfixed_p.h:41 41 constexpr inline qreal toReal() const { return ((qreal)val)/(qreal)64; } (gdb) bt #0 0x00007ffff60bbc8f in QFixed::toReal (this=0x75c0855f5e0005e8) at /mnt/archive/src/qt5/build-pwd-6/qtbase/include/QtGui/6.5.0/QtGui/private/../../../../../../../src-pwd-6/qtbase/src/gui/painting/qfixed_p.h:41 #1 QTextLine::y (this=0x7fffceffc360) at /mnt/archive/src/qt5/src-pwd-6/qtbase/src/gui/text/qtextlayout.cpp:1486 #2 0x00007ffff6fc2630 in QQuickTextLine::y (this=this@entry=0x55555b5b09a0) at /mnt/archive/src/qt5/src-pwd-6/qtdeclarative/src/quick/items/qquicktext.cpp:573 #3 0x00007ffff6fc2750 in QQuickTextLine::qt_static_metacall (_o=0x55555b5b09a0, _c=<optimized out>, _id=4, _a=<optimized out>) at /mnt/archive/src/qt5/build-pwd-6/qtdeclarative/src/quick/Quick_autogen/include/moc_qquicktext_p.cpp:1857 #4 0x00007ffff680a43e in QQmlPropertyData::readPropertyWithArgs (this=this@entry=0x55555875d130, target=target@entry=0x55555b5b09a0, args=args@entry=0x7fffffffb6a0) at /mnt/archive/src/qt5/build-pwd-6/qtdeclarative/include/QtQml/6.5.0/QtQml/private/../../../../../../../src-pwd-6/qtdeclarative/src/qml/qml/qqmlpropertydata_p.h:329 #5 0x00007ffff67fe569 in QQmlPropertyData::readProperty (property=0x7fffffffb670, target=0x55555b5b09a0, this=0x55555875d130) at /mnt/archive/src/qt5/build-pwd-6/qtdeclarative/include/QtQml/6.5.0/QtQml/private/../../../../../../../src-pwd-6/qtdeclarative/src/qml/qml/qqmlpropertydata_p.h:312 #6 QV4::loadProperty (v4=v4@entry=0x555555742d90, wrapper=wrapper@entry=0x7fff7cd77c60, object=0x55555b5b09a0, property=...) at /mnt/archive/src/qt5/src-pwd-6/qtdeclarative/src/qml/jsruntime/qv4qobjectwrapper.cpp:162 #7 0x00007ffff67ff0b8 in QV4::QObjectWrapper::getProperty (engine=engine@entry=0x555555742d90, wrapper=0x7fff7cd77c60, object=<optimized out>, property=0x55555875d130, flags=...) at /mnt/archive/src/qt5/src-pwd-6/qtdeclarative/src/qml/jsruntime/qv4qobjectwrapper.cpp:289 #8 0x00007ffff679e6bb in QV4::QObjectWrapper::lookupPropertyGetterImpl<QV4::Lookup::getterQObject(QV4::Lookup*, QV4::ExecutionEngine*, const QV4::Value&)::<lambda()> > (revertLookup=..., flags=..., object=..., engine=0x555555742d90, lookup=0x555555f7e730) at /mnt/archive/src/qt5/build-pwd-6/qtdeclarative/include/QtQml/6.5.0/QtQml/private/../../../../../../../src-pwd-6/qtdeclarative/src/qml/jsruntime/qv4qobjectwrapper_p.h:298 #9 QV4::Lookup::getterQObject (lookup=0x555555f7e730, engine=0x555555742d90, object=...) at /mnt/archive/src/qt5/src-pwd-6/qtdeclarative/src/qml/jsruntime/qv4lookup.cpp:401 #10 0x00007ffff682f429 in QV4::Runtime::GetLookup::call (engine=0x555555742d90, f=<optimized out>, base=..., index=<optimized out>) at /mnt/archive/src/qt5/src-pwd-6/qtdeclarative/src/qml/jsruntime/qv4runtime.cpp:1128 #11 0x00007fffb4043c70 in ?? () #12 0x0000555555b8f3b0 in ?? () #13 0x0000000000000000 in ?? () (gdb) quit A debugging session is active.
So how can this delayed execution of the onLineLaidOut signal handler be fixed?