2012-10-02 09:12:39 +02:00
|
|
|
/****************************************************************************
|
2011-03-04 12:15:18 +01:00
|
|
|
**
|
2016-01-15 14:57:40 +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:57:40 +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:57:40 +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:57:40 +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
|
|
|
|
|
|
|
|
#include "valgrindrunner.h"
|
|
|
|
|
|
2017-06-21 08:08:43 +02:00
|
|
|
#include "xmlprotocol/threadedparser.h"
|
|
|
|
|
|
2012-08-23 15:53:58 +02:00
|
|
|
#include <utils/hostosinfo.h>
|
2011-03-04 12:15:18 +01:00
|
|
|
#include <utils/qtcassert.h>
|
2017-06-29 15:03:06 +02:00
|
|
|
#include <utils/qtcprocess.h>
|
2011-03-04 12:15:18 +01:00
|
|
|
|
2012-02-15 10:42:41 +01:00
|
|
|
#include <QEventLoop>
|
2017-06-21 08:08:43 +02:00
|
|
|
#include <QTcpServer>
|
|
|
|
|
#include <QTcpSocket>
|
2011-03-04 12:15:18 +01:00
|
|
|
|
2016-01-25 17:15:54 +01:00
|
|
|
using namespace ProjectExplorer;
|
2017-06-29 15:03:06 +02:00
|
|
|
using namespace Utils;
|
2016-01-25 17:15:54 +01:00
|
|
|
|
2011-05-18 17:05:49 +02:00
|
|
|
namespace Valgrind {
|
2011-03-04 12:15:18 +01:00
|
|
|
|
2017-06-29 15:03:06 +02:00
|
|
|
class ValgrindRunner::Private : public QObject
|
2011-03-04 12:15:18 +01:00
|
|
|
{
|
|
|
|
|
public:
|
2017-06-29 15:03:06 +02:00
|
|
|
Private(ValgrindRunner *owner) : q(owner) {}
|
|
|
|
|
|
2019-06-04 12:10:11 +02:00
|
|
|
bool run();
|
2017-06-29 15:03:06 +02:00
|
|
|
|
2017-07-13 17:59:53 +02:00
|
|
|
void handleRemoteStderr(const QString &b);
|
|
|
|
|
void handleRemoteStdout(const QString &b);
|
2017-06-29 15:03:06 +02:00
|
|
|
|
|
|
|
|
void closed(bool success);
|
|
|
|
|
void localProcessStarted();
|
|
|
|
|
void remoteProcessStarted();
|
2017-07-13 17:59:53 +02:00
|
|
|
void findPidOutputReceived(const QString &out);
|
2017-06-29 15:03:06 +02:00
|
|
|
|
|
|
|
|
ValgrindRunner *q;
|
2018-05-16 15:42:03 +02:00
|
|
|
Runnable m_debuggee;
|
2017-06-29 15:03:06 +02:00
|
|
|
ApplicationLauncher m_valgrindProcess;
|
|
|
|
|
IDevice::ConstPtr m_device;
|
|
|
|
|
|
|
|
|
|
ApplicationLauncher m_findPID;
|
|
|
|
|
|
|
|
|
|
QString m_valgrindExecutable;
|
|
|
|
|
QStringList m_valgrindArguments;
|
|
|
|
|
|
2017-06-28 14:53:21 +02:00
|
|
|
QHostAddress localServerAddress;
|
2016-01-25 17:15:54 +01:00
|
|
|
QProcess::ProcessChannelMode channelMode = QProcess::SeparateChannels;
|
2017-06-29 15:03:06 +02:00
|
|
|
bool m_finished = false;
|
2017-06-21 08:08:43 +02:00
|
|
|
|
|
|
|
|
QTcpServer xmlServer;
|
2017-06-21 09:01:48 +02:00
|
|
|
XmlProtocol::ThreadedParser parser;
|
2017-06-21 08:08:43 +02:00
|
|
|
QTcpServer logServer;
|
|
|
|
|
QTcpSocket *logSocket = nullptr;
|
2017-06-29 15:03:06 +02:00
|
|
|
|
|
|
|
|
// Workaround for valgrind bug when running vgdb with xml output
|
|
|
|
|
// https://bugs.kde.org/show_bug.cgi?id=343902
|
2017-06-21 08:08:43 +02:00
|
|
|
bool disableXml = false;
|
2011-03-04 12:15:18 +01:00
|
|
|
};
|
|
|
|
|
|
2019-06-04 12:10:11 +02:00
|
|
|
bool ValgrindRunner::Private::run()
|
2017-06-29 15:03:06 +02:00
|
|
|
{
|
2019-06-04 12:29:07 +02:00
|
|
|
QStringList arguments;
|
|
|
|
|
|
2019-06-04 12:10:11 +02:00
|
|
|
if (!localServerAddress.isNull()) {
|
|
|
|
|
if (!q->startServers())
|
|
|
|
|
return false;
|
|
|
|
|
|
2019-06-04 12:29:07 +02:00
|
|
|
arguments.append("--child-silent-after-fork=yes");
|
2019-06-04 12:10:11 +02:00
|
|
|
|
2019-06-04 12:29:07 +02:00
|
|
|
bool enableXml = !disableXml;
|
2019-06-04 12:10:11 +02:00
|
|
|
|
|
|
|
|
auto handleSocketParameter = [&enableXml, &arguments](const QString &prefix, const QTcpServer &tcpServer)
|
|
|
|
|
{
|
|
|
|
|
QHostAddress serverAddress = tcpServer.serverAddress();
|
|
|
|
|
if (serverAddress.protocol() != QAbstractSocket::IPv4Protocol) {
|
|
|
|
|
// Report will end up in the Application Output pane, i.e. not have
|
|
|
|
|
// clickable items, but that's better than nothing.
|
|
|
|
|
qWarning("Need IPv4 for valgrind");
|
|
|
|
|
enableXml = false;
|
|
|
|
|
} else {
|
|
|
|
|
arguments << QString("%1=%2:%3").arg(prefix).arg(serverAddress.toString())
|
|
|
|
|
.arg(tcpServer.serverPort());
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
handleSocketParameter("--xml-socket", xmlServer);
|
|
|
|
|
handleSocketParameter("--log-socket", logServer);
|
|
|
|
|
|
|
|
|
|
if (enableXml)
|
|
|
|
|
arguments << "--xml=yes";
|
|
|
|
|
}
|
2019-06-04 12:29:07 +02:00
|
|
|
arguments += m_valgrindArguments;
|
2019-06-04 12:10:11 +02:00
|
|
|
|
|
|
|
|
m_valgrindProcess.setProcessChannelMode(channelMode);
|
|
|
|
|
// consider appending our options last so they override any interfering user-supplied options
|
|
|
|
|
// -q as suggested by valgrind manual
|
|
|
|
|
|
2017-06-29 15:03:06 +02:00
|
|
|
connect(&m_valgrindProcess, &ApplicationLauncher::processExited,
|
|
|
|
|
this, &ValgrindRunner::Private::closed);
|
|
|
|
|
connect(&m_valgrindProcess, &ApplicationLauncher::processStarted,
|
|
|
|
|
this, &ValgrindRunner::Private::localProcessStarted);
|
|
|
|
|
connect(&m_valgrindProcess, &ApplicationLauncher::error,
|
|
|
|
|
q, &ValgrindRunner::processError);
|
|
|
|
|
connect(&m_valgrindProcess, &ApplicationLauncher::appendMessage,
|
|
|
|
|
q, &ValgrindRunner::processOutputReceived);
|
|
|
|
|
connect(&m_valgrindProcess, &ApplicationLauncher::finished,
|
|
|
|
|
q, &ValgrindRunner::finished);
|
|
|
|
|
|
|
|
|
|
connect(&m_valgrindProcess, &ApplicationLauncher::remoteStderr,
|
|
|
|
|
this, &ValgrindRunner::Private::handleRemoteStderr);
|
|
|
|
|
connect(&m_valgrindProcess, &ApplicationLauncher::remoteStdout,
|
|
|
|
|
this, &ValgrindRunner::Private::handleRemoteStdout);
|
|
|
|
|
connect(&m_valgrindProcess, &ApplicationLauncher::remoteProcessStarted,
|
|
|
|
|
this, &ValgrindRunner::Private::remoteProcessStarted);
|
|
|
|
|
|
|
|
|
|
if (HostOsInfo::isMacHost())
|
|
|
|
|
// May be slower to start but without it we get no filenames for symbols.
|
2019-06-04 12:29:07 +02:00
|
|
|
arguments << "--dsymutil=yes";
|
|
|
|
|
arguments << m_debuggee.executable;
|
2017-06-29 15:03:06 +02:00
|
|
|
|
2018-05-16 15:42:03 +02:00
|
|
|
Runnable valgrind;
|
2017-06-29 15:03:06 +02:00
|
|
|
valgrind.executable = m_valgrindExecutable;
|
|
|
|
|
valgrind.workingDirectory = m_debuggee.workingDirectory;
|
|
|
|
|
valgrind.environment = m_debuggee.environment;
|
|
|
|
|
valgrind.device = m_device;
|
2019-06-04 12:29:07 +02:00
|
|
|
valgrind.commandLineArguments = QtcProcess::joinArgs(arguments, m_device->osType());
|
2017-06-29 15:03:06 +02:00
|
|
|
Utils::QtcProcess::addArgs(&valgrind.commandLineArguments, m_debuggee.commandLineArguments);
|
2018-01-24 15:09:50 +02:00
|
|
|
emit q->valgrindExecuted(QtcProcess::quoteArg(valgrind.executable) + ' '
|
|
|
|
|
+ valgrind.commandLineArguments);
|
2017-06-29 15:03:06 +02:00
|
|
|
|
|
|
|
|
if (m_device->type() == ProjectExplorer::Constants::DESKTOP_DEVICE_TYPE)
|
|
|
|
|
m_valgrindProcess.start(valgrind);
|
|
|
|
|
else
|
|
|
|
|
m_valgrindProcess.start(valgrind, m_device);
|
2019-06-04 12:10:11 +02:00
|
|
|
|
|
|
|
|
return true;
|
2017-06-29 15:03:06 +02:00
|
|
|
}
|
|
|
|
|
|
2017-07-13 17:59:53 +02:00
|
|
|
void ValgrindRunner::Private::handleRemoteStderr(const QString &b)
|
2017-06-29 15:03:06 +02:00
|
|
|
{
|
|
|
|
|
if (!b.isEmpty())
|
2019-01-16 18:06:21 +01:00
|
|
|
emit q->processOutputReceived(b, Utils::StdErrFormat);
|
2017-06-29 15:03:06 +02:00
|
|
|
}
|
|
|
|
|
|
2017-07-13 17:59:53 +02:00
|
|
|
void ValgrindRunner::Private::handleRemoteStdout(const QString &b)
|
2017-06-29 15:03:06 +02:00
|
|
|
{
|
|
|
|
|
if (!b.isEmpty())
|
2019-01-16 18:06:21 +01:00
|
|
|
emit q->processOutputReceived(b, Utils::StdOutFormat);
|
2017-06-29 15:03:06 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ValgrindRunner::Private::localProcessStarted()
|
|
|
|
|
{
|
|
|
|
|
qint64 pid = m_valgrindProcess.applicationPID().pid();
|
|
|
|
|
emit q->valgrindStarted(pid);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ValgrindRunner::Private::remoteProcessStarted()
|
|
|
|
|
{
|
|
|
|
|
// find out what PID our process has
|
|
|
|
|
|
|
|
|
|
// NOTE: valgrind cloaks its name,
|
|
|
|
|
// e.g.: valgrind --tool=memcheck foobar
|
|
|
|
|
// => ps aux, pidof will see valgrind.bin
|
|
|
|
|
// => pkill/killall/top... will see memcheck-amd64-linux or similar
|
|
|
|
|
// hence we need to do something more complex...
|
|
|
|
|
|
|
|
|
|
// plain path to exe, m_valgrindExe contains e.g. env vars etc. pp.
|
|
|
|
|
const QString proc = m_valgrindExecutable.split(' ').last();
|
|
|
|
|
|
2018-05-16 15:42:03 +02:00
|
|
|
Runnable findPid;
|
2017-06-29 15:03:06 +02:00
|
|
|
findPid.executable = "/bin/sh";
|
|
|
|
|
// sleep required since otherwise we might only match "bash -c..."
|
|
|
|
|
// and not the actual valgrind run
|
|
|
|
|
findPid.commandLineArguments = QString("-c \""
|
|
|
|
|
"sleep 1; ps ax" // list all processes with aliased name
|
|
|
|
|
" | grep '\\b%1.*%2'" // find valgrind process
|
|
|
|
|
" | tail -n 1" // limit to single process
|
|
|
|
|
// we pick the last one, first would be "bash -c ..."
|
|
|
|
|
" | awk '{print $1;}'" // get pid
|
|
|
|
|
"\""
|
2019-05-28 13:49:26 +02:00
|
|
|
).arg(proc, Utils::FilePath::fromString(m_debuggee.executable).fileName());
|
2017-06-29 15:03:06 +02:00
|
|
|
|
|
|
|
|
// m_remote.m_findPID = m_remote.m_connection->createRemoteProcess(cmd.toUtf8());
|
|
|
|
|
connect(&m_findPID, &ApplicationLauncher::remoteStderr,
|
|
|
|
|
this, &ValgrindRunner::Private::handleRemoteStderr);
|
|
|
|
|
connect(&m_findPID, &ApplicationLauncher::remoteStdout,
|
2017-07-13 17:59:53 +02:00
|
|
|
this, &ValgrindRunner::Private::findPidOutputReceived);
|
2017-06-29 15:03:06 +02:00
|
|
|
m_findPID.start(findPid, m_device);
|
|
|
|
|
}
|
|
|
|
|
|
2017-07-13 17:59:53 +02:00
|
|
|
void ValgrindRunner::Private::findPidOutputReceived(const QString &out)
|
2017-06-29 15:03:06 +02:00
|
|
|
{
|
|
|
|
|
if (out.isEmpty())
|
|
|
|
|
return;
|
|
|
|
|
bool ok;
|
|
|
|
|
qint64 pid = out.trimmed().toLongLong(&ok);
|
|
|
|
|
if (!ok) {
|
|
|
|
|
// m_remote.m_errorString = tr("Could not determine remote PID.");
|
|
|
|
|
// emit ValgrindRunner::Private::error(QProcess::FailedToStart);
|
|
|
|
|
// close();
|
|
|
|
|
} else {
|
|
|
|
|
emit q->valgrindStarted(pid);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ValgrindRunner::Private::closed(bool success)
|
|
|
|
|
{
|
|
|
|
|
Q_UNUSED(success);
|
|
|
|
|
// QTC_ASSERT(m_remote.m_process, return);
|
|
|
|
|
|
|
|
|
|
// m_remote.m_errorString = m_remote.m_process->errorString();
|
|
|
|
|
// if (status == QSsh::SshRemoteProcess::FailedToStart) {
|
|
|
|
|
// m_remote.m_error = QProcess::FailedToStart;
|
|
|
|
|
// q->processError(QProcess::FailedToStart);
|
|
|
|
|
// } else if (status == QSsh::SshRemoteProcess::NormalExit) {
|
|
|
|
|
// q->processFinished(m_remote.m_process->exitCode(), QProcess::NormalExit);
|
|
|
|
|
// } else if (status == QSsh::SshRemoteProcess::CrashExit) {
|
|
|
|
|
// m_remote.m_error = QProcess::Crashed;
|
|
|
|
|
// q->processFinished(m_remote.m_process->exitCode(), QProcess::CrashExit);
|
|
|
|
|
// }
|
|
|
|
|
q->processFinished(0, QProcess::NormalExit);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2011-03-04 12:15:18 +01:00
|
|
|
ValgrindRunner::ValgrindRunner(QObject *parent)
|
2017-06-29 15:03:06 +02:00
|
|
|
: QObject(parent), d(new Private(this))
|
2011-03-04 12:15:18 +01:00
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ValgrindRunner::~ValgrindRunner()
|
|
|
|
|
{
|
2017-06-29 15:03:06 +02:00
|
|
|
if (d->m_valgrindProcess.isRunning()) {
|
2011-03-04 12:15:18 +01:00
|
|
|
// make sure we don't delete the thread while it's still running
|
|
|
|
|
waitForFinished();
|
|
|
|
|
}
|
2017-06-21 09:01:48 +02:00
|
|
|
if (d->parser.isRunning()) {
|
2017-06-21 08:08:43 +02:00
|
|
|
// make sure we don't delete the thread while it's still running
|
|
|
|
|
waitForFinished();
|
|
|
|
|
}
|
2011-03-04 12:15:18 +01:00
|
|
|
delete d;
|
2018-12-10 08:11:18 +01:00
|
|
|
d = nullptr;
|
2011-03-04 12:15:18 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ValgrindRunner::setValgrindExecutable(const QString &executable)
|
|
|
|
|
{
|
2017-06-29 15:03:06 +02:00
|
|
|
d->m_valgrindExecutable = executable;
|
2011-03-04 12:15:18 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ValgrindRunner::setValgrindArguments(const QStringList &toolArguments)
|
|
|
|
|
{
|
2017-06-29 15:03:06 +02:00
|
|
|
d->m_valgrindArguments = toolArguments;
|
2014-04-25 12:19:48 +02:00
|
|
|
}
|
|
|
|
|
|
2018-05-16 15:42:03 +02:00
|
|
|
void ValgrindRunner::setDebuggee(const Runnable &debuggee)
|
2011-03-04 12:15:18 +01:00
|
|
|
{
|
2017-06-29 15:03:06 +02:00
|
|
|
d->m_debuggee = debuggee;
|
2014-05-06 00:08:12 +03:00
|
|
|
}
|
|
|
|
|
|
2011-03-04 12:15:18 +01:00
|
|
|
void ValgrindRunner::setProcessChannelMode(QProcess::ProcessChannelMode mode)
|
|
|
|
|
{
|
|
|
|
|
d->channelMode = mode;
|
|
|
|
|
}
|
|
|
|
|
|
2017-06-28 14:53:21 +02:00
|
|
|
void ValgrindRunner::setLocalServerAddress(const QHostAddress &localServerAddress)
|
|
|
|
|
{
|
|
|
|
|
d->localServerAddress = localServerAddress;
|
|
|
|
|
}
|
|
|
|
|
|
2016-01-30 01:38:58 +01:00
|
|
|
void ValgrindRunner::setDevice(const IDevice::ConstPtr &device)
|
2015-06-16 11:48:45 +02:00
|
|
|
{
|
2017-06-29 15:03:06 +02:00
|
|
|
d->m_device = device;
|
2015-06-16 11:48:45 +02:00
|
|
|
}
|
|
|
|
|
|
2018-05-03 18:15:49 +02:00
|
|
|
void ValgrindRunner::setUseTerminal(bool on)
|
|
|
|
|
{
|
|
|
|
|
d->m_valgrindProcess.setUseTerminal(on);
|
|
|
|
|
}
|
|
|
|
|
|
2011-03-04 12:15:18 +01:00
|
|
|
void ValgrindRunner::waitForFinished() const
|
|
|
|
|
{
|
2017-06-29 15:03:06 +02:00
|
|
|
if (d->m_finished)
|
2011-03-04 12:15:18 +01:00
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
QEventLoop loop;
|
2015-02-06 12:39:07 +02:00
|
|
|
connect(this, &ValgrindRunner::finished, &loop, &QEventLoop::quit);
|
2011-03-04 12:15:18 +01:00
|
|
|
loop.exec();
|
|
|
|
|
}
|
|
|
|
|
|
2012-01-20 14:19:44 +01:00
|
|
|
bool ValgrindRunner::start()
|
2011-03-04 12:15:18 +01:00
|
|
|
{
|
2019-06-04 12:10:11 +02:00
|
|
|
return d->run();
|
2011-03-04 12:15:18 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ValgrindRunner::processError(QProcess::ProcessError e)
|
|
|
|
|
{
|
2017-06-29 15:03:06 +02:00
|
|
|
if (d->m_finished)
|
2011-03-04 12:15:18 +01:00
|
|
|
return;
|
|
|
|
|
|
2017-06-29 15:03:06 +02:00
|
|
|
d->m_finished = true;
|
2011-03-04 12:15:18 +01:00
|
|
|
|
|
|
|
|
// make sure we don't wait for the connection anymore
|
|
|
|
|
emit processErrorReceived(errorString(), e);
|
|
|
|
|
emit finished();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ValgrindRunner::processFinished(int ret, QProcess::ExitStatus status)
|
|
|
|
|
{
|
2017-06-20 18:01:25 +02:00
|
|
|
emit extraProcessFinished();
|
|
|
|
|
|
2017-06-29 15:03:06 +02:00
|
|
|
if (d->m_finished)
|
2011-03-04 12:15:18 +01:00
|
|
|
return;
|
|
|
|
|
|
2017-06-29 15:03:06 +02:00
|
|
|
d->m_finished = true;
|
2011-03-04 12:15:18 +01:00
|
|
|
|
|
|
|
|
// make sure we don't wait for the connection anymore
|
|
|
|
|
emit finished();
|
|
|
|
|
|
|
|
|
|
if (ret != 0 || status == QProcess::CrashExit)
|
2017-06-29 15:03:06 +02:00
|
|
|
emit processErrorReceived(errorString(), d->m_valgrindProcess.processError());
|
2011-03-04 12:15:18 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QString ValgrindRunner::errorString() const
|
|
|
|
|
{
|
2017-06-29 15:03:06 +02:00
|
|
|
return d->m_valgrindProcess.errorString();
|
2011-03-04 12:15:18 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ValgrindRunner::stop()
|
|
|
|
|
{
|
2017-06-29 15:03:06 +02:00
|
|
|
d->m_valgrindProcess.stop();
|
2011-04-04 14:39:27 +02:00
|
|
|
}
|
2011-05-18 17:05:49 +02:00
|
|
|
|
2017-06-21 09:01:48 +02:00
|
|
|
XmlProtocol::ThreadedParser *ValgrindRunner::parser() const
|
2017-06-21 08:08:43 +02:00
|
|
|
{
|
2017-06-21 09:01:48 +02:00
|
|
|
return &d->parser;
|
2017-06-21 08:08:43 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ValgrindRunner::xmlSocketConnected()
|
|
|
|
|
{
|
|
|
|
|
QTcpSocket *socket = d->xmlServer.nextPendingConnection();
|
|
|
|
|
QTC_ASSERT(socket, return);
|
|
|
|
|
d->xmlServer.close();
|
2017-06-21 09:01:48 +02:00
|
|
|
d->parser.parse(socket);
|
2017-06-21 08:08:43 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ValgrindRunner::logSocketConnected()
|
|
|
|
|
{
|
|
|
|
|
d->logSocket = d->logServer.nextPendingConnection();
|
|
|
|
|
QTC_ASSERT(d->logSocket, return);
|
|
|
|
|
connect(d->logSocket, &QIODevice::readyRead,
|
|
|
|
|
this, &ValgrindRunner::readLogSocket);
|
|
|
|
|
d->logServer.close();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ValgrindRunner::readLogSocket()
|
|
|
|
|
{
|
|
|
|
|
QTC_ASSERT(d->logSocket, return);
|
|
|
|
|
emit logMessageReceived(d->logSocket->readAll());
|
|
|
|
|
}
|
|
|
|
|
|
2017-06-28 14:53:21 +02:00
|
|
|
bool ValgrindRunner::startServers()
|
2017-06-21 08:08:43 +02:00
|
|
|
{
|
2017-06-28 14:53:21 +02:00
|
|
|
bool check = d->xmlServer.listen(d->localServerAddress);
|
|
|
|
|
const QString ip = d->localServerAddress.toString();
|
2017-06-21 08:08:43 +02:00
|
|
|
if (!check) {
|
|
|
|
|
emit processErrorReceived(tr("XmlServer on %1:").arg(ip) + ' '
|
|
|
|
|
+ d->xmlServer.errorString(), QProcess::FailedToStart );
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
d->xmlServer.setMaxPendingConnections(1);
|
|
|
|
|
connect(&d->xmlServer, &QTcpServer::newConnection,
|
|
|
|
|
this, &ValgrindRunner::xmlSocketConnected);
|
2017-06-28 14:53:21 +02:00
|
|
|
check = d->logServer.listen(d->localServerAddress);
|
2017-06-21 08:08:43 +02:00
|
|
|
if (!check) {
|
|
|
|
|
emit processErrorReceived(tr("LogServer on %1:").arg(ip) + ' '
|
|
|
|
|
+ d->logServer.errorString(), QProcess::FailedToStart );
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
d->logServer.setMaxPendingConnections(1);
|
|
|
|
|
connect(&d->logServer, &QTcpServer::newConnection,
|
|
|
|
|
this, &ValgrindRunner::logSocketConnected);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2011-05-18 17:05:49 +02:00
|
|
|
} // namespace Valgrind
|