Valgrind: Support console applications

Task-number: QTCREATORBUG-7311
Change-Id: I973136076118fd8868c6cb461ad31e107c73566e
Reviewed-by: Christian Kandeler <christian.kandeler@digia.com>
This commit is contained in:
Orgad Shaneh
2014-05-06 00:08:12 +03:00
committed by Orgad Shaneh
parent 3089c8b1df
commit 60cd217981
13 changed files with 75 additions and 41 deletions

View File

@@ -38,6 +38,7 @@
#include <ssh/sshconnection.h> #include <ssh/sshconnection.h>
#include <utils/environment.h> #include <utils/environment.h>
#include <projectexplorer/projectexplorerconstants.h> #include <projectexplorer/projectexplorerconstants.h>
#include <projectexplorer/applicationlauncher.h>
namespace Analyzer { namespace Analyzer {
@@ -47,12 +48,15 @@ namespace Analyzer {
class ANALYZER_EXPORT AnalyzerStartParameters class ANALYZER_EXPORT AnalyzerStartParameters
{ {
public: public:
AnalyzerStartParameters() : analyzerPort(0) AnalyzerStartParameters()
: localRunMode(ProjectExplorer::ApplicationLauncher::Gui)
, analyzerPort(0)
{} {}
StartMode startMode; StartMode startMode;
ProjectExplorer::RunMode runMode; ProjectExplorer::RunMode runMode;
QSsh::SshConnectionParameters connParams; QSsh::SshConnectionParameters connParams;
ProjectExplorer::ApplicationLauncher::Mode localRunMode;
QString debuggee; QString debuggee;
QString debuggeeArgs; QString debuggeeArgs;

View File

@@ -59,3 +59,5 @@ SOURCES += $$PWD/xmlprotocol/error.cpp \
$$PWD/memcheck/memcheckrunner.cpp \ $$PWD/memcheck/memcheckrunner.cpp \
$$PWD/valgrindrunner.cpp \ $$PWD/valgrindrunner.cpp \
$$PWD/valgrindprocess.cpp $$PWD/valgrindprocess.cpp
LIBS += -L$$IDE_PLUGIN_PATH/QtProject

View File

@@ -108,6 +108,7 @@ bool ValgrindRunControl::startEngine()
run->setEnvironment(sp.environment); run->setEnvironment(sp.environment);
run->setConnectionParameters(sp.connParams); run->setConnectionParameters(sp.connParams);
run->setStartMode(sp.startMode); run->setStartMode(sp.startMode);
run->setLocalRunMode(sp.localRunMode);
connect(run, SIGNAL(processOutputReceived(QString,Utils::OutputFormat)), connect(run, SIGNAL(processOutputReceived(QString,Utils::OutputFormat)),
SLOT(receiveProcessOutput(QString,Utils::OutputFormat))); SLOT(receiveProcessOutput(QString,Utils::OutputFormat)));

View File

@@ -35,6 +35,7 @@
#include <QFileInfo> #include <QFileInfo>
#include <utils/qtcassert.h> #include <utils/qtcassert.h>
#include <utils/qtcprocess.h>
namespace Valgrind { namespace Valgrind {
@@ -74,7 +75,7 @@ QString ValgrindProcess::workingDirectory() const
bool ValgrindProcess::isRunning() const bool ValgrindProcess::isRunning() const
{ {
if (isLocal()) if (isLocal())
return m_localProcess.state() != QProcess::NotRunning; return m_localProcess.isRunning();
else else
return m_remote.m_process && m_remote.m_process->isRunning(); return m_remote.m_process && m_remote.m_process->isRunning();
} }
@@ -106,10 +107,15 @@ void ValgrindProcess::setEnvironment(const Utils::Environment &environment)
///TODO: remote anything that should/could be done here? ///TODO: remote anything that should/could be done here?
} }
void ValgrindProcess::setLocalRunMode(ProjectExplorer::ApplicationLauncher::Mode localRunMode)
{
m_localRunMode = localRunMode;
}
void ValgrindProcess::close() void ValgrindProcess::close()
{ {
if (isLocal()) { if (isLocal()) {
m_localProcess.terminate(); m_localProcess.stop();
} else { } else {
QTC_ASSERT(m_remote.m_connection->state() == QSsh::SshConnection::Connected, return); QTC_ASSERT(m_remote.m_connection->state() == QSsh::SshConnection::Connected, return);
if (m_remote.m_process) { if (m_remote.m_process) {
@@ -131,22 +137,18 @@ void ValgrindProcess::close()
void ValgrindProcess::run() void ValgrindProcess::run()
{ {
if (isLocal()) { if (isLocal()) {
connect(&m_localProcess, SIGNAL(finished(int,QProcess::ExitStatus)), connect(&m_localProcess, SIGNAL(processExited(int,QProcess::ExitStatus)),
this, SIGNAL(finished(int,QProcess::ExitStatus))); this, SIGNAL(finished(int,QProcess::ExitStatus)));
connect(&m_localProcess, SIGNAL(started()), connect(&m_localProcess, SIGNAL(processStarted()),
this, SIGNAL(started())); this, SLOT(localProcessStarted()));
connect(&m_localProcess, SIGNAL(error(QProcess::ProcessError)), connect(&m_localProcess, SIGNAL(error(QProcess::ProcessError)),
this, SIGNAL(error(QProcess::ProcessError))); this, SIGNAL(error(QProcess::ProcessError)));
connect(&m_localProcess, SIGNAL(readyReadStandardError()), connect(&m_localProcess, SIGNAL(appendMessage(QString,Utils::OutputFormat)),
this, SLOT(handleReadyReadStandardError())); this, SIGNAL(processOutput(QString,Utils::OutputFormat)));
connect(&m_localProcess, SIGNAL(readyReadStandardOutput()),
this, SLOT(handleReadyReadStandardOutput())); m_localProcess.start(m_localRunMode, m_valgrindExecutable,
argumentString(Utils::HostOsInfo::hostOs()));
m_localProcess.setCommand(m_valgrindExecutable,
argumentString(Utils::HostOsInfo::hostOs()));
m_localProcess.start();
m_localProcess.waitForStarted();
m_pid = Utils::qPidToPid(m_localProcess.pid());
} else { } else {
m_remote.m_valgrindExe = m_valgrindExecutable; m_remote.m_valgrindExe = m_valgrindExecutable;
m_remote.m_debuggee = m_debuggeeExecutable; m_remote.m_debuggee = m_debuggeeExecutable;
@@ -204,26 +206,18 @@ qint64 ValgrindProcess::pid() const
return m_pid; return m_pid;
} }
void ValgrindProcess::handleReadyReadStandardError() void ValgrindProcess::handleRemoteStderr()
{ {
QByteArray b; const QString b = QString::fromLocal8Bit(m_remote.m_process->readAllStandardError());
if (isLocal())
b = m_localProcess.readAllStandardError();
else
b = m_remote.m_process->readAllStandardError();
if (!b.isEmpty()) if (!b.isEmpty())
emit processOutput(QString::fromLocal8Bit(b), Utils::StdErrFormat); emit processOutput(b, Utils::StdErrFormat);
} }
void ValgrindProcess::handleReadyReadStandardOutput() void ValgrindProcess::handleRemoteStdout()
{ {
QByteArray b; const QString b = QString::fromLocal8Bit(m_remote.m_process->readAllStandardOutput());
if (isLocal())
b = m_localProcess.readAllStandardOutput();
else
b = m_remote.m_process->readAllStandardOutput();
if (!b.isEmpty()) if (!b.isEmpty())
emit processOutput(QString::fromLocal8Bit(b), Utils::StdOutFormat); emit processOutput(b, Utils::StdOutFormat);
} }
/// Remote /// Remote
@@ -243,23 +237,28 @@ void ValgrindProcess::connected()
m_remote.m_process = m_remote.m_connection->createRemoteProcess(cmd.toUtf8()); m_remote.m_process = m_remote.m_connection->createRemoteProcess(cmd.toUtf8());
connect(m_remote.m_process.data(), SIGNAL(readyReadStandardError()), connect(m_remote.m_process.data(), SIGNAL(readyReadStandardError()),
this, SLOT(handleReadyReadStandardError())); this, SLOT(handleRemoteStderr()));
connect(m_remote.m_process.data(), SIGNAL(readyReadStandardOutput()), connect(m_remote.m_process.data(), SIGNAL(readyReadStandardOutput()),
this, SLOT(handleReadyReadStandardOutput())); this, SLOT(handleRemoteStdout()));
connect(m_remote.m_process.data(), SIGNAL(closed(int)), connect(m_remote.m_process.data(), SIGNAL(closed(int)),
this, SLOT(closed(int))); this, SLOT(closed(int)));
connect(m_remote.m_process.data(), SIGNAL(started()), connect(m_remote.m_process.data(), SIGNAL(started()),
this, SLOT(processStarted())); this, SLOT(remoteProcessStarted()));
m_remote.m_process->start(); m_remote.m_process->start();
} }
QSsh::SshConnection *ValgrindProcess::connection() const QSsh::SshConnection *ValgrindProcess::connection() const
{ {
return m_remote.m_connection; return m_remote.m_connection;
} }
void ValgrindProcess::processStarted() void ValgrindProcess::localProcessStarted()
{
m_pid = m_localProcess.applicationPID();
emit started();
}
void ValgrindProcess::remoteProcessStarted()
{ {
QTC_ASSERT(m_remote.m_connection->state() == QSsh::SshConnection::Connected, return); QTC_ASSERT(m_remote.m_connection->state() == QSsh::SshConnection::Connected, return);
@@ -284,7 +283,7 @@ void ValgrindProcess::processStarted()
m_remote.m_findPID = m_remote.m_connection->createRemoteProcess(cmd.toUtf8()); m_remote.m_findPID = m_remote.m_connection->createRemoteProcess(cmd.toUtf8());
connect(m_remote.m_findPID.data(), SIGNAL(readyReadStandardError()), connect(m_remote.m_findPID.data(), SIGNAL(readyReadStandardError()),
this, SLOT(handleReadyReadStandardError())); this, SLOT(handleRemoteStderr()));
connect(m_remote.m_findPID.data(), SIGNAL(readyReadStandardOutput()), connect(m_remote.m_findPID.data(), SIGNAL(readyReadStandardOutput()),
this, SLOT(findPIDOutputReceived())); this, SLOT(findPIDOutputReceived()));
m_remote.m_findPID->start(); m_remote.m_findPID->start();

View File

@@ -31,7 +31,8 @@
#ifndef VALGRINDPROCESS_H #ifndef VALGRINDPROCESS_H
#define VALGRINDPROCESS_H #define VALGRINDPROCESS_H
#include <utils/qtcprocess.h> #include <projectexplorer/applicationlauncher.h>
#include <ssh/sshremoteprocess.h> #include <ssh/sshremoteprocess.h>
#include <ssh/sshconnection.h> #include <ssh/sshconnection.h>
#include <utils/osspecificaspects.h> #include <utils/osspecificaspects.h>
@@ -79,6 +80,7 @@ public:
void setWorkingDirectory(const QString &path); void setWorkingDirectory(const QString &path);
QString workingDirectory() const; QString workingDirectory() const;
void setEnvironment(const Utils::Environment &environment); void setEnvironment(const Utils::Environment &environment);
void setLocalRunMode(ProjectExplorer::ApplicationLauncher::Mode localRunMode);
qint64 pid() const; qint64 pid() const;
QSsh::SshConnection *connection() const; QSsh::SshConnection *connection() const;
@@ -92,19 +94,21 @@ signals:
void localHostAddressRetrieved(const QHostAddress &localHostAddress); void localHostAddressRetrieved(const QHostAddress &localHostAddress);
private slots: private slots:
void handleReadyReadStandardError(); void handleRemoteStderr();
void handleReadyReadStandardOutput(); void handleRemoteStdout();
void handleError(QSsh::SshError); void handleError(QSsh::SshError);
void closed(int); void closed(int);
void connected(); void connected();
void processStarted(); void localProcessStarted();
void remoteProcessStarted();
void findPIDOutputReceived(); void findPIDOutputReceived();
private: private:
QString argumentString(Utils::OsType osType) const; QString argumentString(Utils::OsType osType) const;
Utils::QtcProcess m_localProcess; ProjectExplorer::ApplicationLauncher m_localProcess;
qint64 m_pid; qint64 m_pid;
Remote m_remote; Remote m_remote;
@@ -113,6 +117,7 @@ private:
QString m_debuggeeExecutable; QString m_debuggeeExecutable;
QString m_debuggeeArguments; QString m_debuggeeArguments;
bool m_isLocal; bool m_isLocal;
ProjectExplorer::ApplicationLauncher::Mode m_localRunMode;
}; };

View File

@@ -94,6 +94,7 @@ RunControl *ValgrindRunControlFactory::create(RunConfiguration *runConfiguration
sp.connParams.host = server.serverAddress().toString(); sp.connParams.host = server.serverAddress().toString();
sp.connParams.port = server.serverPort(); sp.connParams.port = server.serverPort();
sp.startMode = StartLocal; sp.startMode = StartLocal;
sp.localRunMode = static_cast<ProjectExplorer::ApplicationLauncher::Mode>(rc1->runMode());
} else if (RemoteLinux::AbstractRemoteLinuxRunConfiguration *rc2 = } else if (RemoteLinux::AbstractRemoteLinuxRunConfiguration *rc2 =
qobject_cast<RemoteLinux::AbstractRemoteLinuxRunConfiguration *>(runConfiguration)) { qobject_cast<RemoteLinux::AbstractRemoteLinuxRunConfiguration *>(runConfiguration)) {
sp.startMode = StartRemote; sp.startMode = StartRemote;

View File

@@ -50,7 +50,8 @@ public:
process(0), process(0),
channelMode(QProcess::SeparateChannels), channelMode(QProcess::SeparateChannels),
finished(false), finished(false),
startMode(Analyzer::StartLocal) startMode(Analyzer::StartLocal),
localRunMode(ProjectExplorer::ApplicationLauncher::Gui)
{ {
} }
@@ -67,6 +68,7 @@ public:
QString debuggeeArguments; QString debuggeeArguments;
QString workingdir; QString workingdir;
Analyzer::StartMode startMode; Analyzer::StartMode startMode;
ProjectExplorer::ApplicationLauncher::Mode localRunMode;
QSsh::SshConnectionParameters connParams; QSsh::SshConnectionParameters connParams;
}; };
@@ -87,6 +89,7 @@ void ValgrindRunner::Private::run(ValgrindProcess *_process)
process->setWorkingDirectory(workingdir); process->setWorkingDirectory(workingdir);
process->setProcessChannelMode(channelMode); process->setProcessChannelMode(channelMode);
process->setLocalRunMode(localRunMode);
// consider appending our options last so they override any interfering user-supplied options // consider appending our options last so they override any interfering user-supplied options
// -q as suggested by valgrind manual // -q as suggested by valgrind manual
@@ -179,6 +182,16 @@ Analyzer::StartMode ValgrindRunner::startMode() const
return d->startMode; return d->startMode;
} }
void ValgrindRunner::setLocalRunMode(ProjectExplorer::ApplicationLauncher::Mode localRunMode)
{
d->localRunMode = localRunMode;
}
ProjectExplorer::ApplicationLauncher::Mode ValgrindRunner::localRunMode() const
{
return d->localRunMode;
}
void ValgrindRunner::setStartMode(Analyzer::StartMode startMode) void ValgrindRunner::setStartMode(Analyzer::StartMode startMode)
{ {
d->startMode = startMode; d->startMode = startMode;

View File

@@ -32,6 +32,7 @@
#define VALGRIND_RUNNER_H #define VALGRIND_RUNNER_H
#include <analyzerbase/analyzerconstants.h> #include <analyzerbase/analyzerconstants.h>
#include <projectexplorer/applicationlauncher.h>
#include <utils/outputformat.h> #include <utils/outputformat.h>
#include <ssh/sshconnection.h> #include <ssh/sshconnection.h>
@@ -73,6 +74,9 @@ public:
void setStartMode(Analyzer::StartMode startMode); void setStartMode(Analyzer::StartMode startMode);
Analyzer::StartMode startMode() const; Analyzer::StartMode startMode() const;
void setLocalRunMode(ProjectExplorer::ApplicationLauncher::Mode localRunMode);
ProjectExplorer::ApplicationLauncher::Mode localRunMode() const;
void setConnectionParameters(const QSsh::SshConnectionParameters &connParams); void setConnectionParameters(const QSsh::SshConnectionParameters &connParams);
const QSsh::SshConnectionParameters &connectionParameters() const; const QSsh::SshConnectionParameters &connectionParameters() const;

View File

@@ -1,4 +1,5 @@
QTC_LIB_DEPENDS += utils ssh QTC_LIB_DEPENDS += utils ssh
QTC_PLUGIN_DEPENDS += projectexplorer
include(../../qttest.pri) include(../../qttest.pri)
include($$IDE_SOURCE_TREE/src/plugins/valgrind/valgrind_test.pri) include($$IDE_SOURCE_TREE/src/plugins/valgrind/valgrind_test.pri)
TARGET = tst_callgrindparsertests TARGET = tst_callgrindparsertests

View File

@@ -1,4 +1,5 @@
QTC_LIB_DEPENDS += utils ssh QTC_LIB_DEPENDS += utils ssh
QTC_PLUGIN_DEPENDS += projectexplorer
include(../../../../qtcreator.pri) include(../../../../qtcreator.pri)
include(../../qttestrpath.pri) include(../../qttestrpath.pri)
include($$IDE_SOURCE_TREE/src/plugins/valgrind/valgrind_test.pri) include($$IDE_SOURCE_TREE/src/plugins/valgrind/valgrind_test.pri)

View File

@@ -1,4 +1,5 @@
QTC_LIB_DEPENDS += utils ssh QTC_LIB_DEPENDS += utils ssh
QTC_PLUGIN_DEPENDS += projectexplorer
include(../../qttest.pri) include(../../qttest.pri)
include($$IDE_SOURCE_TREE/src/plugins/valgrind/valgrind_test.pri) include($$IDE_SOURCE_TREE/src/plugins/valgrind/valgrind_test.pri)

View File

@@ -1,4 +1,5 @@
QTC_LIB_DEPENDS += utils ssh QTC_LIB_DEPENDS += utils ssh
QTC_PLUGIN_DEPENDS += projectexplorer
include(../../qttest.pri) include(../../qttest.pri)
include($$IDE_SOURCE_TREE/src/plugins/valgrind/valgrind_test.pri) include($$IDE_SOURCE_TREE/src/plugins/valgrind/valgrind_test.pri)

View File

@@ -4,6 +4,7 @@ import QtcAutotest
QtcAutotest { QtcAutotest {
Depends { name: "QtcSsh" } Depends { name: "QtcSsh" }
Depends { name: "Utils" } Depends { name: "Utils" }
Depends { name: "ProjectExplorer" }
Depends { name: "Qt.widgets" } // TODO: Remove when qbs bug is fixed Depends { name: "Qt.widgets" } // TODO: Remove when qbs bug is fixed
property path pluginDir: project.ide_source_tree + "/src/plugins/valgrind" property path pluginDir: project.ide_source_tree + "/src/plugins/valgrind"