Valgrind: Remove CallgrindController's use of ValgrindProcess

It's simply one-shot command execution, using (only some part of) the
ValgrindProcess machinery that just happens to also to wrap a process
is conceptually different from ValgrindProcess that "is" the
valgrind-with-debuggee entity (and an unneeded dependency)

Change-Id: I57a2c3d1cab6b15e59cb41b8e131948c170297b6
Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
This commit is contained in:
hjk
2017-06-28 18:45:57 +02:00
parent ef7c633de2
commit 3418070a4f
9 changed files with 158 additions and 129 deletions

View File

@@ -24,28 +24,31 @@
****************************************************************************/
#include "callgrindcontroller.h"
#include "../valgrindprocess.h"
#include <ssh/sftpchannel.h>
#include <ssh/sshconnectionmanager.h>
#include <utils/fileutils.h>
#include <utils/hostosinfo.h>
#include <utils/qtcassert.h>
#include <utils/qtcprocess.h>
#include <utils/temporaryfile.h>
#include <QDebug>
#include <QDir>
#include <utils/hostosinfo.h>
#include <utils/qtcassert.h>
#include <utils/temporaryfile.h>
#include <ssh/sftpchannel.h>
#include <QEventLoop>
#define CALLGRIND_CONTROL_DEBUG 0
const QLatin1String CALLGRIND_CONTROL_BINARY("callgrind_control");
using namespace ProjectExplorer;
using namespace Utils;
namespace Valgrind {
namespace Callgrind {
CallgrindController::CallgrindController(QObject *parent)
: QObject(parent)
, m_process(0)
, m_valgrindProc(0)
, m_lastOption(Unknown)
const QLatin1String CALLGRIND_CONTROL_BINARY("callgrind_control");
CallgrindController::CallgrindController()
{
}
@@ -54,7 +57,7 @@ CallgrindController::~CallgrindController()
cleanupTempFile();
}
QString toOptionString(CallgrindController::Option option)
static QString toOptionString(CallgrindController::Option option)
{
/* callgrind_control help from v3.9.0
@@ -86,23 +89,15 @@ QString toOptionString(CallgrindController::Option option)
void CallgrindController::run(Option option)
{
if (m_process) {
if (m_controllerProcess) {
emit statusMessage(tr("Previous command has not yet finished."));
return;
}
QTC_ASSERT(m_valgrindProc, return);
m_process = new ValgrindProcess(m_valgrindProc->device(), this);
connect(m_process, &ValgrindProcess::finished,
this, &CallgrindController::processFinished);
connect(m_process, &ValgrindProcess::error,
this, &CallgrindController::processError);
// save back current running operation
m_lastOption = option;
const QString optionString = toOptionString(option);
m_controllerProcess = new ApplicationLauncher;
switch (option) {
case CallgrindController::Dump:
@@ -122,31 +117,49 @@ void CallgrindController::run(Option option)
}
#if CALLGRIND_CONTROL_DEBUG
m_process->setProcessChannelMode(QProcess::ForwardedChannels);
m_controllerProcess->setProcessChannelMode(QProcess::ForwardedChannels);
#endif
const int pid = Utils::HostOsInfo::isWindowsHost() ? 0 : m_valgrindProc->pid();
m_process->setValgrindExecutable(CALLGRIND_CONTROL_BINARY);
m_process->setValgrindArguments(QStringList() << optionString << QString::number(pid));
m_process->run(ProjectExplorer::ApplicationLauncher::Gui);
connect(m_controllerProcess, &ApplicationLauncher::processExited,
this, &CallgrindController::controllerProcessFinished);
connect(m_controllerProcess, &ApplicationLauncher::error,
this, &CallgrindController::handleControllerProcessError);
connect(m_controllerProcess, &ApplicationLauncher::finished,
this, &CallgrindController::controllerProcessClosed);
StandardRunnable controller = m_valgrindRunnable;
controller.executable = CALLGRIND_CONTROL_BINARY;
controller.runMode = ApplicationLauncher::Gui;
controller.commandLineArguments = QString("%1 %2").arg(toOptionString(option)).arg(m_pid);
if (!m_valgrindRunnable.device
|| m_valgrindRunnable.device->type() == ProjectExplorer::Constants::DESKTOP_DEVICE_TYPE)
m_controllerProcess->start(controller);
else
m_controllerProcess->start(controller, m_valgrindRunnable.device);
}
void CallgrindController::processError(QProcess::ProcessError)
void CallgrindController::setValgrindPid(qint64 pid)
{
QTC_ASSERT(m_process, return);
const QString error = m_process->errorString();
m_pid = pid;
}
void CallgrindController::handleControllerProcessError(QProcess::ProcessError)
{
QTC_ASSERT(m_controllerProcess, return);
const QString error = m_controllerProcess->errorString();
emit statusMessage(tr("An error occurred while trying to run %1: %2").arg(CALLGRIND_CONTROL_BINARY).arg(error));
m_process->deleteLater();
m_process = 0;
m_controllerProcess->deleteLater();
m_controllerProcess = nullptr;
}
void CallgrindController::processFinished(int rc, QProcess::ExitStatus status)
void CallgrindController::controllerProcessFinished(int rc, QProcess::ExitStatus status)
{
QTC_ASSERT(m_process, return);
const QString error = m_process->errorString();
QTC_ASSERT(m_controllerProcess, return);
const QString error = m_controllerProcess->errorString();
m_process->deleteLater(); // Called directly from finished() signal in m_process
m_process = 0;
m_controllerProcess->deleteLater(); // Called directly from finished() signal in m_process
m_controllerProcess = nullptr;
if (rc != 0 || status != QProcess::NormalExit) {
qWarning() << "Controller exited abnormally:" << error;
@@ -175,23 +188,34 @@ void CallgrindController::processFinished(int rc, QProcess::ExitStatus status)
m_lastOption = Unknown;
}
void CallgrindController::setValgrindProcess(ValgrindProcess *proc)
void CallgrindController::controllerProcessClosed(bool success)
{
m_valgrindProc = proc;
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;
// emit ValgrindProcessX::error(QProcess::FailedToStart);
// } else if (status == QSsh::SshRemoteProcess::NormalExit) {
// emit finished(m_remote.m_process->exitCode(), QProcess::NormalExit);
// } else if (status == QSsh::SshRemoteProcess::CrashExit) {
// m_remote.m_error = QProcess::Crashed;
// emit finished(m_remote.m_process->exitCode(), QProcess::CrashExit);
// }
controllerProcessFinished(0, QProcess::NormalExit);
}
void CallgrindController::getLocalDataFile()
{
QTC_ASSERT(m_valgrindProc, return);
// we look for callgrind.out.PID, but there may be updated ones called ~.PID.NUM
QString baseFileName = QString::fromLatin1("callgrind.out.%1").
arg(m_valgrindProc->pid());
const QString workingDir = m_valgrindProc->workingDirectory();
const QString baseFileName = QString("callgrind.out.%1").arg(m_pid);
const QString workingDir = m_valgrindRunnable.workingDirectory;
// first, set the to-be-parsed file to callgrind.out.PID
QString fileName = workingDir.isEmpty() ? baseFileName : (workingDir + QLatin1Char('/') + baseFileName);
QString fileName = workingDir.isEmpty() ? baseFileName : (workingDir + '/' + baseFileName);
if (!m_valgrindProc->isLocal()) {
if (m_valgrindRunnable.device
&& m_valgrindRunnable.device->type() != ProjectExplorer::Constants::DESKTOP_DEVICE_TYPE) {
// ///TODO: error handling
// emit statusMessage(tr("Downloading remote profile data..."));
// m_ssh = m_valgrindProc->connection();
@@ -254,5 +278,11 @@ void CallgrindController::cleanupTempFile()
m_tempDataFile.clear();
}
void CallgrindController::setValgrindRunnable(const Runnable &runnable)
{
QTC_ASSERT(runnable.is<StandardRunnable>(), return);
m_valgrindRunnable = runnable.as<StandardRunnable>();
}
} // namespace Callgrind
} // namespace Valgrind