Details
Description
Our CI shows infrequent address sanitizer errors when running autotests on Linux. All in the same testcase, presumably triggered by jscommandexecutor and introduced by https://codereview.qt-project.org/c/qbs/qbs/+/267630
Examples:
https://travis-ci.org/rweickelt/qbs/jobs/574510176
FAIL! : TestBlackbox::errorInfo() 'm_qbsStderr.contains("JavaScriptCommand.sourceCode")' returned FALSE. (================================================================= ==7977==ERROR: AddressSanitizer: heap-use-after-free on address 0x607000002518 at pc 0x7fbfcc5f2b29 bp 0x7fbf3e8968a0 sp 0x7fbf3e896898 READ of size 8 at 0x607000002518 thread T5 (QThread) #0 0x7fbfcc5f2b28 in std::enable_if<std::__and_<std::is_move_constructible<QTypedArrayData<unsigned short>*>, std::is_move_assignable<QTypedArrayData<unsigned short>*> >::value, void>::type std::swap<QTypedArrayData<unsigned short>*>(QTypedArrayData<unsigned short>*&, QTypedArrayData<unsigned short>*&) /usr/include/c++/6/bits/move.h:190 #1 0x7fbfcc5f2663 in void qSwap<QTypedArrayData<unsigned short>*>(QTypedArrayData<unsigned short>*&, QTypedArrayData<unsigned short>*&) /opt/Qt/5.12.4/gcc_64/include/QtCore/qglobal.h:915 #2 0x7fbfcc5f1d26 in QString::operator=(QString&&) /opt/Qt/5.12.4/gcc_64/include/QtCore/qstring.h:236 #3 0x7fbfcc8ad958 in qbs::Internal::JsCommandExecuto Loc: [/qbs/tests/auto/blackbox/tst_blackbox.cpp(3469)]
https://travis-ci.org/rweickelt/qbs/jobs/573884069
FAIL! : TestBlackbox::errorInfo() 'm_qbsStderr.contains("JavaScriptCommand.sourceCode")' returned FALSE. (================================================================= ==8390==ERROR: AddressSanitizer: heap-use-after-free on address 0x607000002518 at pc 0x7f17c7236b89 bp 0x7f173c2968b0 sp 0x7f173c2968a8 READ of size 8 at 0x607000002518 thread T5 (QThread) #0 0x7f17c7236b88 in std::enable_if<std::__and_<std::is_move_constructible<QTypedArrayData<unsigned short>*>, std::is_move_assignable<QTypedArrayData<unsigned short>*> >::value, void>::type std::swap<QTypedArrayData<unsigned short>*>(QTypedArrayData<unsigned short>*&, QTypedArrayData<unsigned short>*&) /usr/include/c++/6/bits/move.h:190 #1 0x7f17c72366c3 in void qSwap<QTypedArrayData<unsigned short>*>(QTypedArrayData<unsigned short>*&, QTypedArrayData<unsigned short>*&) /opt/qt5-linux-x86_64/include/QtCore/qglobal.h:915 #2 0x7f17c7235d86 in QString::operator=(QString&&) /opt/qt5-linux-x86_64/include/QtCore/qstring.h:236 #3 0x7f17c74f1082 in qbs::Internal::JsCommandExecuto Loc: [/qbs/tests/auto/blackbox/tst_blackbox.cpp(3469)]
https://travis-ci.org/rweickelt/qbs/jobs/573772618
FAIL! : TestBlackbox::errorInfo() 'm_qbsStderr.contains("JavaScriptCommand.sourceCode")' returned FALSE. (ASAN:DEADLYSIGNAL ================================================================= ==11370==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000000 (pc 0x7fec3c3b72bc bp 0x7febb2587048 sp 0x7febb3596950 T5) #0 0x7fec3c3b72bb in QScriptEngine::isEvaluating() const (/opt/qt5-linux-x86_64/lib/libQt5Script.so.5+0x1bc2bb) #1 0x7fec3c3b7301 in QScriptEngine::abortEvaluation(QScriptValue const&) (/opt/qt5-linux-x86_64/lib/libQt5Script.so.5+0x1bc301) #2 0x7fec3e782079 in qbs::Internal::JsCommandExecutorThreadObject::cancel(qbs::ErrorInfo const&) /qbs/src/lib/corelib/buildgraph/jscommandexecutor.cpp:91 #3 0x7fec3e78086a in operator() /qbs/src/lib/corelib/buildgraph/jscommandexecutor.cpp:250 #4 0x7fec3e781a9c in call /opt/qt5-linux-x86_64/include/QtCore/qobjectdefs_impl.h:128 #5 0x7fec3e781a27 in call<QtPrivate::List<>, void> /opt/qt5-linux-x86_64/include/QtCore/qobjectdefs_impl.h:238 #6 0x7fec3e7819cb in impl Loc: [/qbs/tests/auto/blackbox/tst_blackbox.cpp(3469)]
It looks like the following method triggers the error:
void JsCommandExecutor::cancel(const qbs::ErrorInfo &reason) { if (m_running && !dryRun()) QTimer::singleShot(0, m_objectInThread, [objectInThread = m_objectInThread, reason] { objectInThread->cancel(reason); }); }