forked from qt-creator/qt-creator
Add valgrindfake emulation/testing tool.
Merge-request: 260 Reviewed-by: hjk <qtc-committer@nokia.com>
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -87,6 +87,7 @@ share/doc/qtcreator/qtcreator.qch
|
|||||||
src/tools/gen-cpp-ast/generate-ast
|
src/tools/gen-cpp-ast/generate-ast
|
||||||
src/tools/mkvisitor/cplusplus0
|
src/tools/mkvisitor/cplusplus0
|
||||||
src/tools/qml/qmldump/qmldump
|
src/tools/qml/qmldump/qmldump
|
||||||
|
src/tools/valgrindfake/valgrind-fake
|
||||||
|
|
||||||
# Tests
|
# Tests
|
||||||
#------
|
#------
|
||||||
|
@@ -3,6 +3,10 @@ TEMPLATE = subdirs
|
|||||||
win32:SUBDIRS = qtcdebugger
|
win32:SUBDIRS = qtcdebugger
|
||||||
SUBDIRS += qtpromaker
|
SUBDIRS += qtpromaker
|
||||||
|
|
||||||
|
!win32 {
|
||||||
|
SUBDIRS += valgrindfake
|
||||||
|
}
|
||||||
|
|
||||||
QT_BREAKPAD_ROOT_PATH = $$(QT_BREAKPAD_ROOT_PATH)
|
QT_BREAKPAD_ROOT_PATH = $$(QT_BREAKPAD_ROOT_PATH)
|
||||||
!isEmpty(QT_BREAKPAD_ROOT_PATH) {
|
!isEmpty(QT_BREAKPAD_ROOT_PATH) {
|
||||||
SUBDIRS += qtcrashhandler
|
SUBDIRS += qtcrashhandler
|
||||||
|
158
src/tools/valgrindfake/main.cpp
Normal file
158
src/tools/valgrindfake/main.cpp
Normal file
@@ -0,0 +1,158 @@
|
|||||||
|
/**************************************************************************
|
||||||
|
**
|
||||||
|
** This file is part of Qt Creator
|
||||||
|
**
|
||||||
|
** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
|
||||||
|
**
|
||||||
|
** Author: Milian Wolff, KDAB (milian.wolff@kdab.com)
|
||||||
|
**
|
||||||
|
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||||
|
**
|
||||||
|
** No Commercial Usage
|
||||||
|
**
|
||||||
|
** This file contains pre-release code and may not be distributed.
|
||||||
|
** You may use this file in accordance with the terms and conditions
|
||||||
|
** contained in the Technology Preview License Agreement accompanying
|
||||||
|
** this package.
|
||||||
|
**
|
||||||
|
** GNU Lesser General Public License Usage
|
||||||
|
**
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||||
|
** General Public License version 2.1 as published by the Free Software
|
||||||
|
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||||
|
** packaging of this file. Please review the following information to
|
||||||
|
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||||
|
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||||
|
**
|
||||||
|
** In addition, as a special exception, Nokia gives you certain additional
|
||||||
|
** rights. These rights are described in the Nokia Qt LGPL Exception
|
||||||
|
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||||
|
**
|
||||||
|
** If you have questions regarding the use of this file, please contact
|
||||||
|
** Nokia at qt-info@nokia.com.
|
||||||
|
**
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
#include <QCoreApplication>
|
||||||
|
#include <QStringList>
|
||||||
|
#include <QTextStream>
|
||||||
|
#include <QDir>
|
||||||
|
#include <QTcpSocket>
|
||||||
|
#include <QXmlStreamReader>
|
||||||
|
#include <QProcessEnvironment>
|
||||||
|
|
||||||
|
#include "outputgenerator.h"
|
||||||
|
|
||||||
|
using namespace Valgrind::Fake;
|
||||||
|
|
||||||
|
QTextStream qerr(stderr);
|
||||||
|
QTextStream qout(stdout);
|
||||||
|
|
||||||
|
void usage(QTextStream& stream)
|
||||||
|
{
|
||||||
|
stream << "valgrind-fake OPTIONS" << endl;
|
||||||
|
stream << endl;
|
||||||
|
stream << " REQUIRED OPTIONS:" << endl;
|
||||||
|
stream << " --xml-socket=ipaddr:port \tXML output to socket ipaddr:port" << endl;
|
||||||
|
stream << " -i, --xml-input FILE \tpath to a XML file as generated by valgrind" << endl;
|
||||||
|
stream << endl;
|
||||||
|
stream << " OPTIONAL OPTIONS:" << endl;
|
||||||
|
stream << " -c, --crash \tcrash randomly" << endl;
|
||||||
|
stream << " -g, --garbage \toutput invalid XML somewhere" << endl;
|
||||||
|
stream << " -w, --wait SECONDS \twait randomly for the given amount of seconds" << endl;
|
||||||
|
stream << " -h, --help \tprint help" << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char** argv)
|
||||||
|
{
|
||||||
|
QCoreApplication app(argc, argv);
|
||||||
|
|
||||||
|
const QStringList args = app.arguments();
|
||||||
|
QString arg_port;
|
||||||
|
QString arg_server;
|
||||||
|
QString arg_xmlFile;
|
||||||
|
bool arg_crash = false;
|
||||||
|
bool arg_garbage = false;
|
||||||
|
uint arg_wait = 0;
|
||||||
|
|
||||||
|
const QProcessEnvironment sysEnv = QProcessEnvironment::systemEnvironment();
|
||||||
|
arg_xmlFile = sysEnv.value("QCIT_INPUT_FILE");
|
||||||
|
|
||||||
|
for (int i = 1; i < args.size(); ++i) {
|
||||||
|
const QString& arg = args.at(i);
|
||||||
|
if (arg.startsWith(QLatin1String("--xml-socket="))) {
|
||||||
|
arg_server = arg.mid(13, arg.indexOf(':') - 13);
|
||||||
|
arg_port = arg.mid(13 + arg_server.length() + 1);
|
||||||
|
} else if (args.size() > i + 1
|
||||||
|
&& (args.at(i) == QLatin1String("-i")
|
||||||
|
|| args.at(i) == QLatin1String("--xml-input"))) {
|
||||||
|
arg_xmlFile = args.at(i+1);
|
||||||
|
++i;
|
||||||
|
} else if (arg == QLatin1String("-c") || arg == QLatin1String("--crash")) {
|
||||||
|
arg_crash = true;
|
||||||
|
} else if (arg == QLatin1String("-g") || arg == QLatin1String("--garbage")) {
|
||||||
|
arg_garbage = true;
|
||||||
|
} else if (args.size() > i + 1 && (arg == QLatin1String("-w") || arg == QLatin1String("--wait"))) {
|
||||||
|
bool ok;
|
||||||
|
arg_wait = args.at(i+1).toUInt(&ok);
|
||||||
|
if (!ok) {
|
||||||
|
qerr << "ERROR: invalid wait time given" << args.at(i+1) << endl;
|
||||||
|
usage(qerr);
|
||||||
|
return 4;
|
||||||
|
}
|
||||||
|
} else if (args.at(i) == QLatin1String("--help") || args.at(i) == QLatin1String("-h")) {
|
||||||
|
usage(qout);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (arg_xmlFile.isEmpty()) {
|
||||||
|
qerr << "ERROR: no XML input file given" << endl;
|
||||||
|
usage(qerr);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (arg_server.isEmpty()) {
|
||||||
|
qerr << "ERROR: no server given" << endl;
|
||||||
|
usage(qerr);
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
if (arg_port.isEmpty()) {
|
||||||
|
qerr << "ERROR: no port given" << endl;
|
||||||
|
usage(qerr);
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
QFile xmlFile(arg_xmlFile);
|
||||||
|
if (!xmlFile.exists() || !xmlFile.open(QIODevice::ReadOnly)) {
|
||||||
|
qerr << "ERROR: invalid XML file" << endl;
|
||||||
|
usage(qerr);
|
||||||
|
return 10;
|
||||||
|
}
|
||||||
|
bool ok = false;
|
||||||
|
quint16 port = arg_port.toUInt(&ok);
|
||||||
|
if (!ok) {
|
||||||
|
qerr << "ERROR: invalid port" << endl;
|
||||||
|
usage(qerr);
|
||||||
|
return 30;
|
||||||
|
}
|
||||||
|
|
||||||
|
QTcpSocket socket;
|
||||||
|
socket.connectToHost(arg_server, port, QIODevice::WriteOnly);
|
||||||
|
if (!socket.isOpen()) {
|
||||||
|
qerr << "ERROR: could not open socket to server:" << arg_server << ":" << port << endl;
|
||||||
|
usage(qerr);
|
||||||
|
return 20;
|
||||||
|
}
|
||||||
|
if (!socket.waitForConnected()) {
|
||||||
|
qerr << "ERROR: could not connect to socket: " << socket.errorString() << endl;
|
||||||
|
return 21;
|
||||||
|
}
|
||||||
|
|
||||||
|
OutputGenerator generator(&socket, &xmlFile);
|
||||||
|
QObject::connect(&generator, SIGNAL(finished()), &app, SLOT(quit()));
|
||||||
|
generator.setCrashRandomly(arg_crash);
|
||||||
|
generator.setOutputGarbage(arg_garbage);
|
||||||
|
generator.setWait(arg_wait);
|
||||||
|
|
||||||
|
return app.exec();
|
||||||
|
}
|
159
src/tools/valgrindfake/outputgenerator.cpp
Normal file
159
src/tools/valgrindfake/outputgenerator.cpp
Normal file
@@ -0,0 +1,159 @@
|
|||||||
|
/**************************************************************************
|
||||||
|
**
|
||||||
|
** This file is part of Qt Creator
|
||||||
|
**
|
||||||
|
** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
|
||||||
|
**
|
||||||
|
** Author: Milian Wolff, KDAB (milian.wolff@kdab.com)
|
||||||
|
**
|
||||||
|
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||||
|
**
|
||||||
|
** No Commercial Usage
|
||||||
|
**
|
||||||
|
** This file contains pre-release code and may not be distributed.
|
||||||
|
** You may use this file in accordance with the terms and conditions
|
||||||
|
** contained in the Technology Preview License Agreement accompanying
|
||||||
|
** this package.
|
||||||
|
**
|
||||||
|
** GNU Lesser General Public License Usage
|
||||||
|
**
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||||
|
** General Public License version 2.1 as published by the Free Software
|
||||||
|
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||||
|
** packaging of this file. Please review the following information to
|
||||||
|
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||||
|
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||||
|
**
|
||||||
|
** In addition, as a special exception, Nokia gives you certain additional
|
||||||
|
** rights. These rights are described in the Nokia Qt LGPL Exception
|
||||||
|
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||||
|
**
|
||||||
|
** If you have questions regarding the use of this file, please contact
|
||||||
|
** Nokia at qt-info@nokia.com.
|
||||||
|
**
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
#include "outputgenerator.h"
|
||||||
|
|
||||||
|
#include <QAbstractSocket>
|
||||||
|
#include <QIODevice>
|
||||||
|
#include <QTextStream>
|
||||||
|
#include <QCoreApplication>
|
||||||
|
#include <QStringList>
|
||||||
|
#include <QDebug>
|
||||||
|
|
||||||
|
using namespace Valgrind::Fake;
|
||||||
|
|
||||||
|
OutputGenerator::OutputGenerator(QAbstractSocket *output, QIODevice *input) :
|
||||||
|
m_output(output),
|
||||||
|
m_input(input),
|
||||||
|
m_finished(false),
|
||||||
|
m_crash(false),
|
||||||
|
m_garbage(false),
|
||||||
|
m_wait(0)
|
||||||
|
{
|
||||||
|
Q_ASSERT(input->isOpen());
|
||||||
|
Q_ASSERT(input->isReadable());
|
||||||
|
|
||||||
|
m_timer.setSingleShot(true);
|
||||||
|
m_timer.start();
|
||||||
|
|
||||||
|
connect(&m_timer, SIGNAL(timeout()),
|
||||||
|
this, SLOT(writeOutput()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void OutputGenerator::setCrashRandomly(bool enable)
|
||||||
|
{
|
||||||
|
m_crash = enable;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OutputGenerator::setOutputGarbage(bool enable)
|
||||||
|
{
|
||||||
|
m_garbage = enable;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OutputGenerator::setWait(uint seconds)
|
||||||
|
{
|
||||||
|
m_wait = seconds;
|
||||||
|
}
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
static bool blockingWrite(QIODevice *dev, const QByteArray &ba)
|
||||||
|
{
|
||||||
|
const qint64 toWrite = ba.size();
|
||||||
|
qint64 written = 0;
|
||||||
|
while (written < ba.size()) {
|
||||||
|
const qint64 n = dev->write(ba.constData() + written, toWrite - written);
|
||||||
|
if (n < 0)
|
||||||
|
return false;
|
||||||
|
written += n;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OutputGenerator::produceRuntimeError()
|
||||||
|
{
|
||||||
|
if (m_crash) {
|
||||||
|
std::cerr << "Goodbye, cruel world" << std::endl;
|
||||||
|
int zero = 0; // hide the error at compile-time to avoid a compiler warning
|
||||||
|
int i = 1 / zero;
|
||||||
|
Q_UNUSED(i);
|
||||||
|
Q_ASSERT(false);
|
||||||
|
}
|
||||||
|
else if (m_garbage) {
|
||||||
|
std::cerr << "Writing garbage" << std::endl;
|
||||||
|
blockingWrite(m_output, "<</GARBAGE = '\"''asdfaqre");
|
||||||
|
m_output->flush();
|
||||||
|
} else if (m_wait) {
|
||||||
|
qDebug() << "waiting in fake valgrind for " << m_wait << " seconds..." << endl;
|
||||||
|
sleep(m_wait);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void OutputGenerator::writeOutput()
|
||||||
|
{
|
||||||
|
m_timer.setInterval(qrand() % 1000);
|
||||||
|
|
||||||
|
int lines = 0;
|
||||||
|
while (!m_input->atEnd()) {
|
||||||
|
qint64 lastPos = m_input->pos();
|
||||||
|
QByteArray line = m_input->readLine();
|
||||||
|
if (lines > 0 && !m_finished && line.contains("<error>")) {
|
||||||
|
if ((m_crash || m_garbage || m_wait) && qrand() % 10 == 1) {
|
||||||
|
produceRuntimeError();
|
||||||
|
m_timer.start();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_input->seek(lastPos);
|
||||||
|
m_timer.start();
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
if (!m_finished && line.contains("<state>FINISHED</state>")) {
|
||||||
|
m_finished = true;
|
||||||
|
if (m_crash || m_garbage || m_wait) {
|
||||||
|
produceRuntimeError();
|
||||||
|
m_timer.start();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!blockingWrite(m_output, line)) {
|
||||||
|
std::cerr << "Writing to socket failed: " << qPrintable(m_output->errorString()) << std::endl;
|
||||||
|
emit finished();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
m_output->flush();
|
||||||
|
++lines;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Q_ASSERT(m_input->atEnd());
|
||||||
|
|
||||||
|
while (m_output->bytesToWrite() > 0)
|
||||||
|
m_output->waitForBytesWritten(-1);
|
||||||
|
emit finished();
|
||||||
|
}
|
84
src/tools/valgrindfake/outputgenerator.h
Normal file
84
src/tools/valgrindfake/outputgenerator.h
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
/**************************************************************************
|
||||||
|
**
|
||||||
|
** This file is part of Qt Creator
|
||||||
|
**
|
||||||
|
** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
|
||||||
|
**
|
||||||
|
** Author: Milian Wolff, KDAB (milian.wolff@kdab.com)
|
||||||
|
**
|
||||||
|
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||||
|
**
|
||||||
|
** No Commercial Usage
|
||||||
|
**
|
||||||
|
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||||
|
** accordance with the Qt Commercial License Agreement provided with the
|
||||||
|
** Software or, alternatively, in accordance with the terms contained in
|
||||||
|
** a written agreement between you and Nokia.
|
||||||
|
**
|
||||||
|
** GNU Lesser General Public License Usage
|
||||||
|
**
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||||
|
** General Public License version 2.1 as published by the Free Software
|
||||||
|
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||||
|
** packaging of this file. Please review the following information to
|
||||||
|
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||||
|
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||||
|
**
|
||||||
|
** In addition, as a special exception, Nokia gives you certain additional
|
||||||
|
** rights. These rights are described in the Nokia Qt LGPL Exception
|
||||||
|
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||||
|
**
|
||||||
|
** If you have questions regarding the use of this file, please contact
|
||||||
|
** Nokia at qt-info@nokia.com.
|
||||||
|
**
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
#ifndef LIBVALGRIND_FAKE_OUTPUTGENERATOR_H
|
||||||
|
#define LIBVALGRIND_FAKE_OUTPUTGENERATOR_H
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QTimer>
|
||||||
|
#include <QTextStream>
|
||||||
|
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
class QAbstractSocket;
|
||||||
|
class QIODevice;
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
|
namespace Valgrind {
|
||||||
|
namespace Fake {
|
||||||
|
|
||||||
|
class OutputGenerator : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit OutputGenerator(QAbstractSocket *output, QIODevice *input);
|
||||||
|
|
||||||
|
void setCrashRandomly(bool enable);
|
||||||
|
void setOutputGarbage(bool enable);
|
||||||
|
void setWait(uint seconds);
|
||||||
|
|
||||||
|
Q_SIGNALS:
|
||||||
|
void finished();
|
||||||
|
private slots:
|
||||||
|
/// write output to the stream until the next error
|
||||||
|
void writeOutput();
|
||||||
|
|
||||||
|
private:
|
||||||
|
void produceRuntimeError();
|
||||||
|
|
||||||
|
QAbstractSocket *m_output;
|
||||||
|
QIODevice *m_input;
|
||||||
|
QTimer m_timer;
|
||||||
|
bool m_finished;
|
||||||
|
bool m_crash;
|
||||||
|
bool m_garbage;
|
||||||
|
uint m_wait;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Fake
|
||||||
|
} // namespace Valgrind
|
||||||
|
|
||||||
|
#endif // LIBVALGRIND_FAKE_OUTPUTGENERATOR_H
|
10
src/tools/valgrindfake/valgrindfake.pro
Normal file
10
src/tools/valgrindfake/valgrindfake.pro
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
TEMPLATE = app
|
||||||
|
TARGET = valgrind-fake
|
||||||
|
|
||||||
|
QT += network xml
|
||||||
|
|
||||||
|
macx:CONFIG -= app_bundle
|
||||||
|
|
||||||
|
HEADERS += outputgenerator.h
|
||||||
|
SOURCES += main.cpp \
|
||||||
|
outputgenerator.cpp
|
Reference in New Issue
Block a user