diff --git a/src/plugins/autotest/boost/boosttestoutputreader.cpp b/src/plugins/autotest/boost/boosttestoutputreader.cpp index c4ba9f160b9..ecc93648da9 100644 --- a/src/plugins/autotest/boost/boosttestoutputreader.cpp +++ b/src/plugins/autotest/boost/boosttestoutputreader.cpp @@ -396,6 +396,7 @@ void BoostTestOutputReader::processOutputLine(const QByteArray &outputLine) void BoostTestOutputReader::processStdError(const QByteArray &outputLine) { // we need to process the output, Boost UTF uses both out streams + checkForSanitizerOutput(outputLine); processOutputLine(outputLine); emit newOutputLineAvailable(outputLine, OutputChannel::StdErr); } diff --git a/src/plugins/autotest/gtest/gtestoutputreader.cpp b/src/plugins/autotest/gtest/gtestoutputreader.cpp index 270a297704f..77c0e825e81 100644 --- a/src/plugins/autotest/gtest/gtestoutputreader.cpp +++ b/src/plugins/autotest/gtest/gtestoutputreader.cpp @@ -192,6 +192,7 @@ void GTestOutputReader::processOutputLine(const QByteArray &outputLine) void GTestOutputReader::processStdError(const QByteArray &outputLine) { // we need to process the output, GTest may uses both out streams + checkForSanitizerOutput(outputLine); processOutputLine(outputLine); emit newOutputLineAvailable(outputLine, OutputChannel::StdErr); } diff --git a/src/plugins/autotest/testoutputreader.cpp b/src/plugins/autotest/testoutputreader.cpp index 930f55697db..4974dca44f4 100644 --- a/src/plugins/autotest/testoutputreader.cpp +++ b/src/plugins/autotest/testoutputreader.cpp @@ -27,6 +27,7 @@ #include "testresult.h" #include "testresultspane.h" +#include "testtreeitem.h" #include @@ -66,6 +67,12 @@ TestOutputReader::TestOutputReader(const QFutureInterface &future } } +TestOutputReader::~TestOutputReader() +{ + if (m_sanitizerResult) + sendAndResetSanitizerResult(); +} + void TestOutputReader::processStdOutput(const QByteArray &outputLine) { processOutputLine(outputLine); @@ -74,7 +81,7 @@ void TestOutputReader::processStdOutput(const QByteArray &outputLine) void TestOutputReader::processStdError(const QByteArray &outputLine) { - qWarning() << "AutoTest.Run: Ignored plain output:" << outputLine; + checkForSanitizerOutput(outputLine); emit newOutputLineAvailable(outputLine, OutputChannel::StdErr); } @@ -120,4 +127,43 @@ void TestOutputReader::reportResult(const TestResultPtr &result) m_hadValidOutput = true; } +void TestOutputReader::checkForSanitizerOutput(const QByteArray &line) +{ + const QString lineStr = removeCommandlineColors(QString::fromUtf8(line)); + if (m_sanitizerOutputMode == SanitizerOutputMode::Asan) { + // append the new line and check for end + m_sanitizerLines.append(lineStr); + const QRegularExpression regex("^==\\d+==\\s*ABORTING.*"); + if (regex.match(lineStr).hasMatch()) + sendAndResetSanitizerResult(); + } else { + const QRegularExpression regex("^==\\d+==\\s*(ERROR|WARNING|Sanitizer CHECK failed):.*"); + if (regex.match(lineStr).hasMatch()) { + m_sanitizerOutputMode = SanitizerOutputMode::Asan; + m_sanitizerResult = createDefaultResult(); + m_sanitizerLines.append("Sanitizer Issue"); + m_sanitizerLines.append(lineStr); + } + } +} + +void TestOutputReader::sendAndResetSanitizerResult() +{ + m_sanitizerResult->setDescription(m_sanitizerLines.join('\n')); + m_sanitizerResult->setResult(ResultType::MessageFatal); + + if (m_sanitizerResult->fileName().isEmpty()) { + const TestTreeItem *testItem = m_sanitizerResult->findTestTreeItem(); + if (testItem && testItem->line()) { + m_sanitizerResult->setFileName(testItem->filePath()); + m_sanitizerResult->setLine(testItem->line()); + } + } + + reportResult(m_sanitizerResult); + m_sanitizerLines.clear(); + m_sanitizerResult.reset(); + m_sanitizerOutputMode = SanitizerOutputMode::None; +} + } // namespace Autotest diff --git a/src/plugins/autotest/testoutputreader.h b/src/plugins/autotest/testoutputreader.h index bd065eaf76f..246f00af03f 100644 --- a/src/plugins/autotest/testoutputreader.h +++ b/src/plugins/autotest/testoutputreader.h @@ -40,7 +40,7 @@ class TestOutputReader : public QObject public: TestOutputReader(const QFutureInterface &futureInterface, QProcess *testApplication, const QString &buildDirectory); - + virtual ~TestOutputReader(); void processStdOutput(const QByteArray &outputLine); virtual void processStdError(const QByteArray &outputLine); void reportCrash(); @@ -59,6 +59,8 @@ protected: QString removeCommandlineColors(const QString &original); virtual void processOutputLine(const QByteArray &outputLine) = 0; virtual TestResultPtr createDefaultResult() const = 0; + void checkForSanitizerOutput(const QByteArray &line); + void sendAndResetSanitizerResult(); void reportResult(const TestResultPtr &result); QFutureInterface m_futureInterface; @@ -68,6 +70,10 @@ protected: QHash m_summary; int m_disabled = -1; private: + enum class SanitizerOutputMode { None, Asan}; + TestResultPtr m_sanitizerResult; + QStringList m_sanitizerLines; + SanitizerOutputMode m_sanitizerOutputMode = SanitizerOutputMode::None; bool m_hadValidOutput = false; };