Fix crash when using signaldumper and sender is deleted

Testlib's signaldumper functionality would crash inside
testlib as it dereferenced the sender after it was deleted.

Change-Id: I6013b75b0a121e2768429d8a3cf0339a940314f2
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
This commit is contained in:
Mårten Nordheim 2019-09-18 10:46:58 +02:00
parent 4f757e0757
commit 895a786827
8 changed files with 52 additions and 15 deletions

View File

@ -3908,11 +3908,12 @@ void doActivate(QObject *sender, int signal_index, void **argv)
if (connections->currentConnectionId.loadRelaxed() == 0)
senderDeleted = true;
}
if (!senderDeleted)
if (!senderDeleted) {
sp->connections.loadRelaxed()->cleanOrphanedConnections(sender);
if (callbacks_enabled && signal_spy_set->signal_end_callback != nullptr)
signal_spy_set->signal_end_callback(sender, signal_index);
if (callbacks_enabled && signal_spy_set->signal_end_callback != nullptr)
signal_spy_set->signal_end_callback(sender, signal_index);
}
}
/*!

View File

@ -568,11 +568,18 @@
<Incident type="pass" file="" line="0" />
<Duration msecs="0"/>
</TestFunction>
<TestFunction name="deletingSender">
<Message type="info" file="" line="0">
<Description><![CDATA[Signal: SignalSlotClass(_POINTER_) signalWithoutParameters ()]]></Description>
</Message>
<Incident type="pass" file="" line="0" />
<Duration msecs="0"/>
</TestFunction>
<TestFunction name="cleanupTestCase">
<Incident type="pass" file="" line="0" />
<Duration msecs="0"/>
</TestFunction>
<Message type="info" file="" line="0">
<Description><![CDATA[Signal: QThread(_POINTER_) finished ()]]></Description>
<Description><![CDATA[ Signal: QThread(_POINTER_) finished ()]]></Description>
</Message>
<Duration msecs="0"/>

View File

@ -143,9 +143,11 @@ ok 18 - slotEmittingSignalOldSyntax(queued)
# Signal: SignalSlotClass(_POINTER_) qVariantSignal (QVariant())
# Signal: SignalSlotClass(_POINTER_) qVariantSignal (QVariant())
ok 19 - variousTypes()
ok 20 - cleanupTestCase()
# Signal: QThread(_POINTER_) finished ()
1..20
# tests 20
# pass 20
# Signal: SignalSlotClass(_POINTER_) signalWithoutParameters ()
ok 20 - deletingSender()
ok 21 - cleanupTestCase()
# Signal: QThread(_POINTER_) finished ()
1..21
# tests 21
# pass 21
# fail 0

View File

@ -56,6 +56,9 @@
##teamcity[testStarted name='variousTypes()' flowId='tst_Signaldumper']
##teamcity[testStdOut name='variousTypes()' out='INFO: Signal: SignalSlotClass(_POINTER_) qStringSignal (QString(Test string))|nINFO: Signal: SignalSlotClass(_POINTER_) qStringRefSignal ((QString&)@_POINTER_)|nINFO: Signal: SignalSlotClass(_POINTER_) qStringConstRefSignal (QString(Test string))|nINFO: Signal: SignalSlotClass(_POINTER_) qByteArraySignal (QByteArray(Test bytearray))|nINFO: Signal: SignalSlotClass(_POINTER_) qListSignal (QList<int>())|nINFO: Signal: SignalSlotClass(_POINTER_) qVectorSignal (QVector<int>())|nINFO: Signal: SignalSlotClass(_POINTER_) qVectorRefSignal ((QVector<int>&)@_POINTER_)|nINFO: Signal: SignalSlotClass(_POINTER_) qVectorConstRefSignal (QVector<int>())|nINFO: Signal: SignalSlotClass(_POINTER_) qVectorConstPointerSignal ((const QVector<int>*)_POINTER_)|nINFO: Signal: SignalSlotClass(_POINTER_) qVectorPointerConstSignal ()|nINFO: Signal: SignalSlotClass(_POINTER_) qVariantSignal (QVariant())|nINFO: Signal: SignalSlotClass(_POINTER_) qVariantSignal (QVariant())' flowId='tst_Signaldumper']
##teamcity[testFinished name='variousTypes()' flowId='tst_Signaldumper']
##teamcity[testStarted name='deletingSender()' flowId='tst_Signaldumper']
##teamcity[testStdOut name='deletingSender()' out='INFO: Signal: SignalSlotClass(_POINTER_) signalWithoutParameters ()' flowId='tst_Signaldumper']
##teamcity[testFinished name='deletingSender()' flowId='tst_Signaldumper']
##teamcity[testStarted name='cleanupTestCase()' flowId='tst_Signaldumper']
##teamcity[testFinished name='cleanupTestCase()' flowId='tst_Signaldumper']
##teamcity[testSuiteFinished name='tst_Signaldumper' flowId='tst_Signaldumper']

View File

@ -143,7 +143,9 @@ INFO : tst_Signaldumper::variousTypes() Signal: SignalSlotClass(_POINTER_) qVe
INFO : tst_Signaldumper::variousTypes() Signal: SignalSlotClass(_POINTER_) qVariantSignal (QVariant())
INFO : tst_Signaldumper::variousTypes() Signal: SignalSlotClass(_POINTER_) qVariantSignal (QVariant())
PASS : tst_Signaldumper::variousTypes()
INFO : tst_Signaldumper::deletingSender() Signal: SignalSlotClass(_POINTER_) signalWithoutParameters ()
PASS : tst_Signaldumper::deletingSender()
PASS : tst_Signaldumper::cleanupTestCase()
INFO : tst_Signaldumper::UnknownTestFunc() Signal: QThread(_POINTER_) finished ()
Totals: 20 passed, 0 failed, 0 skipped, 0 blacklisted, 0ms
INFO : tst_Signaldumper::UnknownTestFunc() Signal: QThread(_POINTER_) finished ()
Totals: 21 passed, 0 failed, 0 skipped, 0 blacklisted, 0ms
********* Finished testing of tst_Signaldumper *********

View File

@ -570,12 +570,19 @@
<Incident type="pass" file="" line="0" />
<Duration msecs="0"/>
</TestFunction>
<TestFunction name="deletingSender">
<Message type="info" file="" line="0">
<Description><![CDATA[Signal: SignalSlotClass(_POINTER_) signalWithoutParameters ()]]></Description>
</Message>
<Incident type="pass" file="" line="0" />
<Duration msecs="0"/>
</TestFunction>
<TestFunction name="cleanupTestCase">
<Incident type="pass" file="" line="0" />
<Duration msecs="0"/>
</TestFunction>
<Message type="info" file="" line="0">
<Description><![CDATA[Signal: QThread(_POINTER_) finished ()]]></Description>
<Description><![CDATA[ Signal: QThread(_POINTER_) finished ()]]></Description>
</Message>
<Duration msecs="0"/>
</TestCase>

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" ?>
<testsuite errors="125" failures="0" tests="12" name="tst_Signaldumper">
<testsuite errors="126" failures="0" tests="13" name="tst_Signaldumper">
<properties>
<property value="@INSERT_QT_VERSION_HERE@" name="QTestVersion"/>
<property value="@INSERT_QT_VERSION_HERE@" name="QtVersion"/>
@ -151,8 +151,11 @@
<!-- message="Signal: SignalSlotClass(_POINTER_) qVariantSignal (QVariant())" type="info" -->
<!-- message="Signal: SignalSlotClass(_POINTER_) qVariantSignal (QVariant())" type="info" -->
</testcase>
<testcase result="pass" name="deletingSender">
<!-- message="Signal: SignalSlotClass(_POINTER_) signalWithoutParameters ()" type="info" -->
</testcase>
<testcase result="pass" name="cleanupTestCase">
<!-- message="Signal: QThread(_POINTER_) finished ()" type="info" -->
<!-- message=" Signal: QThread(_POINTER_) finished ()" type="info" -->
</testcase>
<system-err>
<![CDATA[Signal: QThread(_POINTER_) started ()]]>
@ -279,6 +282,7 @@
<![CDATA[Signal: SignalSlotClass(_POINTER_) qVectorPointerConstSignal ()]]>
<![CDATA[Signal: SignalSlotClass(_POINTER_) qVariantSignal (QVariant())]]>
<![CDATA[Signal: SignalSlotClass(_POINTER_) qVariantSignal (QVariant())]]>
<![CDATA[Signal: QThread(_POINTER_) finished ()]]>
<![CDATA[Signal: SignalSlotClass(_POINTER_) signalWithoutParameters ()]]>
<![CDATA[ Signal: QThread(_POINTER_) finished ()]]>
</system-err>
</testsuite>

View File

@ -56,6 +56,8 @@ private slots:
void slotEmittingSignalOldSyntax();
void variousTypes();
void deletingSender();
};
void tst_Signaldumper::addConnectionTypeData()
@ -413,5 +415,14 @@ void tst_Signaldumper::variousTypes()
emit signalSlotOwner.qVariantSignal(variant);
}
void tst_Signaldumper::deletingSender()
{
SignalSlotClass *signalSlotOwner = new SignalSlotClass();
connect(signalSlotOwner, &SignalSlotClass::signalWithoutParameters, [signalSlotOwner]() {
delete signalSlotOwner;
});
emit signalSlotOwner->signalWithoutParameters();
}
QTEST_MAIN(tst_Signaldumper)
#include "tst_signaldumper.moc"