2012-10-02 09:12:39 +02:00
|
|
|
/****************************************************************************
|
2011-03-04 12:15:18 +01:00
|
|
|
**
|
2016-01-15 14:55:33 +01:00
|
|
|
** Copyright (C) 2016 The Qt Company Ltd.
|
2011-03-04 12:15:18 +01:00
|
|
|
** Author: Milian Wolff, KDAB (milian.wolff@kdab.com)
|
2016-01-15 14:55:33 +01:00
|
|
|
** Contact: https://www.qt.io/licensing/
|
2011-03-04 12:15:18 +01:00
|
|
|
**
|
2012-10-02 09:12:39 +02:00
|
|
|
** This file is part of Qt Creator.
|
2011-03-04 12:15:18 +01:00
|
|
|
**
|
2012-10-02 09:12:39 +02:00
|
|
|
** Commercial License Usage
|
|
|
|
|
** Licensees holding valid commercial Qt licenses may use this file in
|
|
|
|
|
** accordance with the commercial license agreement provided with the
|
|
|
|
|
** Software or, alternatively, in accordance with the terms contained in
|
2016-01-15 14:55:33 +01:00
|
|
|
** a written agreement between you and The Qt Company. For licensing terms
|
|
|
|
|
** and conditions see https://www.qt.io/terms-conditions. For further
|
|
|
|
|
** information use the contact form at https://www.qt.io/contact-us.
|
2011-03-04 12:15:18 +01:00
|
|
|
**
|
2016-01-15 14:55:33 +01:00
|
|
|
** GNU General Public License Usage
|
|
|
|
|
** Alternatively, this file may be used under the terms of the GNU
|
|
|
|
|
** General Public License version 3 as published by the Free Software
|
|
|
|
|
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
|
|
|
|
** included in the packaging of this file. Please review the following
|
|
|
|
|
** information to ensure the GNU General Public License requirements will
|
|
|
|
|
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
2011-03-04 12:15:18 +01:00
|
|
|
**
|
2012-10-02 09:12:39 +02:00
|
|
|
****************************************************************************/
|
2011-03-04 12:15:18 +01:00
|
|
|
|
2016-12-06 12:05:05 +01:00
|
|
|
#include "valgrindtestrunnertest.h"
|
2011-03-04 12:15:18 +01:00
|
|
|
|
2016-12-06 12:05:05 +01:00
|
|
|
#include "xmlprotocol/frame.h"
|
|
|
|
|
#include "xmlprotocol/stack.h"
|
|
|
|
|
#include "xmlprotocol/suppression.h"
|
|
|
|
|
#include "xmlprotocol/threadedparser.h"
|
|
|
|
|
#include "xmlprotocol/parser.h"
|
2017-06-21 08:08:43 +02:00
|
|
|
#include "valgrindrunner.h"
|
2011-03-04 12:15:18 +01:00
|
|
|
|
2016-12-06 12:05:05 +01:00
|
|
|
#include <projectexplorer/devicesupport/devicemanager.h>
|
2014-05-13 13:50:06 +02:00
|
|
|
#include <projectexplorer/projectexplorer.h>
|
2018-05-16 15:42:03 +02:00
|
|
|
#include <projectexplorer/runconfiguration.h>
|
2014-05-13 13:50:06 +02:00
|
|
|
|
2017-07-04 10:23:15 +02:00
|
|
|
#include <utils/algorithm.h>
|
|
|
|
|
|
2011-03-04 12:15:18 +01:00
|
|
|
#include <QDebug>
|
|
|
|
|
#include <QTest>
|
|
|
|
|
#include <QDir>
|
|
|
|
|
#include <QSignalSpy>
|
|
|
|
|
|
2016-12-06 12:05:05 +01:00
|
|
|
#define HEADER_LENGTH 25
|
2011-03-04 12:15:18 +01:00
|
|
|
|
2019-07-23 08:30:25 +02:00
|
|
|
using namespace ProjectExplorer;
|
2016-12-06 12:05:05 +01:00
|
|
|
using namespace Valgrind::XmlProtocol;
|
2019-07-23 08:30:25 +02:00
|
|
|
using namespace Utils;
|
2016-12-06 12:05:05 +01:00
|
|
|
|
|
|
|
|
namespace Valgrind {
|
|
|
|
|
namespace Test {
|
|
|
|
|
|
|
|
|
|
//BEGIN Test Helpers and boilerplate code
|
2013-04-08 17:26:37 +02:00
|
|
|
|
2016-12-06 12:05:05 +01:00
|
|
|
static const QString appSrcDir(TESTRUNNER_SRC_DIR);
|
|
|
|
|
static const QString appBinDir(TESTRUNNER_APP_DIR);
|
|
|
|
|
|
|
|
|
|
static bool on64bit()
|
2013-04-08 17:26:37 +02:00
|
|
|
{
|
|
|
|
|
return sizeof(char*) == 8;
|
|
|
|
|
}
|
|
|
|
|
|
2016-12-06 12:05:05 +01:00
|
|
|
static QString srcDirForApp(const QString &app)
|
2011-03-04 12:15:18 +01:00
|
|
|
{
|
2018-12-01 20:56:21 +02:00
|
|
|
return QDir::cleanPath(appSrcDir + '/' + app);
|
2011-03-04 12:15:18 +01:00
|
|
|
}
|
|
|
|
|
|
2016-12-06 12:05:05 +01:00
|
|
|
ValgrindTestRunnerTest::ValgrindTestRunnerTest(QObject *parent)
|
|
|
|
|
: QObject(parent)
|
2011-03-04 12:15:18 +01:00
|
|
|
{
|
|
|
|
|
qRegisterMetaType<Error>();
|
|
|
|
|
}
|
|
|
|
|
|
2016-12-06 12:05:05 +01:00
|
|
|
QString ValgrindTestRunnerTest::runTestBinary(const QString &binary, const QStringList &vArgs)
|
2011-03-04 12:15:18 +01:00
|
|
|
{
|
2016-12-06 12:05:05 +01:00
|
|
|
const QFileInfo binPathFileInfo(appBinDir, binary);
|
|
|
|
|
if (!binPathFileInfo.isExecutable())
|
|
|
|
|
return QString();
|
2019-07-23 08:30:25 +02:00
|
|
|
|
|
|
|
|
Runnable debuggee;
|
2016-12-06 12:05:05 +01:00
|
|
|
const QString &binPath = binPathFileInfo.canonicalFilePath();
|
2019-06-20 17:19:12 +02:00
|
|
|
debuggee.executable = Utils::FilePath::fromString(binPath);
|
2016-12-06 12:05:05 +01:00
|
|
|
debuggee.environment = Utils::Environment::systemEnvironment();
|
2019-07-23 08:30:25 +02:00
|
|
|
|
2019-07-23 10:17:57 +02:00
|
|
|
CommandLine valgrind{"valgrind", {"--num-callers=50", "--track-origins=yes"}};
|
2019-07-23 08:30:25 +02:00
|
|
|
valgrind.addArgs(vArgs);
|
|
|
|
|
|
2017-07-04 10:23:15 +02:00
|
|
|
m_runner->setLocalServerAddress(QHostAddress::LocalHost);
|
2019-07-23 08:30:25 +02:00
|
|
|
m_runner->setValgrindCommand(valgrind);
|
2016-01-26 16:11:39 +01:00
|
|
|
m_runner->setDebuggee(debuggee);
|
2019-07-23 08:30:25 +02:00
|
|
|
m_runner->setDevice(DeviceManager::instance()->defaultDevice(
|
|
|
|
|
ProjectExplorer::Constants::DESKTOP_DEVICE_TYPE));
|
2011-03-04 12:15:18 +01:00
|
|
|
m_runner->start();
|
|
|
|
|
m_runner->waitForFinished();
|
|
|
|
|
return binPath;
|
|
|
|
|
}
|
|
|
|
|
|
2016-12-06 12:05:05 +01:00
|
|
|
void ValgrindTestRunnerTest::logMessageReceived(const QByteArray &message)
|
2011-03-04 12:15:18 +01:00
|
|
|
{
|
|
|
|
|
qDebug() << "log message received:" << message;
|
|
|
|
|
m_logMessages << message;
|
|
|
|
|
}
|
|
|
|
|
|
2016-12-06 12:05:05 +01:00
|
|
|
void ValgrindTestRunnerTest::internalError(const QString &error)
|
2011-03-04 12:15:18 +01:00
|
|
|
{
|
|
|
|
|
if (!m_expectCrash)
|
|
|
|
|
QFAIL(qPrintable(error));
|
|
|
|
|
else
|
|
|
|
|
qDebug() << "expected crash:" << error;
|
|
|
|
|
}
|
|
|
|
|
|
2016-12-06 12:05:05 +01:00
|
|
|
void ValgrindTestRunnerTest::error(const Error &error)
|
2011-03-04 12:15:18 +01:00
|
|
|
{
|
|
|
|
|
m_errors << error;
|
|
|
|
|
}
|
|
|
|
|
|
2016-12-06 12:05:05 +01:00
|
|
|
void ValgrindTestRunnerTest::cleanup()
|
2011-03-04 12:15:18 +01:00
|
|
|
{
|
|
|
|
|
Q_ASSERT(m_runner);
|
|
|
|
|
delete m_runner;
|
2018-12-10 08:11:18 +01:00
|
|
|
m_runner = nullptr;
|
2011-03-04 12:15:18 +01:00
|
|
|
|
|
|
|
|
m_logMessages.clear();
|
|
|
|
|
m_errors.clear();
|
|
|
|
|
m_expectCrash = false;
|
|
|
|
|
}
|
|
|
|
|
|
2016-12-06 12:05:05 +01:00
|
|
|
void ValgrindTestRunnerTest::init()
|
2011-03-04 12:15:18 +01:00
|
|
|
{
|
2016-12-06 12:05:05 +01:00
|
|
|
const Utils::Environment &sysEnv = Utils::Environment::systemEnvironment();
|
|
|
|
|
auto fileName = sysEnv.searchInPath("valgrind");
|
|
|
|
|
if (fileName.isEmpty())
|
|
|
|
|
QSKIP("This test needs valgrind in PATH");
|
2011-03-04 12:15:18 +01:00
|
|
|
Q_ASSERT(m_logMessages.isEmpty());
|
|
|
|
|
|
|
|
|
|
Q_ASSERT(!m_runner);
|
2017-06-21 08:08:43 +02:00
|
|
|
m_runner = new ValgrindRunner;
|
2011-03-04 12:15:18 +01:00
|
|
|
m_runner->setProcessChannelMode(QProcess::ForwardedChannels);
|
2017-06-21 08:08:43 +02:00
|
|
|
connect(m_runner, &ValgrindRunner::logMessageReceived,
|
2016-12-06 12:05:05 +01:00
|
|
|
this, &ValgrindTestRunnerTest::logMessageReceived);
|
2015-06-09 10:56:57 +02:00
|
|
|
connect(m_runner, &ValgrindRunner::processErrorReceived,
|
2016-12-06 12:05:05 +01:00
|
|
|
this, &ValgrindTestRunnerTest::internalError);
|
2017-06-21 09:01:48 +02:00
|
|
|
connect(m_runner->parser(), &ThreadedParser::internalError,
|
2016-12-06 12:05:05 +01:00
|
|
|
this, &ValgrindTestRunnerTest::internalError);
|
2017-06-21 09:01:48 +02:00
|
|
|
connect(m_runner->parser(), &ThreadedParser::error,
|
2016-12-06 12:05:05 +01:00
|
|
|
this, &ValgrindTestRunnerTest::error);
|
2011-03-04 12:15:18 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//BEGIN: Actual test cases
|
|
|
|
|
|
2016-12-06 12:05:05 +01:00
|
|
|
void ValgrindTestRunnerTest::testLeak1()
|
2011-03-04 12:15:18 +01:00
|
|
|
{
|
2018-12-01 20:56:21 +02:00
|
|
|
const QString binary = runTestBinary("leak1/leak1");
|
2016-12-06 12:05:05 +01:00
|
|
|
if (binary.isEmpty())
|
|
|
|
|
QSKIP("You need to pass BUILD_TESTS when building Qt Creator or build valgrind testapps "
|
|
|
|
|
"manually before executing this test.");
|
2011-03-04 12:15:18 +01:00
|
|
|
|
|
|
|
|
QVERIFY(m_logMessages.isEmpty());
|
|
|
|
|
|
|
|
|
|
QCOMPARE(m_errors.count(), 1);
|
|
|
|
|
const Error error = m_errors.first();
|
|
|
|
|
QCOMPARE(error.kind(), int(Leak_DefinitelyLost));
|
|
|
|
|
QCOMPARE(error.leakedBlocks(), qint64(1));
|
|
|
|
|
QCOMPARE(error.leakedBytes(), quint64(8));
|
|
|
|
|
QCOMPARE(error.stacks().count(), 1);
|
2019-01-30 20:54:57 +01:00
|
|
|
const Stack stack = error.stacks().constFirst();
|
2011-03-04 12:15:18 +01:00
|
|
|
QCOMPARE(stack.line(), qint64(-1));
|
|
|
|
|
QCOMPARE(stack.frames().count(), 2);
|
|
|
|
|
{
|
|
|
|
|
const Frame frame = stack.frames().at(0);
|
2013-04-08 17:26:37 +02:00
|
|
|
if (on64bit())
|
2018-12-03 15:30:51 +01:00
|
|
|
QCOMPARE(frame.functionName(), QString("operator new(unsigned long)"));
|
2013-04-08 17:26:37 +02:00
|
|
|
else
|
2018-12-03 15:30:51 +01:00
|
|
|
QCOMPARE(frame.functionName(), QString("operator new(unsigned int)"));
|
2011-03-04 12:15:18 +01:00
|
|
|
}
|
|
|
|
|
{
|
|
|
|
|
const Frame frame = stack.frames().at(1);
|
2018-12-03 15:30:51 +01:00
|
|
|
QCOMPARE(frame.functionName(), QString("main"));
|
2013-04-08 17:26:37 +02:00
|
|
|
QCOMPARE(frame.line(), 5 + HEADER_LENGTH);
|
2011-03-04 12:15:18 +01:00
|
|
|
|
|
|
|
|
QCOMPARE(frame.object(), binary);
|
2018-12-03 15:30:51 +01:00
|
|
|
QCOMPARE(frame.fileName(), QString("main.cpp"));
|
2011-03-04 12:15:18 +01:00
|
|
|
QCOMPARE(QDir::cleanPath(frame.directory()), srcDirForApp("leak1"));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-12-06 12:05:05 +01:00
|
|
|
void ValgrindTestRunnerTest::testLeak2()
|
2011-03-04 12:15:18 +01:00
|
|
|
{
|
2018-12-01 20:56:21 +02:00
|
|
|
const QString binary = runTestBinary("leak2/leak2");
|
2016-12-06 12:05:05 +01:00
|
|
|
if (binary.isEmpty())
|
|
|
|
|
QSKIP("You need to pass BUILD_TESTS when building Qt Creator or build valgrind testapps "
|
|
|
|
|
"manually before executing this test.");
|
2011-03-04 12:15:18 +01:00
|
|
|
|
|
|
|
|
QVERIFY(m_logMessages.isEmpty());
|
|
|
|
|
QCOMPARE(m_errors.count(), 1);
|
|
|
|
|
const Error error = m_errors.first();
|
|
|
|
|
QCOMPARE(error.kind(), int(Leak_PossiblyLost));
|
|
|
|
|
QCOMPARE(error.leakedBlocks(), qint64(1));
|
|
|
|
|
QCOMPARE(error.leakedBytes(), quint64(5));
|
|
|
|
|
QCOMPARE(error.stacks().count(), 1);
|
2019-01-30 20:54:57 +01:00
|
|
|
const Stack stack = error.stacks().constFirst();
|
2011-03-04 12:15:18 +01:00
|
|
|
QCOMPARE(stack.line(), qint64(-1));
|
|
|
|
|
QCOMPARE(stack.frames().count(), 3);
|
|
|
|
|
{
|
|
|
|
|
const Frame frame = stack.frames().at(0);
|
2018-12-03 15:30:51 +01:00
|
|
|
QCOMPARE(frame.functionName(), QString("malloc"));
|
2011-03-04 12:15:18 +01:00
|
|
|
}
|
|
|
|
|
{
|
|
|
|
|
const Frame frame = stack.frames().at(1);
|
2018-12-03 15:30:51 +01:00
|
|
|
QCOMPARE(frame.functionName(), QString("strdup"));
|
2011-03-04 12:15:18 +01:00
|
|
|
}
|
|
|
|
|
{
|
|
|
|
|
const Frame frame = stack.frames().at(2);
|
2013-04-08 17:26:37 +02:00
|
|
|
if (on64bit()) {
|
2018-12-03 15:30:51 +01:00
|
|
|
QCOMPARE(frame.functionName(), QString("main"));
|
2013-04-08 17:26:37 +02:00
|
|
|
QCOMPARE(frame.line(), 7 + HEADER_LENGTH);
|
2011-03-04 12:15:18 +01:00
|
|
|
|
2013-04-08 17:26:37 +02:00
|
|
|
QCOMPARE(frame.object(), binary);
|
2018-12-03 15:30:51 +01:00
|
|
|
QCOMPARE(frame.fileName(), QString("main.cpp"));
|
2013-04-08 17:26:37 +02:00
|
|
|
QCOMPARE(QDir::cleanPath(frame.directory()), srcDirForApp("leak2"));
|
|
|
|
|
} else {
|
2018-12-03 15:30:51 +01:00
|
|
|
QCOMPARE(frame.functionName(), QString("(below main)"));
|
2013-04-08 17:26:37 +02:00
|
|
|
}
|
2011-03-04 12:15:18 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-12-06 12:05:05 +01:00
|
|
|
void ValgrindTestRunnerTest::testLeak3()
|
2011-03-04 12:15:18 +01:00
|
|
|
{
|
2018-12-01 20:56:21 +02:00
|
|
|
const QString binary = runTestBinary("leak3/leak3", QStringList{"--show-reachable=yes"});
|
2016-12-06 12:05:05 +01:00
|
|
|
if (binary.isEmpty())
|
|
|
|
|
QSKIP("You need to pass BUILD_TESTS when building Qt Creator or build valgrind testapps "
|
|
|
|
|
"manually before executing this test.");
|
2011-03-04 12:15:18 +01:00
|
|
|
QVERIFY(m_logMessages.isEmpty());
|
|
|
|
|
|
|
|
|
|
QCOMPARE(m_errors.count(), 1);
|
|
|
|
|
const Error error = m_errors.first();
|
|
|
|
|
QCOMPARE(error.kind(), int(Leak_StillReachable));
|
|
|
|
|
QCOMPARE(error.leakedBlocks(), qint64(1));
|
|
|
|
|
QCOMPARE(error.leakedBytes(), quint64(5));
|
|
|
|
|
QCOMPARE(error.stacks().count(), 1);
|
2019-01-30 20:54:57 +01:00
|
|
|
const Stack stack = error.stacks().constFirst();
|
2011-03-04 12:15:18 +01:00
|
|
|
QCOMPARE(stack.line(), qint64(-1));
|
|
|
|
|
QCOMPARE(stack.frames().count(), 3);
|
|
|
|
|
{
|
|
|
|
|
const Frame frame = stack.frames().at(0);
|
2018-12-03 15:30:51 +01:00
|
|
|
QCOMPARE(frame.functionName(), QString("malloc"));
|
2011-03-04 12:15:18 +01:00
|
|
|
}
|
|
|
|
|
{
|
|
|
|
|
const Frame frame = stack.frames().at(1);
|
2018-12-03 15:30:51 +01:00
|
|
|
QCOMPARE(frame.functionName(), QString("strdup"));
|
2011-03-04 12:15:18 +01:00
|
|
|
}
|
|
|
|
|
{
|
|
|
|
|
const Frame frame = stack.frames().at(2);
|
2013-04-08 17:26:37 +02:00
|
|
|
if (on64bit()) {
|
2018-12-03 15:30:51 +01:00
|
|
|
QCOMPARE(frame.functionName(), QString("main"));
|
2013-04-08 17:26:37 +02:00
|
|
|
QCOMPARE(frame.line(), 7 + HEADER_LENGTH);
|
2011-03-04 12:15:18 +01:00
|
|
|
|
2013-04-08 17:26:37 +02:00
|
|
|
QCOMPARE(frame.object(), binary);
|
2018-12-03 15:30:51 +01:00
|
|
|
QCOMPARE(frame.fileName(), QString("main.cpp"));
|
2013-04-08 17:26:37 +02:00
|
|
|
QCOMPARE(QDir::cleanPath(frame.directory()), srcDirForApp("leak3"));
|
|
|
|
|
} else {
|
2018-12-03 15:30:51 +01:00
|
|
|
QCOMPARE(frame.functionName(), QString("(below main)"));
|
2013-04-08 17:26:37 +02:00
|
|
|
}
|
2011-03-04 12:15:18 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-12-06 12:05:05 +01:00
|
|
|
void ValgrindTestRunnerTest::testLeak4()
|
2011-03-04 12:15:18 +01:00
|
|
|
{
|
|
|
|
|
const QString app("leak4");
|
2018-12-01 20:56:21 +02:00
|
|
|
const QString binary = runTestBinary(app + '/' + app,
|
2011-03-04 12:15:18 +01:00
|
|
|
QStringList() << "--show-reachable=yes");
|
2016-12-06 12:05:05 +01:00
|
|
|
if (binary.isEmpty())
|
|
|
|
|
QSKIP("You need to pass BUILD_TESTS when building Qt Creator or build valgrind testapps "
|
|
|
|
|
"manually before executing this test.");
|
2011-03-04 12:15:18 +01:00
|
|
|
const QString srcDir = srcDirForApp("leak4");
|
|
|
|
|
|
|
|
|
|
QVERIFY(m_logMessages.isEmpty());
|
|
|
|
|
|
2017-07-04 10:23:15 +02:00
|
|
|
QVERIFY(m_errors.count() >= 3);
|
2011-03-04 12:15:18 +01:00
|
|
|
//BEGIN first error
|
|
|
|
|
{
|
2017-07-04 10:23:15 +02:00
|
|
|
// depending on the valgrind version the errors can be different - try to find the correct one
|
|
|
|
|
const Error error = Utils::findOrDefault(m_errors, [](const Error &err) {
|
|
|
|
|
return err.kind() == Leak_IndirectlyLost;
|
|
|
|
|
});
|
|
|
|
|
|
2011-03-04 12:15:18 +01:00
|
|
|
QCOMPARE(error.leakedBlocks(), qint64(1));
|
|
|
|
|
QCOMPARE(error.leakedBytes(), quint64(8));
|
|
|
|
|
QCOMPARE(error.stacks().count(), 1);
|
2019-01-30 20:54:57 +01:00
|
|
|
const Stack stack = error.stacks().constFirst();
|
2011-03-04 12:15:18 +01:00
|
|
|
QCOMPARE(stack.line(), qint64(-1));
|
|
|
|
|
QCOMPARE(stack.frames().count(), 3);
|
|
|
|
|
{
|
|
|
|
|
const Frame frame = stack.frames().at(0);
|
2013-04-08 17:26:37 +02:00
|
|
|
if (on64bit())
|
2018-12-03 15:30:51 +01:00
|
|
|
QCOMPARE(frame.functionName(), QString("operator new(unsigned long)"));
|
2013-04-08 17:26:37 +02:00
|
|
|
else
|
2018-12-03 15:30:51 +01:00
|
|
|
QCOMPARE(frame.functionName(), QString("operator new(unsigned int)"));
|
2011-03-04 12:15:18 +01:00
|
|
|
}
|
|
|
|
|
{
|
|
|
|
|
const Frame frame = stack.frames().at(1);
|
2018-12-03 15:30:51 +01:00
|
|
|
QCOMPARE(frame.functionName(), QString("Foo::Foo()"));
|
2013-04-08 17:26:37 +02:00
|
|
|
QCOMPARE(frame.line(), 6 + HEADER_LENGTH);
|
2011-03-04 12:15:18 +01:00
|
|
|
|
|
|
|
|
QCOMPARE(frame.object(), binary);
|
2018-12-03 15:30:51 +01:00
|
|
|
QCOMPARE(frame.fileName(), QString("main.cpp"));
|
2011-03-04 12:15:18 +01:00
|
|
|
QCOMPARE(QDir::cleanPath(frame.directory()), srcDir);
|
|
|
|
|
}
|
|
|
|
|
{
|
|
|
|
|
const Frame frame = stack.frames().at(2);
|
2018-12-03 15:30:51 +01:00
|
|
|
QCOMPARE(frame.functionName(), QString("main"));
|
2013-04-08 17:26:37 +02:00
|
|
|
QCOMPARE(frame.line(), 14 + HEADER_LENGTH);
|
2011-03-04 12:15:18 +01:00
|
|
|
|
|
|
|
|
QCOMPARE(frame.object(), binary);
|
2018-12-03 15:30:51 +01:00
|
|
|
QCOMPARE(frame.fileName(), QString("main.cpp"));
|
2011-03-04 12:15:18 +01:00
|
|
|
QCOMPARE(QDir::cleanPath(frame.directory()), srcDir);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
//BEGIN second error
|
|
|
|
|
{
|
2017-07-04 10:23:15 +02:00
|
|
|
const Error error = Utils::findOrDefault(m_errors, [](const Error &err) {
|
|
|
|
|
return err.kind() == Leak_DefinitelyLost;
|
|
|
|
|
});
|
|
|
|
|
|
2011-03-04 12:15:18 +01:00
|
|
|
QCOMPARE(error.leakedBlocks(), qint64(1));
|
2013-04-08 17:26:37 +02:00
|
|
|
if (on64bit())
|
|
|
|
|
QCOMPARE(error.leakedBytes(), quint64(16));
|
|
|
|
|
else
|
|
|
|
|
QCOMPARE(error.leakedBytes(), quint64(12));
|
2011-03-04 12:15:18 +01:00
|
|
|
QCOMPARE(error.stacks().count(), 1);
|
2019-01-30 20:54:57 +01:00
|
|
|
const Stack stack = error.stacks().constFirst();
|
2011-03-04 12:15:18 +01:00
|
|
|
QCOMPARE(stack.line(), qint64(-1));
|
|
|
|
|
QCOMPARE(stack.frames().count(), 2);
|
|
|
|
|
{
|
|
|
|
|
const Frame frame = stack.frames().at(0);
|
2013-04-08 17:26:37 +02:00
|
|
|
if (on64bit())
|
2018-12-03 15:30:51 +01:00
|
|
|
QCOMPARE(frame.functionName(), QString("operator new(unsigned long)"));
|
2013-04-08 17:26:37 +02:00
|
|
|
else
|
2018-12-03 15:30:51 +01:00
|
|
|
QCOMPARE(frame.functionName(), QString("operator new(unsigned int)"));
|
2011-03-04 12:15:18 +01:00
|
|
|
}
|
|
|
|
|
{
|
|
|
|
|
const Frame frame = stack.frames().at(1);
|
2018-12-03 15:30:51 +01:00
|
|
|
QCOMPARE(frame.functionName(), QString("main"));
|
2013-04-08 17:26:37 +02:00
|
|
|
QCOMPARE(frame.line(), 14 + HEADER_LENGTH);
|
2011-03-04 12:15:18 +01:00
|
|
|
|
|
|
|
|
QCOMPARE(frame.object(), binary);
|
2018-12-03 15:30:51 +01:00
|
|
|
QCOMPARE(frame.fileName(), QString("main.cpp"));
|
2011-03-04 12:15:18 +01:00
|
|
|
QCOMPARE(QDir::cleanPath(frame.directory()), srcDir);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-12-06 12:05:05 +01:00
|
|
|
void ValgrindTestRunnerTest::testUninit1()
|
2011-03-04 12:15:18 +01:00
|
|
|
{
|
|
|
|
|
const QString app("uninit1");
|
2018-12-01 20:56:21 +02:00
|
|
|
const QString binary = runTestBinary(app + '/' + app);
|
2016-12-06 12:05:05 +01:00
|
|
|
if (binary.isEmpty())
|
|
|
|
|
QSKIP("You need to pass BUILD_TESTS when building Qt Creator or build valgrind testapps "
|
|
|
|
|
"manually before executing this test.");
|
2011-03-04 12:15:18 +01:00
|
|
|
const QString srcDir = srcDirForApp(app);
|
|
|
|
|
|
|
|
|
|
QVERIFY(m_logMessages.isEmpty());
|
|
|
|
|
|
|
|
|
|
QCOMPARE(m_errors.count(), 1);
|
|
|
|
|
const Error error = m_errors.first();
|
|
|
|
|
QCOMPARE(error.kind(), int(UninitCondition));
|
|
|
|
|
QCOMPARE(error.stacks().count(), 2);
|
|
|
|
|
//BEGIN first stack
|
|
|
|
|
{
|
2019-01-30 20:54:57 +01:00
|
|
|
const Stack stack = error.stacks().constFirst();
|
2011-03-04 12:15:18 +01:00
|
|
|
QCOMPARE(stack.line(), qint64(-1));
|
|
|
|
|
QCOMPARE(stack.frames().count(), 1);
|
|
|
|
|
|
2019-01-30 20:54:57 +01:00
|
|
|
const Frame frame = stack.frames().constFirst();
|
2018-12-03 15:30:51 +01:00
|
|
|
QCOMPARE(frame.functionName(), QString("main"));
|
2015-01-21 13:46:17 +01:00
|
|
|
QCOMPARE(frame.line(), 4 + HEADER_LENGTH);
|
2011-03-04 12:15:18 +01:00
|
|
|
|
|
|
|
|
QCOMPARE(frame.object(), binary);
|
2018-12-03 15:30:51 +01:00
|
|
|
QCOMPARE(frame.fileName(), QString("main.cpp"));
|
2011-03-04 12:15:18 +01:00
|
|
|
QCOMPARE(QDir::cleanPath(frame.directory()), srcDir);
|
|
|
|
|
}
|
|
|
|
|
//BEGIN second stack
|
|
|
|
|
{
|
2019-01-30 20:54:57 +01:00
|
|
|
const Stack stack = error.stacks().constLast();
|
2011-03-04 12:15:18 +01:00
|
|
|
QCOMPARE(stack.line(), qint64(-1));
|
|
|
|
|
QCOMPARE(stack.frames().count(), 1);
|
|
|
|
|
|
2019-01-30 20:54:57 +01:00
|
|
|
const Frame frame = stack.frames().constFirst();
|
2018-12-03 15:30:51 +01:00
|
|
|
QCOMPARE(frame.functionName(), QString("main"));
|
2015-01-21 13:46:17 +01:00
|
|
|
QCOMPARE(frame.line(), 2 + HEADER_LENGTH);
|
2011-03-04 12:15:18 +01:00
|
|
|
|
|
|
|
|
QCOMPARE(frame.object(), binary);
|
2018-12-03 15:30:51 +01:00
|
|
|
QCOMPARE(frame.fileName(), QString("main.cpp"));
|
2011-03-04 12:15:18 +01:00
|
|
|
QCOMPARE(QDir::cleanPath(frame.directory()), srcDir);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-12-06 12:05:05 +01:00
|
|
|
void ValgrindTestRunnerTest::testUninit2()
|
2011-03-04 12:15:18 +01:00
|
|
|
{
|
|
|
|
|
const QString app("uninit2");
|
|
|
|
|
m_expectCrash = true;
|
2018-12-01 20:56:21 +02:00
|
|
|
const QString binary = runTestBinary(app + '/' + app);
|
2016-12-06 12:05:05 +01:00
|
|
|
if (binary.isEmpty())
|
|
|
|
|
QSKIP("You need to pass BUILD_TESTS when building Qt Creator or build valgrind testapps "
|
|
|
|
|
"manually before executing this test.");
|
2011-03-04 12:15:18 +01:00
|
|
|
const QString srcDir = srcDirForApp(app);
|
|
|
|
|
|
2020-07-27 13:51:20 +02:00
|
|
|
QVERIFY(m_logMessages.size() < 2);
|
|
|
|
|
if (!m_logMessages.isEmpty()) {
|
|
|
|
|
QVERIFY2(m_logMessages.first().contains("If you believe"),
|
|
|
|
|
m_logMessages.first().constData());
|
|
|
|
|
}
|
2011-03-04 12:15:18 +01:00
|
|
|
|
|
|
|
|
QCOMPARE(m_errors.count(), 2);
|
|
|
|
|
//BEGIN first error
|
|
|
|
|
{
|
|
|
|
|
const Error error = m_errors.first();
|
|
|
|
|
QCOMPARE(error.kind(), int(UninitValue));
|
|
|
|
|
QCOMPARE(error.stacks().count(), 2);
|
|
|
|
|
//BEGIN first stack
|
|
|
|
|
{
|
2019-01-30 20:54:57 +01:00
|
|
|
const Stack stack = error.stacks().constFirst();
|
2011-03-04 12:15:18 +01:00
|
|
|
QCOMPARE(stack.line(), qint64(-1));
|
|
|
|
|
QCOMPARE(stack.frames().count(), 1);
|
|
|
|
|
|
2019-01-30 20:54:57 +01:00
|
|
|
const Frame frame = stack.frames().constFirst();
|
2018-12-03 15:30:51 +01:00
|
|
|
QCOMPARE(frame.functionName(), QString("main"));
|
2015-01-21 13:46:17 +01:00
|
|
|
QCOMPARE(frame.line(), 4 + HEADER_LENGTH);
|
2011-03-04 12:15:18 +01:00
|
|
|
|
|
|
|
|
QCOMPARE(frame.object(), binary);
|
2018-12-03 15:30:51 +01:00
|
|
|
QCOMPARE(frame.fileName(), QString("main.cpp"));
|
2011-03-04 12:15:18 +01:00
|
|
|
QCOMPARE(QDir::cleanPath(frame.directory()), srcDir);
|
|
|
|
|
}
|
|
|
|
|
//BEGIN second stack
|
|
|
|
|
{
|
2019-01-30 20:54:57 +01:00
|
|
|
const Stack stack = error.stacks().constLast();
|
2011-03-04 12:15:18 +01:00
|
|
|
QCOMPARE(stack.line(), qint64(-1));
|
|
|
|
|
QCOMPARE(stack.frames().count(), 1);
|
|
|
|
|
|
2019-01-30 20:54:57 +01:00
|
|
|
const Frame frame = stack.frames().constFirst();
|
2018-12-03 15:30:51 +01:00
|
|
|
QCOMPARE(frame.functionName(), QString("main"));
|
2015-01-21 13:46:17 +01:00
|
|
|
QCOMPARE(frame.line(), 2 + HEADER_LENGTH);
|
2011-03-04 12:15:18 +01:00
|
|
|
|
|
|
|
|
QCOMPARE(frame.object(), binary);
|
2018-12-03 15:30:51 +01:00
|
|
|
QCOMPARE(frame.fileName(), QString("main.cpp"));
|
2011-03-04 12:15:18 +01:00
|
|
|
QCOMPARE(QDir::cleanPath(frame.directory()), srcDir);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
//BEGIN second error
|
|
|
|
|
{
|
|
|
|
|
const Error error = m_errors.last();
|
|
|
|
|
QCOMPARE(error.kind(), int(InvalidWrite));
|
|
|
|
|
QCOMPARE(error.stacks().count(), 1);
|
|
|
|
|
|
2019-01-30 20:54:57 +01:00
|
|
|
const Stack stack = error.stacks().constFirst();
|
2011-03-04 12:15:18 +01:00
|
|
|
QCOMPARE(stack.line(), qint64(-1));
|
|
|
|
|
QCOMPARE(stack.frames().count(), 1);
|
|
|
|
|
|
2019-01-30 20:54:57 +01:00
|
|
|
const Frame frame = stack.frames().constFirst();
|
2018-12-03 15:30:51 +01:00
|
|
|
QCOMPARE(frame.functionName(), QString("main"));
|
2015-01-21 13:46:17 +01:00
|
|
|
QCOMPARE(frame.line(), 4 + HEADER_LENGTH);
|
2011-03-04 12:15:18 +01:00
|
|
|
|
|
|
|
|
QCOMPARE(frame.object(), binary);
|
2018-12-03 15:30:51 +01:00
|
|
|
QCOMPARE(frame.fileName(), QString("main.cpp"));
|
2011-03-04 12:15:18 +01:00
|
|
|
QCOMPARE(QDir::cleanPath(frame.directory()), srcDir);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-12-06 12:05:05 +01:00
|
|
|
void ValgrindTestRunnerTest::testUninit3()
|
2011-03-04 12:15:18 +01:00
|
|
|
{
|
|
|
|
|
const QString app("uninit3");
|
|
|
|
|
m_expectCrash = true;
|
2018-12-01 20:56:21 +02:00
|
|
|
const QString binary = runTestBinary(app + '/' + app);
|
2016-12-06 12:05:05 +01:00
|
|
|
if (binary.isEmpty())
|
|
|
|
|
QSKIP("You need to pass BUILD_TESTS when building Qt Creator or build valgrind testapps "
|
|
|
|
|
"manually before executing this test.");
|
2011-03-04 12:15:18 +01:00
|
|
|
const QString srcDir = srcDirForApp(app);
|
|
|
|
|
|
2020-07-27 13:51:20 +02:00
|
|
|
QVERIFY(m_logMessages.size() < 2);
|
|
|
|
|
if (!m_logMessages.isEmpty()) {
|
|
|
|
|
QVERIFY2(m_logMessages.first().contains("If you believe"),
|
|
|
|
|
m_logMessages.first().constData());
|
|
|
|
|
}
|
2011-03-04 12:15:18 +01:00
|
|
|
|
|
|
|
|
QCOMPARE(m_errors.count(), 2);
|
|
|
|
|
//BEGIN first error
|
|
|
|
|
{
|
|
|
|
|
const Error error = m_errors.first();
|
|
|
|
|
QCOMPARE(error.kind(), int(UninitValue));
|
|
|
|
|
QCOMPARE(error.stacks().count(), 2);
|
|
|
|
|
//BEGIN first stack
|
|
|
|
|
{
|
2019-01-30 20:54:57 +01:00
|
|
|
const Stack stack = error.stacks().constFirst();
|
2011-03-04 12:15:18 +01:00
|
|
|
QCOMPARE(stack.line(), qint64(-1));
|
|
|
|
|
QCOMPARE(stack.frames().count(), 1);
|
|
|
|
|
|
2019-01-30 20:54:57 +01:00
|
|
|
const Frame frame = stack.frames().constFirst();
|
2018-12-03 15:30:51 +01:00
|
|
|
QCOMPARE(frame.functionName(), QString("main"));
|
2015-01-21 13:46:17 +01:00
|
|
|
QCOMPARE(frame.line(), 4 + HEADER_LENGTH);
|
2011-03-04 12:15:18 +01:00
|
|
|
|
|
|
|
|
QCOMPARE(frame.object(), binary);
|
2018-12-03 15:30:51 +01:00
|
|
|
QCOMPARE(frame.fileName(), QString("main.cpp"));
|
2011-03-04 12:15:18 +01:00
|
|
|
QCOMPARE(QDir::cleanPath(frame.directory()), srcDir);
|
|
|
|
|
}
|
|
|
|
|
//BEGIN second stack
|
|
|
|
|
{
|
2019-01-30 20:54:57 +01:00
|
|
|
const Stack stack = error.stacks().constLast();
|
2011-03-04 12:15:18 +01:00
|
|
|
QCOMPARE(stack.line(), qint64(-1));
|
|
|
|
|
QCOMPARE(stack.frames().count(), 1);
|
|
|
|
|
|
2019-01-30 20:54:57 +01:00
|
|
|
const Frame frame = stack.frames().constFirst();
|
2018-12-03 15:30:51 +01:00
|
|
|
QCOMPARE(frame.functionName(), QString("main"));
|
2015-01-21 13:46:17 +01:00
|
|
|
QCOMPARE(frame.line(), 2 + HEADER_LENGTH);
|
2011-03-04 12:15:18 +01:00
|
|
|
|
|
|
|
|
QCOMPARE(frame.object(), binary);
|
2018-12-03 15:30:51 +01:00
|
|
|
QCOMPARE(frame.fileName(), QString("main.cpp"));
|
2011-03-04 12:15:18 +01:00
|
|
|
QCOMPARE(QDir::cleanPath(frame.directory()), srcDir);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
//BEGIN second error
|
|
|
|
|
{
|
|
|
|
|
const Error error = m_errors.last();
|
|
|
|
|
QCOMPARE(error.kind(), int(InvalidRead));
|
|
|
|
|
QCOMPARE(error.stacks().count(), 1);
|
|
|
|
|
|
2019-01-30 20:54:57 +01:00
|
|
|
const Stack stack = error.stacks().constFirst();
|
2011-03-04 12:15:18 +01:00
|
|
|
QCOMPARE(stack.line(), qint64(-1));
|
|
|
|
|
QCOMPARE(stack.frames().count(), 1);
|
|
|
|
|
|
2019-01-30 20:54:57 +01:00
|
|
|
const Frame frame = stack.frames().constFirst();
|
2018-12-03 15:30:51 +01:00
|
|
|
QCOMPARE(frame.functionName(), QString("main"));
|
2015-01-21 13:46:17 +01:00
|
|
|
QCOMPARE(frame.line(), 4 + HEADER_LENGTH);
|
2011-03-04 12:15:18 +01:00
|
|
|
|
|
|
|
|
QCOMPARE(frame.object(), binary);
|
2018-12-03 15:30:51 +01:00
|
|
|
QCOMPARE(frame.fileName(), QString("main.cpp"));
|
2011-03-04 12:15:18 +01:00
|
|
|
QCOMPARE(QDir::cleanPath(frame.directory()), srcDir);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-12-06 12:05:05 +01:00
|
|
|
void ValgrindTestRunnerTest::testSyscall()
|
2011-03-04 12:15:18 +01:00
|
|
|
{
|
|
|
|
|
const QString app("syscall");
|
2018-12-01 20:56:21 +02:00
|
|
|
const QString binary = runTestBinary(app + '/' + app);
|
2016-12-06 12:05:05 +01:00
|
|
|
if (binary.isEmpty())
|
|
|
|
|
QSKIP("You need to pass BUILD_TESTS when building Qt Creator or build valgrind testapps "
|
|
|
|
|
"manually before executing this test.");
|
2011-03-04 12:15:18 +01:00
|
|
|
const QString srcDir = srcDirForApp(app);
|
|
|
|
|
|
|
|
|
|
QVERIFY(m_logMessages.isEmpty());
|
|
|
|
|
|
|
|
|
|
QCOMPARE(m_errors.count(), 1);
|
|
|
|
|
const Error error = m_errors.first();
|
|
|
|
|
QCOMPARE(error.kind(), int(SyscallParam));
|
|
|
|
|
QCOMPARE(error.stacks().count(), 2);
|
|
|
|
|
//BEGIN first stack
|
|
|
|
|
{
|
2019-01-30 20:54:57 +01:00
|
|
|
const Stack stack = error.stacks().constFirst();
|
2011-03-04 12:15:18 +01:00
|
|
|
QCOMPARE(stack.line(), qint64(-1));
|
2013-04-08 17:26:37 +02:00
|
|
|
if (on64bit()) {
|
|
|
|
|
QCOMPARE(stack.frames().count(), 4);
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
const Frame frame = stack.frames().at(0);
|
2018-12-03 15:30:51 +01:00
|
|
|
QCOMPARE(frame.functionName(), QString("_Exit"));
|
2013-04-08 17:26:37 +02:00
|
|
|
}
|
|
|
|
|
{
|
|
|
|
|
const Frame frame = stack.frames().at(1);
|
2018-12-03 15:30:51 +01:00
|
|
|
QCOMPARE(frame.functionName(), QString("__run_exit_handlers"));
|
2013-04-08 17:26:37 +02:00
|
|
|
}
|
|
|
|
|
{
|
|
|
|
|
const Frame frame = stack.frames().at(2);
|
2018-12-03 15:30:51 +01:00
|
|
|
QCOMPARE(frame.functionName(), QString("exit"));
|
2013-04-08 17:26:37 +02:00
|
|
|
}
|
|
|
|
|
{
|
|
|
|
|
const Frame frame = stack.frames().at(3);
|
2018-12-03 15:30:51 +01:00
|
|
|
QCOMPARE(frame.functionName(), QString("(below main)"));
|
2013-04-08 17:26:37 +02:00
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
QCOMPARE(stack.frames().count(), 1);
|
|
|
|
|
{
|
|
|
|
|
const Frame frame = stack.frames().at(0);
|
2018-12-03 15:30:51 +01:00
|
|
|
QCOMPARE(frame.functionName(), QString("_Exit"));
|
2013-04-08 17:26:37 +02:00
|
|
|
}
|
2011-03-04 12:15:18 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
//BEGIN second stack
|
|
|
|
|
{
|
2019-01-30 20:54:57 +01:00
|
|
|
const Stack stack = error.stacks().constLast();
|
2011-03-04 12:15:18 +01:00
|
|
|
QCOMPARE(stack.line(), qint64(-1));
|
|
|
|
|
QCOMPARE(stack.frames().count(), 1);
|
|
|
|
|
|
2019-01-30 20:54:57 +01:00
|
|
|
const Frame frame = stack.frames().constFirst();
|
2018-12-03 15:30:51 +01:00
|
|
|
QCOMPARE(frame.functionName(), QString("main"));
|
2015-03-02 15:57:10 +01:00
|
|
|
QCOMPARE(frame.line(), 2 + HEADER_LENGTH);
|
2011-03-04 12:15:18 +01:00
|
|
|
|
|
|
|
|
QCOMPARE(frame.object(), binary);
|
2018-12-03 15:30:51 +01:00
|
|
|
QCOMPARE(frame.fileName(), QString("main.cpp"));
|
2011-03-04 12:15:18 +01:00
|
|
|
QCOMPARE(QDir::cleanPath(frame.directory()), srcDir);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-12-06 12:05:05 +01:00
|
|
|
void ValgrindTestRunnerTest::testFree1()
|
2011-03-04 12:15:18 +01:00
|
|
|
{
|
|
|
|
|
const QString app("free1");
|
2018-12-01 20:56:21 +02:00
|
|
|
const QString binary = runTestBinary(app + '/' + app);
|
2016-12-06 12:05:05 +01:00
|
|
|
if (binary.isEmpty())
|
|
|
|
|
QSKIP("You need to pass BUILD_TESTS when building Qt Creator or build valgrind testapps "
|
|
|
|
|
"manually before executing this test.");
|
2011-03-04 12:15:18 +01:00
|
|
|
const QString srcDir = srcDirForApp(app);
|
|
|
|
|
|
|
|
|
|
QVERIFY(m_logMessages.isEmpty());
|
|
|
|
|
|
|
|
|
|
QCOMPARE(m_errors.count(), 1);
|
|
|
|
|
const Error error = m_errors.first();
|
|
|
|
|
QCOMPARE(error.kind(), int(InvalidFree));
|
2017-07-04 10:23:15 +02:00
|
|
|
QVERIFY(error.stacks().count() >= 2);
|
2011-03-04 12:15:18 +01:00
|
|
|
//BEGIN first stack
|
|
|
|
|
{
|
2019-01-30 20:54:57 +01:00
|
|
|
const Stack stack = error.stacks().constFirst();
|
2011-03-04 12:15:18 +01:00
|
|
|
QCOMPARE(stack.line(), qint64(-1));
|
|
|
|
|
QCOMPARE(stack.frames().count(), 2);
|
|
|
|
|
|
|
|
|
|
{
|
2019-01-30 20:54:57 +01:00
|
|
|
const Frame frame = stack.frames().constFirst();
|
2020-07-27 13:51:20 +02:00
|
|
|
QVERIFY2(frame.functionName().contains("operator delete"), qPrintable(frame.functionName()));
|
2011-03-04 12:15:18 +01:00
|
|
|
}
|
|
|
|
|
{
|
2019-01-30 20:54:57 +01:00
|
|
|
const Frame frame = stack.frames().constLast();
|
2018-12-03 15:30:51 +01:00
|
|
|
QCOMPARE(frame.functionName(), QString("main"));
|
2013-04-08 17:26:37 +02:00
|
|
|
QCOMPARE(frame.line(), 7 + HEADER_LENGTH);
|
2011-03-04 12:15:18 +01:00
|
|
|
|
|
|
|
|
QCOMPARE(frame.object(), binary);
|
2018-12-03 15:30:51 +01:00
|
|
|
QCOMPARE(frame.fileName(), QString("main.cpp"));
|
2011-03-04 12:15:18 +01:00
|
|
|
QCOMPARE(QDir::cleanPath(frame.directory()), srcDir);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
//BEGIN second stack
|
|
|
|
|
{
|
2017-07-04 10:23:15 +02:00
|
|
|
const Stack stack = error.stacks().at(1);
|
2011-03-04 12:15:18 +01:00
|
|
|
QCOMPARE(stack.line(), qint64(-1));
|
|
|
|
|
QCOMPARE(stack.frames().count(), 2);
|
|
|
|
|
|
|
|
|
|
{
|
2019-01-30 20:54:57 +01:00
|
|
|
const Frame frame = stack.frames().constFirst();
|
2020-07-27 13:51:20 +02:00
|
|
|
QVERIFY2(frame.functionName().contains("operator delete"), qPrintable(frame.functionName()));
|
2011-03-04 12:15:18 +01:00
|
|
|
}
|
|
|
|
|
{
|
2019-01-30 20:54:57 +01:00
|
|
|
const Frame frame = stack.frames().constLast();
|
2018-12-03 15:30:51 +01:00
|
|
|
QCOMPARE(frame.functionName(), QString("main"));
|
2013-04-08 17:26:37 +02:00
|
|
|
QCOMPARE(frame.line(), 6 + HEADER_LENGTH);
|
2011-03-04 12:15:18 +01:00
|
|
|
|
|
|
|
|
QCOMPARE(frame.object(), binary);
|
2018-12-03 15:30:51 +01:00
|
|
|
QCOMPARE(frame.fileName(), QString("main.cpp"));
|
2011-03-04 12:15:18 +01:00
|
|
|
QCOMPARE(QDir::cleanPath(frame.directory()), srcDir);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-12-06 12:05:05 +01:00
|
|
|
void ValgrindTestRunnerTest::testFree2()
|
2011-03-04 12:15:18 +01:00
|
|
|
{
|
|
|
|
|
const QString app("free2");
|
2018-12-01 20:56:21 +02:00
|
|
|
const QString binary = runTestBinary(app + '/' + app);
|
2016-12-06 12:05:05 +01:00
|
|
|
if (binary.isEmpty())
|
|
|
|
|
QSKIP("You need to pass BUILD_TESTS when building Qt Creator or build valgrind testapps "
|
|
|
|
|
"manually before executing this test.");
|
2011-03-04 12:15:18 +01:00
|
|
|
const QString srcDir = srcDirForApp(app);
|
|
|
|
|
|
|
|
|
|
QVERIFY(m_logMessages.isEmpty());
|
|
|
|
|
|
|
|
|
|
QCOMPARE(m_errors.count(), 1);
|
|
|
|
|
const Error error = m_errors.first();
|
|
|
|
|
QCOMPARE(error.kind(), int(MismatchedFree));
|
|
|
|
|
QCOMPARE(error.stacks().count(), 2);
|
|
|
|
|
//BEGIN first stack
|
|
|
|
|
{
|
2019-01-30 20:54:57 +01:00
|
|
|
const Stack stack = error.stacks().constFirst();
|
2011-03-04 12:15:18 +01:00
|
|
|
QCOMPARE(stack.line(), qint64(-1));
|
|
|
|
|
QCOMPARE(stack.frames().count(), 2);
|
|
|
|
|
|
|
|
|
|
{
|
2019-01-30 20:54:57 +01:00
|
|
|
const Frame frame = stack.frames().constFirst();
|
2018-12-03 15:30:51 +01:00
|
|
|
QCOMPARE(frame.functionName(), QString("free"));
|
2011-03-04 12:15:18 +01:00
|
|
|
}
|
|
|
|
|
{
|
2019-01-30 20:54:57 +01:00
|
|
|
const Frame frame = stack.frames().constLast();
|
2018-12-03 15:30:51 +01:00
|
|
|
QCOMPARE(frame.functionName(), QString("main"));
|
2013-04-08 17:26:37 +02:00
|
|
|
QCOMPARE(frame.line(), 6 + HEADER_LENGTH);
|
2011-03-04 12:15:18 +01:00
|
|
|
|
|
|
|
|
QCOMPARE(frame.object(), binary);
|
2018-12-03 15:30:51 +01:00
|
|
|
QCOMPARE(frame.fileName(), QString("main.cpp"));
|
2011-03-04 12:15:18 +01:00
|
|
|
QCOMPARE(QDir::cleanPath(frame.directory()), srcDir);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
//BEGIN second stack
|
|
|
|
|
{
|
2019-01-30 20:54:57 +01:00
|
|
|
const Stack stack = error.stacks().constLast();
|
2011-03-04 12:15:18 +01:00
|
|
|
QCOMPARE(stack.line(), qint64(-1));
|
|
|
|
|
QCOMPARE(stack.frames().count(), 2);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
{
|
2019-01-30 20:54:57 +01:00
|
|
|
const Frame frame = stack.frames().constFirst();
|
2013-04-08 17:26:37 +02:00
|
|
|
if (on64bit())
|
2018-12-03 15:30:51 +01:00
|
|
|
QCOMPARE(frame.functionName(), QString("operator new(unsigned long)"));
|
2013-04-08 17:26:37 +02:00
|
|
|
else
|
2018-12-03 15:30:51 +01:00
|
|
|
QCOMPARE(frame.functionName(), QString("operator new(unsigned int)"));
|
2011-03-04 12:15:18 +01:00
|
|
|
}
|
|
|
|
|
{
|
2019-01-30 20:54:57 +01:00
|
|
|
const Frame frame = stack.frames().constLast();
|
2018-12-03 15:30:51 +01:00
|
|
|
QCOMPARE(frame.functionName(), QString("main"));
|
2013-04-08 17:26:37 +02:00
|
|
|
QCOMPARE(frame.line(), 5 + HEADER_LENGTH);
|
2011-03-04 12:15:18 +01:00
|
|
|
|
|
|
|
|
QCOMPARE(frame.object(), binary);
|
2018-12-03 15:30:51 +01:00
|
|
|
QCOMPARE(frame.fileName(), QString("main.cpp"));
|
2011-03-04 12:15:18 +01:00
|
|
|
QCOMPARE(QDir::cleanPath(frame.directory()), srcDir);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-12-06 12:05:05 +01:00
|
|
|
void ValgrindTestRunnerTest::testInvalidjump()
|
2011-03-04 12:15:18 +01:00
|
|
|
{
|
|
|
|
|
const QString app("invalidjump");
|
|
|
|
|
m_expectCrash = true;
|
2018-12-01 20:56:21 +02:00
|
|
|
const QString binary = runTestBinary(app + '/' + app);
|
2016-12-06 12:05:05 +01:00
|
|
|
if (binary.isEmpty())
|
|
|
|
|
QSKIP("You need to pass BUILD_TESTS when building Qt Creator or build valgrind testapps "
|
|
|
|
|
"manually before executing this test.");
|
2011-03-04 12:15:18 +01:00
|
|
|
|
|
|
|
|
QVERIFY(m_logMessages.isEmpty());
|
|
|
|
|
|
|
|
|
|
QCOMPARE(m_errors.count(), 1);
|
|
|
|
|
const Error error = m_errors.first();
|
|
|
|
|
QCOMPARE(error.kind(), int(InvalidJump));
|
|
|
|
|
QCOMPARE(error.stacks().count(), 1);
|
2019-01-30 20:54:57 +01:00
|
|
|
const Stack stack = error.stacks().constFirst();
|
2011-03-04 12:15:18 +01:00
|
|
|
QCOMPARE(stack.line(), qint64(-1));
|
|
|
|
|
QCOMPARE(stack.frames().count(), 2);
|
|
|
|
|
QVERIFY(!stack.auxWhat().isEmpty());
|
|
|
|
|
{
|
|
|
|
|
const Frame frame = stack.frames().at(0);
|
|
|
|
|
QCOMPARE(frame.instructionPointer(), quint64(0));
|
|
|
|
|
}
|
|
|
|
|
{
|
|
|
|
|
const Frame frame = stack.frames().at(1);
|
2018-12-03 15:30:51 +01:00
|
|
|
QCOMPARE(frame.functionName(), QString("(below main)"));
|
2011-03-04 12:15:18 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-12-06 12:05:05 +01:00
|
|
|
void ValgrindTestRunnerTest::testOverlap()
|
2011-03-04 12:15:18 +01:00
|
|
|
{
|
|
|
|
|
const QString app("overlap");
|
|
|
|
|
m_expectCrash = true;
|
2018-12-01 20:56:21 +02:00
|
|
|
const QString binary = runTestBinary(app + '/' + app);
|
2016-12-06 12:05:05 +01:00
|
|
|
if (binary.isEmpty())
|
|
|
|
|
QSKIP("You need to pass BUILD_TESTS when building Qt Creator or build valgrind testapps "
|
|
|
|
|
"manually before executing this test.");
|
2011-03-04 12:15:18 +01:00
|
|
|
const QString srcDir = srcDirForApp(app);
|
|
|
|
|
|
|
|
|
|
QVERIFY(m_logMessages.isEmpty());
|
|
|
|
|
|
2020-07-27 13:51:20 +02:00
|
|
|
QVERIFY(m_errors.count() <= 1);
|
|
|
|
|
if (m_errors.isEmpty())
|
|
|
|
|
QSKIP("Some libc implementations automatically use memmove in case of an overlap.");
|
|
|
|
|
|
2011-03-04 12:15:18 +01:00
|
|
|
const Error error = m_errors.first();
|
|
|
|
|
QCOMPARE(error.kind(), int(Overlap));
|
|
|
|
|
QCOMPARE(error.stacks().count(), 1);
|
2019-01-30 20:54:57 +01:00
|
|
|
const Stack stack = error.stacks().constFirst();
|
2011-03-04 12:15:18 +01:00
|
|
|
QCOMPARE(stack.line(), qint64(-1));
|
|
|
|
|
QCOMPARE(stack.frames().count(), 2);
|
|
|
|
|
{
|
|
|
|
|
const Frame frame = stack.frames().at(0);
|
2018-12-01 20:56:21 +02:00
|
|
|
QVERIFY(frame.functionName().startsWith("memcpy"));
|
2011-03-04 12:15:18 +01:00
|
|
|
}
|
|
|
|
|
{
|
2019-01-30 20:54:57 +01:00
|
|
|
const Frame frame = stack.frames().constLast();
|
2018-12-03 15:26:07 +02:00
|
|
|
QCOMPARE(frame.functionName(), QLatin1String("main"));
|
2013-04-08 17:26:37 +02:00
|
|
|
QCOMPARE(frame.line(), 6 + HEADER_LENGTH);
|
2011-03-04 12:15:18 +01:00
|
|
|
|
|
|
|
|
QCOMPARE(frame.object(), binary);
|
2018-12-03 15:26:07 +02:00
|
|
|
QCOMPARE(frame.fileName(), QLatin1String("main.cpp"));
|
2011-03-04 12:15:18 +01:00
|
|
|
QCOMPARE(QDir::cleanPath(frame.directory()), srcDir);
|
|
|
|
|
}
|
|
|
|
|
}
|
2016-12-06 12:05:05 +01:00
|
|
|
|
|
|
|
|
} // namespace Test
|
|
|
|
|
} // namespace Valgrind
|