aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/qml/qml/qqmlboundsignal_p.h1
-rw-r--r--src/qml/qml/qqmlengine.cpp29
2 files changed, 30 insertions, 0 deletions
diff --git a/src/qml/qml/qqmlboundsignal_p.h b/src/qml/qml/qqmlboundsignal_p.h
index f9159ee70f..e3ef65ed7f 100644
--- a/src/qml/qml/qqmlboundsignal_p.h
+++ b/src/qml/qml/qqmlboundsignal_p.h
@@ -118,6 +118,7 @@ public:
virtual QQmlBoundSignalExpressionPointer setExpression(QQmlBoundSignalExpression *) = 0;
virtual QQmlBoundSignalExpressionPointer takeExpression(QQmlBoundSignalExpression *) = 0;
virtual QObject *scope() = 0;
+ virtual bool isEvaluating() const = 0;
void removeFromObject();
protected:
diff --git a/src/qml/qml/qqmlengine.cpp b/src/qml/qml/qqmlengine.cpp
index d3ca1b343c..2ebd13bb14 100644
--- a/src/qml/qml/qqmlengine.cpp
+++ b/src/qml/qml/qqmlengine.cpp
@@ -1307,6 +1307,35 @@ void QQmlData::destroyed(QObject *object)
QQmlAbstractBoundSignal *signalHandler = signalHandlers;
while (signalHandler) {
+ if (signalHandler->isEvaluating()) {
+ // The object is being deleted during signal handler evaluation.
+ // This will cause a crash due to invalid memory access when the
+ // evaluation has completed.
+ // Abort with a friendly message instead.
+ QString locationString;
+ QQmlBoundSignalExpression *expr = signalHandler->expression();
+ if (expr) {
+ QString fileName = expr->sourceFile();
+ if (fileName.isEmpty())
+ fileName = QStringLiteral("<Unknown File>");
+ locationString.append(fileName);
+ locationString.append(QString::fromLatin1(":%0: ").arg(expr->lineNumber()));
+ QString source = expr->expression();
+ if (source.size() > 100) {
+ source.truncate(96);
+ source.append(QStringLiteral(" ..."));
+ }
+ locationString.append(source);
+ } else {
+ locationString = QStringLiteral("<Unknown Location>");
+ }
+ qFatal("Object %p destroyed while one of its QML signal handlers is in progress.\n"
+ "Most likely the object was deleted synchronously (use QObject::deleteLater() "
+ "instead), or the application is running a nested event loop.\n"
+ "This behavior is NOT supported!\n"
+ "%s", object, qPrintable(locationString));
+ }
+
QQmlAbstractBoundSignal *next = signalHandler->m_nextSignal;
signalHandler->m_prevSignal = 0;
signalHandler->m_nextSignal = 0;