summaryrefslogtreecommitdiffstats
path: root/src/corelib/kernel
diff options
context:
space:
mode:
authorMitch Curtis <mitch.curtis@digia.com>2012-11-27 14:54:51 +0100
committerThe Qt Project <gerrit-noreply@qt-project.org>2012-11-28 13:29:35 +0100
commitb898c4ed69caec14d51a2be4fc44a4ed54a06c48 (patch)
tree20b57d6b569ab9102baf507cc54470a7d51917c0 /src/corelib/kernel
parentd8cbb158b7013fdf889657f6197eab1b972949be (diff)
Prevent crashes after throwing an exception.
After bc3491c1b85ca36486c9472ecf7ba82f46699e8a, throwing an exception from a slot will cause the application to crash (segfault). This patch wraps the offending callFunction call in a try/catch block when QT_NO_EXCEPTIONS is defined, allowing the appropriate cleanup to occur and hence preventing the crash. Task-number: QTBUG-26825 Task-number: QTBUG-27548 Change-Id: Ia3a02398b0308b2216ad17f8f643745bd013fd50 Reviewed-by: Olivier Goffart <ogoffart@woboq.com> Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> Reviewed-by: Andy Shaw <andy.shaw@digia.com>
Diffstat (limited to 'src/corelib/kernel')
-rw-r--r--src/corelib/kernel/qobject.cpp15
1 files changed, 15 insertions, 0 deletions
diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp
index 9008fb8fb5..5ac32aec53 100644
--- a/src/corelib/kernel/qobject.cpp
+++ b/src/corelib/kernel/qobject.cpp
@@ -3536,8 +3536,23 @@ void QMetaObject::activate(QObject *sender, const QMetaObject *m, int local_sign
if (qt_signal_spy_callback_set.slot_begin_callback != 0)
qt_signal_spy_callback_set.slot_begin_callback(receiver, c->method(), argv ? argv : empty_argv);
+#if defined(QT_NO_EXCEPTIONS)
callFunction(receiver, QMetaObject::InvokeMetaMethod, method_relative, argv ? argv : empty_argv);
+#else
+ QT_TRY {
+ callFunction(receiver, QMetaObject::InvokeMetaMethod, method_relative, argv ? argv : empty_argv);
+ } QT_CATCH(...) {
+ locker.relock();
+ if (receiverInSameThread)
+ QObjectPrivate::resetCurrentSender(receiver, &currentSender, previousSender);
+ --connectionLists->inUse;
+ Q_ASSERT(connectionLists->inUse >= 0);
+ if (connectionLists->orphaned && !connectionLists->inUse)
+ delete connectionLists;
+ QT_RETHROW;
+ }
+#endif
if (qt_signal_spy_callback_set.slot_end_callback != 0)
qt_signal_spy_callback_set.slot_end_callback(receiver, c->method());
locker.relock();