SshDeviceProcessList: Don't use SshRemoteProcessRunner

Use QtcProcess with a path on device instead.
Remove some unneeded includes.

Fix killing a process on remote linux. It amends the old commit
that added "kill -0 -pid pid" command in the middle.
There is no defined "0" signal for kill command, so removing it here.
Currently the issue was that after calling kill -15 the process
may have got terminated and the subsequent call to kill -9
(after one second of sleep) failed with an error.
Instead, we call in a row: kill -15 and kill -9, without the
sleep command inside. It looks like this works fine, and the
old app gets terminated, so the subsequent kill -9 doesn't
cause an error.

This commit makes "Show Running Processes..." work again for remotes.

Amends be4bd1dc06

Change-Id: Id70884bdd0302e6d59f2f58d61f3f3d89a067391
Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
This commit is contained in:
Jarek Kobus
2022-05-06 00:13:52 +02:00
parent 7ef5001076
commit f62a4d6315
4 changed files with 34 additions and 58 deletions

View File

@@ -24,9 +24,8 @@
****************************************************************************/
#include "deviceprocesslist.h"
#include "idevice.h"
#include <projectexplorer/devicesupport/idevice.h>
#include <utils/fileutils.h>
#include <utils/processinfo.h>
#include <utils/qtcassert.h>
#include <utils/treemodel.h>

View File

@@ -24,75 +24,63 @@
****************************************************************************/
#include "sshdeviceprocesslist.h"
#include "idevice.h"
#include <projectexplorer/devicesupport/idevice.h>
#include <ssh/sshremoteprocessrunner.h>
#include <utils/fileutils.h>
#include <utils/processinfo.h>
#include <utils/qtcassert.h>
#include <utils/qtcprocess.h>
using namespace QSsh;
using namespace Utils;
namespace ProjectExplorer {
class SshDeviceProcessList::SshDeviceProcessListPrivate
class SshDeviceProcessListPrivate
{
public:
SshRemoteProcessRunner process;
DeviceProcessSignalOperation::Ptr signalOperation;
QtcProcess m_process;
DeviceProcessSignalOperation::Ptr m_signalOperation;
};
SshDeviceProcessList::SshDeviceProcessList(const IDevice::ConstPtr &device, QObject *parent) :
DeviceProcessList(device, parent), d(std::make_unique<SshDeviceProcessListPrivate>())
{
connect(&d->m_process, &QtcProcess::done, this, &SshDeviceProcessList::handleProcessDone);
}
SshDeviceProcessList::~SshDeviceProcessList() = default;
void SshDeviceProcessList::doUpdate()
{
connect(&d->process, &SshRemoteProcessRunner::connectionError,
this, &SshDeviceProcessList::handleConnectionError);
connect(&d->process, &SshRemoteProcessRunner::finished,
this, &SshDeviceProcessList::handleListProcessFinished);
d->process.run(listProcessesCommandLine(), device()->sshParameters());
d->m_process.close();
d->m_process.setCommand({device()->mapToGlobalPath("/bin/sh"),
{"-c", listProcessesCommandLine()}});
d->m_process.start();
}
void SshDeviceProcessList::doKillProcess(const ProcessInfo &process)
{
d->signalOperation = device()->signalOperation();
QTC_ASSERT(d->signalOperation, return);
connect(d->signalOperation.data(), &DeviceProcessSignalOperation::finished,
d->m_signalOperation = device()->signalOperation();
QTC_ASSERT(d->m_signalOperation, return);
connect(d->m_signalOperation.data(), &DeviceProcessSignalOperation::finished,
this, &SshDeviceProcessList::handleKillProcessFinished);
d->signalOperation->killProcess(process.processId);
d->m_signalOperation->killProcess(process.processId);
}
void SshDeviceProcessList::handleConnectionError()
void SshDeviceProcessList::handleProcessDone()
{
setFinished();
reportError(tr("Connection failure: %1").arg(d->process.lastConnectionErrorString()));
}
void SshDeviceProcessList::handleListProcessFinished()
{
const QString error = d->process.errorString();
setFinished();
if (!error.isEmpty()) {
handleProcessError(error);
return;
}
if (d->process.exitCode() == 0) {
const QByteArray remoteStdout = d->process.readAllStandardOutput();
const QString stdoutString
= QString::fromUtf8(remoteStdout.data(), remoteStdout.count());
reportProcessListUpdated(buildProcessList(stdoutString));
if (d->m_process.result() == ProcessResult::FinishedWithSuccess) {
reportProcessListUpdated(buildProcessList(d->m_process.stdOut()));
} else {
handleProcessError(tr("Process listing command failed with exit code %1.")
.arg(d->process.exitCode()));
const QString errorMessage = d->m_process.exitStatus() == QProcess::NormalExit
? tr("Process listing command failed with exit code %1.").arg(d->m_process.exitCode())
: d->m_process.errorString();
const QString stdErr = d->m_process.stdErr();
const QString fullMessage = stdErr.isEmpty()
? errorMessage : errorMessage + '\n' + tr("Remote stderr was: %1").arg(stdErr);
reportError(fullMessage);
}
setFinished();
}
void SshDeviceProcessList::handleKillProcessFinished(const QString &errorString)
@@ -104,21 +92,12 @@ void SshDeviceProcessList::handleKillProcessFinished(const QString &errorString)
setFinished();
}
void SshDeviceProcessList::handleProcessError(const QString &errorMessage)
{
QString fullMessage = errorMessage;
const QByteArray remoteStderr = d->process.readAllStandardError();
if (!remoteStderr.isEmpty())
fullMessage += QLatin1Char('\n') + tr("Remote stderr was: %1").arg(QString::fromUtf8(remoteStderr));
reportError(fullMessage);
}
void SshDeviceProcessList::setFinished()
{
d->process.disconnect(this);
if (d->signalOperation) {
d->signalOperation->disconnect(this);
d->signalOperation.clear();
d->m_process.close();
if (d->m_signalOperation) {
d->m_signalOperation->disconnect(this);
d->m_signalOperation.clear();
}
}

View File

@@ -31,6 +31,8 @@
namespace ProjectExplorer {
class SshDeviceProcessListPrivate;
class PROJECTEXPLORER_EXPORT SshDeviceProcessList : public DeviceProcessList
{
Q_OBJECT
@@ -39,8 +41,7 @@ public:
~SshDeviceProcessList() override;
private:
void handleConnectionError();
void handleListProcessFinished();
void handleProcessDone();
void handleKillProcessFinished(const QString &errorString);
virtual QString listProcessesCommandLine() const = 0;
@@ -49,10 +50,8 @@ private:
void doUpdate() override;
void doKillProcess(const Utils::ProcessInfo &process) override;
void handleProcessError(const QString &errorMessage);
void setFinished();
class SshDeviceProcessListPrivate;
const std::unique_ptr<SshDeviceProcessListPrivate> d;
};

View File

@@ -43,7 +43,7 @@ RemoteLinuxSignalOperation::~RemoteLinuxSignalOperation() = default;
static QString signalProcessGroupByPidCommandLine(qint64 pid, int signal)
{
return QString::fromLatin1("kill -%1 -%2 %2").arg(signal).arg(pid);
return QString::fromLatin1("kill -%1 %2").arg(signal).arg(pid);
}
void RemoteLinuxSignalOperation::run(const QString &command)
@@ -80,9 +80,8 @@ QString RemoteLinuxSignalOperation::interruptProcessByNameCommandLine(const QStr
void RemoteLinuxSignalOperation::killProcess(qint64 pid)
{
run(QString::fromLatin1("%1; sleep 1; %2 && %3")
run(QString::fromLatin1("%1 && %2")
.arg(signalProcessGroupByPidCommandLine(pid, 15),
signalProcessGroupByPidCommandLine(pid, 0),
signalProcessGroupByPidCommandLine(pid, 9)));
}