diff --git a/src/plugins/autotest/testoutputreader.cpp b/src/plugins/autotest/testoutputreader.cpp index 3d502d5d393..cade15013b8 100644 --- a/src/plugins/autotest/testoutputreader.cpp +++ b/src/plugins/autotest/testoutputreader.cpp @@ -32,6 +32,8 @@ #include #include +#include +#include #include namespace Autotest { @@ -133,24 +135,50 @@ void TestOutputReader::checkForSanitizerOutput(const QByteArray &line) if (m_sanitizerOutputMode == SanitizerOutputMode::Asan) { // append the new line and check for end m_sanitizerLines.append(lineStr); - const QRegularExpression regex("^==\\d+==\\s*ABORTING.*"); + static const QRegularExpression regex("^==\\d+==\\s*ABORTING.*"); if (regex.match(lineStr).hasMatch()) sendAndResetSanitizerResult(); + return; + } + + static const QRegularExpression regex("^==\\d+==\\s*(ERROR|WARNING|Sanitizer CHECK failed):.*"); + static const QRegularExpression ubsanRegex("^(.*):(\\d+):(\\d+): runtime error:.*"); + QRegularExpressionMatch match = regex.match(lineStr); + SanitizerOutputMode mode = SanitizerOutputMode::None; + if (match.hasMatch()) { + mode = SanitizerOutputMode::Asan; } 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"); + match = ubsanRegex.match(lineStr); + if (m_sanitizerOutputMode == SanitizerOutputMode::Ubsan && !match.hasMatch()) { m_sanitizerLines.append(lineStr); + return; + } + if (match.hasMatch()) + mode = SanitizerOutputMode::Ubsan; + } + if (mode != SanitizerOutputMode::None) { + if (m_sanitizerResult) // we have a result that has not been reported yet + sendAndResetSanitizerResult(); + + m_sanitizerOutputMode = mode; + m_sanitizerResult = createDefaultResult(); + m_sanitizerLines.append("Sanitizer Issue"); + m_sanitizerLines.append(lineStr); + if (m_sanitizerOutputMode == SanitizerOutputMode::Ubsan) { + const QString path = QFileInfo(m_buildDir, match.captured(1)).canonicalFilePath(); + // path may be empty if not existing - so, provide at least what we have + m_sanitizerResult->setFileName(path.isEmpty() ? match.captured(1) : path); + m_sanitizerResult->setLine(match.captured(2).toInt()); } } } void TestOutputReader::sendAndResetSanitizerResult() { + QTC_ASSERT(m_sanitizerResult, return); m_sanitizerResult->setDescription(m_sanitizerLines.join('\n')); - m_sanitizerResult->setResult(ResultType::MessageFatal); + m_sanitizerResult->setResult(m_sanitizerOutputMode == SanitizerOutputMode::Ubsan + ? ResultType::Fail : ResultType::MessageFatal); if (m_sanitizerResult->fileName().isEmpty()) { const ITestTreeItem *testItem = m_sanitizerResult->findTestTreeItem(); diff --git a/src/plugins/autotest/testoutputreader.h b/src/plugins/autotest/testoutputreader.h index 246f00af03f..d4dd5c46983 100644 --- a/src/plugins/autotest/testoutputreader.h +++ b/src/plugins/autotest/testoutputreader.h @@ -70,7 +70,7 @@ protected: QHash m_summary; int m_disabled = -1; private: - enum class SanitizerOutputMode { None, Asan}; + enum class SanitizerOutputMode { None, Asan, Ubsan}; TestResultPtr m_sanitizerResult; QStringList m_sanitizerLines; SanitizerOutputMode m_sanitizerOutputMode = SanitizerOutputMode::None;