forked from qt-creator/qt-creator
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:
@@ -24,28 +24,31 @@
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#include "callgrindcontroller.h"
|
#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 <QDebug>
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
|
#include <QEventLoop>
|
||||||
#include <utils/hostosinfo.h>
|
|
||||||
#include <utils/qtcassert.h>
|
|
||||||
#include <utils/temporaryfile.h>
|
|
||||||
#include <ssh/sftpchannel.h>
|
|
||||||
|
|
||||||
#define CALLGRIND_CONTROL_DEBUG 0
|
#define CALLGRIND_CONTROL_DEBUG 0
|
||||||
|
|
||||||
const QLatin1String CALLGRIND_CONTROL_BINARY("callgrind_control");
|
using namespace ProjectExplorer;
|
||||||
|
using namespace Utils;
|
||||||
|
|
||||||
namespace Valgrind {
|
namespace Valgrind {
|
||||||
namespace Callgrind {
|
namespace Callgrind {
|
||||||
|
|
||||||
CallgrindController::CallgrindController(QObject *parent)
|
const QLatin1String CALLGRIND_CONTROL_BINARY("callgrind_control");
|
||||||
: QObject(parent)
|
|
||||||
, m_process(0)
|
CallgrindController::CallgrindController()
|
||||||
, m_valgrindProc(0)
|
|
||||||
, m_lastOption(Unknown)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -54,7 +57,7 @@ CallgrindController::~CallgrindController()
|
|||||||
cleanupTempFile();
|
cleanupTempFile();
|
||||||
}
|
}
|
||||||
|
|
||||||
QString toOptionString(CallgrindController::Option option)
|
static QString toOptionString(CallgrindController::Option option)
|
||||||
{
|
{
|
||||||
/* callgrind_control help from v3.9.0
|
/* callgrind_control help from v3.9.0
|
||||||
|
|
||||||
@@ -86,23 +89,15 @@ QString toOptionString(CallgrindController::Option option)
|
|||||||
|
|
||||||
void CallgrindController::run(Option option)
|
void CallgrindController::run(Option option)
|
||||||
{
|
{
|
||||||
if (m_process) {
|
if (m_controllerProcess) {
|
||||||
emit statusMessage(tr("Previous command has not yet finished."));
|
emit statusMessage(tr("Previous command has not yet finished."));
|
||||||
return;
|
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
|
// save back current running operation
|
||||||
m_lastOption = option;
|
m_lastOption = option;
|
||||||
|
|
||||||
const QString optionString = toOptionString(option);
|
m_controllerProcess = new ApplicationLauncher;
|
||||||
|
|
||||||
switch (option) {
|
switch (option) {
|
||||||
case CallgrindController::Dump:
|
case CallgrindController::Dump:
|
||||||
@@ -122,31 +117,49 @@ void CallgrindController::run(Option option)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if CALLGRIND_CONTROL_DEBUG
|
#if CALLGRIND_CONTROL_DEBUG
|
||||||
m_process->setProcessChannelMode(QProcess::ForwardedChannels);
|
m_controllerProcess->setProcessChannelMode(QProcess::ForwardedChannels);
|
||||||
#endif
|
#endif
|
||||||
const int pid = Utils::HostOsInfo::isWindowsHost() ? 0 : m_valgrindProc->pid();
|
connect(m_controllerProcess, &ApplicationLauncher::processExited,
|
||||||
m_process->setValgrindExecutable(CALLGRIND_CONTROL_BINARY);
|
this, &CallgrindController::controllerProcessFinished);
|
||||||
m_process->setValgrindArguments(QStringList() << optionString << QString::number(pid));
|
connect(m_controllerProcess, &ApplicationLauncher::error,
|
||||||
m_process->run(ProjectExplorer::ApplicationLauncher::Gui);
|
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);
|
m_pid = pid;
|
||||||
const QString error = m_process->errorString();
|
}
|
||||||
|
|
||||||
|
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));
|
emit statusMessage(tr("An error occurred while trying to run %1: %2").arg(CALLGRIND_CONTROL_BINARY).arg(error));
|
||||||
|
|
||||||
m_process->deleteLater();
|
m_controllerProcess->deleteLater();
|
||||||
m_process = 0;
|
m_controllerProcess = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CallgrindController::processFinished(int rc, QProcess::ExitStatus status)
|
void CallgrindController::controllerProcessFinished(int rc, QProcess::ExitStatus status)
|
||||||
{
|
{
|
||||||
QTC_ASSERT(m_process, return);
|
QTC_ASSERT(m_controllerProcess, return);
|
||||||
const QString error = m_process->errorString();
|
const QString error = m_controllerProcess->errorString();
|
||||||
|
|
||||||
m_process->deleteLater(); // Called directly from finished() signal in m_process
|
m_controllerProcess->deleteLater(); // Called directly from finished() signal in m_process
|
||||||
m_process = 0;
|
m_controllerProcess = nullptr;
|
||||||
|
|
||||||
if (rc != 0 || status != QProcess::NormalExit) {
|
if (rc != 0 || status != QProcess::NormalExit) {
|
||||||
qWarning() << "Controller exited abnormally:" << error;
|
qWarning() << "Controller exited abnormally:" << error;
|
||||||
@@ -175,23 +188,34 @@ void CallgrindController::processFinished(int rc, QProcess::ExitStatus status)
|
|||||||
m_lastOption = Unknown;
|
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()
|
void CallgrindController::getLocalDataFile()
|
||||||
{
|
{
|
||||||
QTC_ASSERT(m_valgrindProc, return);
|
|
||||||
|
|
||||||
// we look for callgrind.out.PID, but there may be updated ones called ~.PID.NUM
|
// we look for callgrind.out.PID, but there may be updated ones called ~.PID.NUM
|
||||||
QString baseFileName = QString::fromLatin1("callgrind.out.%1").
|
const QString baseFileName = QString("callgrind.out.%1").arg(m_pid);
|
||||||
arg(m_valgrindProc->pid());
|
const QString workingDir = m_valgrindRunnable.workingDirectory;
|
||||||
const QString workingDir = m_valgrindProc->workingDirectory();
|
|
||||||
// first, set the to-be-parsed file to callgrind.out.PID
|
// 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
|
// ///TODO: error handling
|
||||||
// emit statusMessage(tr("Downloading remote profile data..."));
|
// emit statusMessage(tr("Downloading remote profile data..."));
|
||||||
// m_ssh = m_valgrindProc->connection();
|
// m_ssh = m_valgrindProc->connection();
|
||||||
@@ -254,5 +278,11 @@ void CallgrindController::cleanupTempFile()
|
|||||||
m_tempDataFile.clear();
|
m_tempDataFile.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CallgrindController::setValgrindRunnable(const Runnable &runnable)
|
||||||
|
{
|
||||||
|
QTC_ASSERT(runnable.is<StandardRunnable>(), return);
|
||||||
|
m_valgrindRunnable = runnable.as<StandardRunnable>();
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Callgrind
|
} // namespace Callgrind
|
||||||
} // namespace Valgrind
|
} // namespace Valgrind
|
||||||
|
|||||||
@@ -25,18 +25,15 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <QObject>
|
|
||||||
|
|
||||||
#include <qprocess.h>
|
|
||||||
|
|
||||||
#include <ssh/sshconnection.h>
|
|
||||||
#include <ssh/sshremoteprocess.h>
|
#include <ssh/sshremoteprocess.h>
|
||||||
#include <ssh/sftpchannel.h>
|
#include <ssh/sftpchannel.h>
|
||||||
|
#include <ssh/sshconnection.h>
|
||||||
|
|
||||||
|
#include <projectexplorer/runnables.h>
|
||||||
|
|
||||||
|
#include <QProcess>
|
||||||
|
|
||||||
namespace Valgrind {
|
namespace Valgrind {
|
||||||
|
|
||||||
class ValgrindProcess;
|
|
||||||
|
|
||||||
namespace Callgrind {
|
namespace Callgrind {
|
||||||
|
|
||||||
class CallgrindController : public QObject
|
class CallgrindController : public QObject
|
||||||
@@ -49,16 +46,14 @@ public:
|
|||||||
Unknown,
|
Unknown,
|
||||||
Dump,
|
Dump,
|
||||||
ResetEventCounters,
|
ResetEventCounters,
|
||||||
Pause, UnPause
|
Pause,
|
||||||
|
UnPause
|
||||||
};
|
};
|
||||||
|
|
||||||
explicit CallgrindController(QObject *parent = 0);
|
CallgrindController();
|
||||||
virtual ~CallgrindController();
|
~CallgrindController() override;
|
||||||
|
|
||||||
void run(Valgrind::Callgrind::CallgrindController::Option option);
|
void run(Option option);
|
||||||
|
|
||||||
void setValgrindProcess(ValgrindProcess *process);
|
|
||||||
ValgrindProcess *valgrindProcess() { return m_valgrindProc; }
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Make data file available locally, triggers @c localParseDataAvailable.
|
* Make data file available locally, triggers @c localParseDataAvailable.
|
||||||
@@ -67,32 +62,34 @@ public:
|
|||||||
* downloads the data file first and returns a local path.
|
* downloads the data file first and returns a local path.
|
||||||
*/
|
*/
|
||||||
void getLocalDataFile();
|
void getLocalDataFile();
|
||||||
|
void setValgrindPid(qint64 pid);
|
||||||
|
void setValgrindRunnable(const ProjectExplorer::Runnable &runnable);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void finished(Valgrind::Callgrind::CallgrindController::Option option);
|
void finished(Valgrind::Callgrind::CallgrindController::Option option);
|
||||||
|
|
||||||
void localParseDataAvailable(const QString &file);
|
void localParseDataAvailable(const QString &file);
|
||||||
|
|
||||||
void statusMessage(const QString &msg);
|
void statusMessage(const QString &msg);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void processError(QProcess::ProcessError);
|
void handleControllerProcessError(QProcess::ProcessError);
|
||||||
void processFinished(int, QProcess::ExitStatus);
|
|
||||||
|
|
||||||
void foundRemoteFile();
|
void foundRemoteFile();
|
||||||
void sftpInitialized();
|
void sftpInitialized();
|
||||||
void sftpJobFinished(QSsh::SftpJobId job, const QString &error);
|
void sftpJobFinished(QSsh::SftpJobId job, const QString &error);
|
||||||
void cleanupTempFile();
|
void cleanupTempFile();
|
||||||
|
|
||||||
// callgrind_control process
|
void controllerProcessFinished(int, QProcess::ExitStatus);
|
||||||
Valgrind::ValgrindProcess *m_process;
|
void controllerProcessError(QProcess::ProcessError);
|
||||||
// valgrind process
|
void controllerProcessClosed(bool success);
|
||||||
Valgrind::ValgrindProcess *m_valgrindProc;
|
|
||||||
|
|
||||||
Option m_lastOption;
|
ProjectExplorer::ApplicationLauncher *m_controllerProcess;
|
||||||
|
ProjectExplorer::StandardRunnable m_valgrindRunnable;
|
||||||
|
qint64 m_pid = 0;
|
||||||
|
|
||||||
|
Option m_lastOption = Unknown;
|
||||||
|
|
||||||
// remote callgrind support
|
// remote callgrind support
|
||||||
QSsh::SshConnection *m_ssh;
|
QSsh::SshConnection *m_ssh = nullptr;
|
||||||
QString m_tempDataFile;
|
QString m_tempDataFile;
|
||||||
QSsh::SshRemoteProcess::Ptr m_findRemoteFile;
|
QSsh::SshRemoteProcess::Ptr m_findRemoteFile;
|
||||||
QSsh::SftpChannel::Ptr m_sftp;
|
QSsh::SftpChannel::Ptr m_sftp;
|
||||||
|
|||||||
@@ -30,17 +30,21 @@
|
|||||||
|
|
||||||
#include <valgrind/callgrind/callgrindcontroller.h>
|
#include <valgrind/callgrind/callgrindcontroller.h>
|
||||||
#include <valgrind/callgrind/callgrindparser.h>
|
#include <valgrind/callgrind/callgrindparser.h>
|
||||||
|
#include <valgrind/valgrindrunner.h>
|
||||||
|
#include <valgrind/valgrindprocess.h>
|
||||||
|
|
||||||
#include <debugger/analyzer/analyzermanager.h>
|
#include <debugger/analyzer/analyzermanager.h>
|
||||||
|
|
||||||
#include <utils/qtcassert.h>
|
#include <utils/qtcassert.h>
|
||||||
|
|
||||||
using namespace Debugger;
|
using namespace Debugger;
|
||||||
using namespace Valgrind;
|
using namespace ProjectExplorer;
|
||||||
using namespace Valgrind::Internal;
|
|
||||||
using namespace Valgrind::Callgrind;
|
using namespace Valgrind::Callgrind;
|
||||||
|
|
||||||
CallgrindToolRunner::CallgrindToolRunner(ProjectExplorer::RunControl *runControl)
|
namespace Valgrind {
|
||||||
|
namespace Internal {
|
||||||
|
|
||||||
|
CallgrindToolRunner::CallgrindToolRunner(RunControl *runControl)
|
||||||
: ValgrindToolRunner(runControl)
|
: ValgrindToolRunner(runControl)
|
||||||
{
|
{
|
||||||
setDisplayName("CallgrindToolRunner");
|
setDisplayName("CallgrindToolRunner");
|
||||||
@@ -58,14 +62,14 @@ CallgrindToolRunner::CallgrindToolRunner(ProjectExplorer::RunControl *runControl
|
|||||||
connect(&m_controller, &CallgrindController::statusMessage,
|
connect(&m_controller, &CallgrindController::statusMessage,
|
||||||
this, &CallgrindToolRunner::showStatusMessage);
|
this, &CallgrindToolRunner::showStatusMessage);
|
||||||
|
|
||||||
connect(&m_runner, &ValgrindRunner::extraStart, this, [this] {
|
connect(m_runner.valgrindProcess(), &ValgrindProcess::valgrindStarted,
|
||||||
m_controller.setValgrindProcess(m_runner.valgrindProcess());
|
&m_controller, &CallgrindController::setValgrindPid);
|
||||||
});
|
|
||||||
|
|
||||||
connect(&m_runner, &ValgrindRunner::extraProcessFinished, this, [this] {
|
connect(&m_runner, &ValgrindRunner::extraProcessFinished, this, [this] {
|
||||||
triggerParse();
|
triggerParse();
|
||||||
m_controller.setValgrindProcess(nullptr);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
m_controller.setValgrindRunnable(runnable());
|
||||||
}
|
}
|
||||||
|
|
||||||
QStringList CallgrindToolRunner::toolArguments() const
|
QStringList CallgrindToolRunner::toolArguments() const
|
||||||
@@ -120,12 +124,10 @@ void CallgrindToolRunner::setPaused(bool paused)
|
|||||||
m_markAsPaused = paused;
|
m_markAsPaused = paused;
|
||||||
|
|
||||||
// call controller only if it is attached to a valgrind process
|
// call controller only if it is attached to a valgrind process
|
||||||
if (m_controller.valgrindProcess()) {
|
if (paused)
|
||||||
if (paused)
|
pause();
|
||||||
pause();
|
else
|
||||||
else
|
unpause();
|
||||||
unpause();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CallgrindToolRunner::setToggleCollectFunction(const QString &toggleCollectFunction)
|
void CallgrindToolRunner::setToggleCollectFunction(const QString &toggleCollectFunction)
|
||||||
@@ -202,3 +204,6 @@ void CallgrindToolRunner::controllerFinished(CallgrindController::Option option)
|
|||||||
break; // do nothing
|
break; // do nothing
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // Internal
|
||||||
|
} // Valgrind
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ MemcheckToolRunner::MemcheckToolRunner(RunControl *runControl, bool withGdb)
|
|||||||
this, &MemcheckToolRunner::suppressionCount);
|
this, &MemcheckToolRunner::suppressionCount);
|
||||||
|
|
||||||
if (withGdb) {
|
if (withGdb) {
|
||||||
connect(&m_runner, &ValgrindRunner::started,
|
connect(&m_runner, &ValgrindRunner::valgrindStarted,
|
||||||
this, &MemcheckToolRunner::startDebugger);
|
this, &MemcheckToolRunner::startDebugger);
|
||||||
connect(&m_runner, &ValgrindRunner::logMessageReceived,
|
connect(&m_runner, &ValgrindRunner::logMessageReceived,
|
||||||
this, &MemcheckToolRunner::appendLog);
|
this, &MemcheckToolRunner::appendLog);
|
||||||
@@ -163,10 +163,8 @@ QStringList MemcheckToolRunner::suppressionFiles() const
|
|||||||
return m_settings->suppressionFiles();
|
return m_settings->suppressionFiles();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MemcheckToolRunner::startDebugger()
|
void MemcheckToolRunner::startDebugger(qint64 valgrindPid)
|
||||||
{
|
{
|
||||||
const qint64 valgrindPid = m_runner.valgrindProcess()->pid();
|
|
||||||
|
|
||||||
Debugger::DebuggerStartParameters sp;
|
Debugger::DebuggerStartParameters sp;
|
||||||
sp.inferior = runnable().as<StandardRunnable>();
|
sp.inferior = runnable().as<StandardRunnable>();
|
||||||
sp.startMode = Debugger::AttachToRemoteServer;
|
sp.startMode = Debugger::AttachToRemoteServer;
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ private:
|
|||||||
QString progressTitle() const override;
|
QString progressTitle() const override;
|
||||||
QStringList toolArguments() const override;
|
QStringList toolArguments() const override;
|
||||||
|
|
||||||
void startDebugger();
|
void startDebugger(qint64 valgrindPid);
|
||||||
void appendLog(const QByteArray &data);
|
void appendLog(const QByteArray &data);
|
||||||
|
|
||||||
const bool m_withGdb;
|
const bool m_withGdb;
|
||||||
|
|||||||
@@ -39,8 +39,7 @@ using namespace ProjectExplorer;
|
|||||||
|
|
||||||
namespace Valgrind {
|
namespace Valgrind {
|
||||||
|
|
||||||
ValgrindProcess::ValgrindProcess(const IDevice::ConstPtr &device, QObject *parent)
|
ValgrindProcess::ValgrindProcess()
|
||||||
: QObject(parent), m_device(device)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -129,11 +128,6 @@ QProcess::ProcessError ValgrindProcess::processError() const
|
|||||||
return m_valgrindProcess.processError();
|
return m_valgrindProcess.processError();
|
||||||
}
|
}
|
||||||
|
|
||||||
qint64 ValgrindProcess::pid() const
|
|
||||||
{
|
|
||||||
return m_pid;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ValgrindProcess::handleRemoteStderr(const QByteArray &b)
|
void ValgrindProcess::handleRemoteStderr(const QByteArray &b)
|
||||||
{
|
{
|
||||||
if (!b.isEmpty())
|
if (!b.isEmpty())
|
||||||
@@ -153,8 +147,8 @@ bool ValgrindProcess::isLocal() const
|
|||||||
|
|
||||||
void ValgrindProcess::localProcessStarted()
|
void ValgrindProcess::localProcessStarted()
|
||||||
{
|
{
|
||||||
m_pid = m_valgrindProcess.applicationPID().pid();
|
qint64 pid = m_valgrindProcess.applicationPID().pid();
|
||||||
emit started();
|
emit valgrindStarted(pid);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ValgrindProcess::remoteProcessStarted()
|
void ValgrindProcess::remoteProcessStarted()
|
||||||
@@ -196,14 +190,13 @@ void ValgrindProcess::findPIDOutputReceived(const QByteArray &out)
|
|||||||
if (out.isEmpty())
|
if (out.isEmpty())
|
||||||
return;
|
return;
|
||||||
bool ok;
|
bool ok;
|
||||||
m_pid = out.trimmed().toLongLong(&ok);
|
qint64 pid = out.trimmed().toLongLong(&ok);
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
m_pid = 0;
|
|
||||||
// m_remote.m_errorString = tr("Could not determine remote PID.");
|
// m_remote.m_errorString = tr("Could not determine remote PID.");
|
||||||
// emit ValgrindProcess::error(QProcess::FailedToStart);
|
// emit ValgrindProcess::error(QProcess::FailedToStart);
|
||||||
// close();
|
// close();
|
||||||
} else {
|
} else {
|
||||||
emit started();
|
emit valgrindStarted(pid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -216,6 +209,11 @@ QString ValgrindProcess::argumentString(Utils::OsType osType) const
|
|||||||
return arguments;
|
return arguments;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ValgrindProcess::setDevice(const ProjectExplorer::IDevice::ConstPtr &device)
|
||||||
|
{
|
||||||
|
m_device = device;
|
||||||
|
}
|
||||||
|
|
||||||
void ValgrindProcess::closed(bool success)
|
void ValgrindProcess::closed(bool success)
|
||||||
{
|
{
|
||||||
Q_UNUSED(success);
|
Q_UNUSED(success);
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ class ValgrindProcess : public QObject
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ValgrindProcess(const ProjectExplorer::IDevice::ConstPtr &device, QObject *parent);
|
ValgrindProcess();
|
||||||
~ValgrindProcess();
|
~ValgrindProcess();
|
||||||
|
|
||||||
bool isRunning() const;
|
bool isRunning() const;
|
||||||
@@ -64,12 +64,12 @@ public:
|
|||||||
QString workingDirectory() const;
|
QString workingDirectory() const;
|
||||||
|
|
||||||
ProjectExplorer::IDevice::ConstPtr device() const { return m_device; }
|
ProjectExplorer::IDevice::ConstPtr device() const { return m_device; }
|
||||||
|
void setDevice(const ProjectExplorer::IDevice::ConstPtr &device);
|
||||||
|
|
||||||
qint64 pid() const;
|
|
||||||
bool isLocal() const;
|
bool isLocal() const;
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void started();
|
void valgrindStarted(qint64 pid);
|
||||||
void finished(int, QProcess::ExitStatus);
|
void finished(int, QProcess::ExitStatus);
|
||||||
void error(QProcess::ProcessError);
|
void error(QProcess::ProcessError);
|
||||||
void processOutput(const QString &, Utils::OutputFormat format);
|
void processOutput(const QString &, Utils::OutputFormat format);
|
||||||
@@ -87,7 +87,6 @@ private:
|
|||||||
|
|
||||||
ProjectExplorer::StandardRunnable m_debuggee;
|
ProjectExplorer::StandardRunnable m_debuggee;
|
||||||
ProjectExplorer::ApplicationLauncher m_valgrindProcess;
|
ProjectExplorer::ApplicationLauncher m_valgrindProcess;
|
||||||
qint64 m_pid = 0;
|
|
||||||
ProjectExplorer::IDevice::ConstPtr m_device;
|
ProjectExplorer::IDevice::ConstPtr m_device;
|
||||||
|
|
||||||
ProjectExplorer::ApplicationLauncher m_findPID;
|
ProjectExplorer::ApplicationLauncher m_findPID;
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ class ValgrindRunner::Private
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
QHostAddress localServerAddress;
|
QHostAddress localServerAddress;
|
||||||
ValgrindProcess *process = nullptr;
|
ValgrindProcess process;
|
||||||
QProcess::ProcessChannelMode channelMode = QProcess::SeparateChannels;
|
QProcess::ProcessChannelMode channelMode = QProcess::SeparateChannels;
|
||||||
bool finished = false;
|
bool finished = false;
|
||||||
QString valgrindExecutable;
|
QString valgrindExecutable;
|
||||||
@@ -75,7 +75,7 @@ ValgrindRunner::ValgrindRunner(QObject *parent)
|
|||||||
|
|
||||||
ValgrindRunner::~ValgrindRunner()
|
ValgrindRunner::~ValgrindRunner()
|
||||||
{
|
{
|
||||||
if (d->process && d->process->isRunning()) {
|
if (d->process.isRunning()) {
|
||||||
// make sure we don't delete the thread while it's still running
|
// make sure we don't delete the thread while it's still running
|
||||||
waitForFinished();
|
waitForFinished();
|
||||||
}
|
}
|
||||||
@@ -144,7 +144,7 @@ IDevice::ConstPtr ValgrindRunner::device() const
|
|||||||
|
|
||||||
void ValgrindRunner::waitForFinished() const
|
void ValgrindRunner::waitForFinished() const
|
||||||
{
|
{
|
||||||
if (d->finished || !d->process)
|
if (d->finished)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
QEventLoop loop;
|
QEventLoop loop;
|
||||||
@@ -165,26 +165,24 @@ bool ValgrindRunner::start()
|
|||||||
setValgrindArguments(memcheckLogArguments() + valgrindArguments());
|
setValgrindArguments(memcheckLogArguments() + valgrindArguments());
|
||||||
}
|
}
|
||||||
|
|
||||||
d->process = new ValgrindProcess(d->device, this);
|
d->process.setProcessChannelMode(d->channelMode);
|
||||||
d->process->setProcessChannelMode(d->channelMode);
|
d->process.setDevice(d->device);
|
||||||
// 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
|
||||||
d->process->setValgrindExecutable(d->valgrindExecutable);
|
d->process.setValgrindExecutable(d->valgrindExecutable);
|
||||||
d->process->setValgrindArguments(fullValgrindArguments());
|
d->process.setValgrindArguments(fullValgrindArguments());
|
||||||
d->process->setDebuggee(d->debuggee);
|
d->process.setDebuggee(d->debuggee);
|
||||||
|
|
||||||
QObject::connect(d->process, &ValgrindProcess::processOutput,
|
QObject::connect(&d->process, &ValgrindProcess::processOutput,
|
||||||
this, &ValgrindRunner::processOutputReceived);
|
this, &ValgrindRunner::processOutputReceived);
|
||||||
QObject::connect(d->process, &ValgrindProcess::started,
|
QObject::connect(&d->process, &ValgrindProcess::valgrindStarted,
|
||||||
this, &ValgrindRunner::started);
|
this, &ValgrindRunner::onValgrindStarted);
|
||||||
QObject::connect(d->process, &ValgrindProcess::finished,
|
QObject::connect(&d->process, &ValgrindProcess::finished,
|
||||||
this, &ValgrindRunner::processFinished);
|
this, &ValgrindRunner::processFinished);
|
||||||
QObject::connect(d->process, &ValgrindProcess::error,
|
QObject::connect(&d->process, &ValgrindProcess::error,
|
||||||
this, &ValgrindRunner::processError);
|
this, &ValgrindRunner::processError);
|
||||||
|
|
||||||
d->process->run(d->debuggee.runMode);
|
d->process.run(d->debuggee.runMode);
|
||||||
|
|
||||||
emit extraStart();
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -214,23 +212,22 @@ void ValgrindRunner::processFinished(int ret, QProcess::ExitStatus status)
|
|||||||
emit finished();
|
emit finished();
|
||||||
|
|
||||||
if (ret != 0 || status == QProcess::CrashExit)
|
if (ret != 0 || status == QProcess::CrashExit)
|
||||||
emit processErrorReceived(errorString(), d->process->processError());
|
emit processErrorReceived(errorString(), d->process.processError());
|
||||||
}
|
}
|
||||||
|
|
||||||
QString ValgrindRunner::errorString() const
|
QString ValgrindRunner::errorString() const
|
||||||
{
|
{
|
||||||
return d->process ? d->process->errorString() : QString();
|
return d->process.errorString();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ValgrindRunner::stop()
|
void ValgrindRunner::stop()
|
||||||
{
|
{
|
||||||
QTC_ASSERT(d->process, finished(); return);
|
d->process.close();
|
||||||
d->process->close();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ValgrindProcess *ValgrindRunner::valgrindProcess() const
|
ValgrindProcess *ValgrindRunner::valgrindProcess() const
|
||||||
{
|
{
|
||||||
return d->process;
|
return &d->process;
|
||||||
}
|
}
|
||||||
|
|
||||||
XmlProtocol::ThreadedParser *ValgrindRunner::parser() const
|
XmlProtocol::ThreadedParser *ValgrindRunner::parser() const
|
||||||
@@ -246,6 +243,11 @@ void ValgrindRunner::disableXml()
|
|||||||
d->disableXml = true;
|
d->disableXml = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ValgrindRunner::onValgrindStarted(qint64 pid)
|
||||||
|
{
|
||||||
|
emit valgrindStarted(pid);
|
||||||
|
}
|
||||||
|
|
||||||
void ValgrindRunner::xmlSocketConnected()
|
void ValgrindRunner::xmlSocketConnected()
|
||||||
{
|
{
|
||||||
QTcpSocket *socket = d->xmlServer.nextPendingConnection();
|
QTcpSocket *socket = d->xmlServer.nextPendingConnection();
|
||||||
|
|||||||
@@ -76,17 +76,17 @@ public:
|
|||||||
|
|
||||||
signals:
|
signals:
|
||||||
void logMessageReceived(const QByteArray &);
|
void logMessageReceived(const QByteArray &);
|
||||||
void extraStart();
|
|
||||||
|
|
||||||
void processOutputReceived(const QString &, Utils::OutputFormat);
|
void processOutputReceived(const QString &, Utils::OutputFormat);
|
||||||
void processErrorReceived(const QString &, QProcess::ProcessError);
|
void processErrorReceived(const QString &, QProcess::ProcessError);
|
||||||
void started();
|
void valgrindStarted(qint64 pid);
|
||||||
void finished();
|
void finished();
|
||||||
void extraProcessFinished();
|
void extraProcessFinished();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool startServers();
|
bool startServers();
|
||||||
QStringList memcheckLogArguments() const;
|
QStringList memcheckLogArguments() const;
|
||||||
|
void onValgrindStarted(qint64 pid);
|
||||||
|
|
||||||
void processError(QProcess::ProcessError);
|
void processError(QProcess::ProcessError);
|
||||||
void processFinished(int, QProcess::ExitStatus);
|
void processFinished(int, QProcess::ExitStatus);
|
||||||
|
|||||||
Reference in New Issue
Block a user