Commit ddefe062 authored by Tobias Hunger's avatar Tobias Hunger

Fix up QProcess::waitForFinished()

waitForFinish returns false if the process is no longer running at
the time of the call. Handle that throughout the codebase.

Change-Id: Ia7194095454e82efbd4eb88f2d55926bdd09e094
Reviewed-by: default avatarhjk <hjk@theqtcompany.com>
parent 1a248b1b
......@@ -40,24 +40,22 @@ bool BuildableHelperLibrary::isQtChooser(const QFileInfo &info)
QString BuildableHelperLibrary::qtChooserToQmakePath(const QString &path)
{
const char toolDir[] = "QTTOOLDIR=\"";
QProcess proc;
proc.start(path, QStringList(QLatin1String("-print-env")));
if (!proc.waitForStarted(1000))
return QString();
if (!proc.waitForFinished(1000))
const QString toolDir = QLatin1String("QTTOOLDIR=\"");
SynchronousProcess proc;
proc.setTimeoutS(1);
SynchronousProcessResponse response = proc.run(path, QStringList(QLatin1String("-print-env")));
if (response.result != SynchronousProcessResponse::Finished)
return QString();
QByteArray output = proc.readAllStandardOutput();
const QString output = response.stdOut;
int pos = output.indexOf(toolDir);
if (pos == -1)
return QString();
pos += int(sizeof(toolDir)) - 1;
pos += toolDir.count() - 1;
int end = output.indexOf('\"', pos);
if (end == -1)
return QString();
QString result = QString::fromLocal8Bit(output.mid(pos, end - pos)) + QLatin1String("/qmake");
return result;
return output.mid(pos, end - pos) + QLatin1String("/qmake");
}
static bool isQmake(const QString &path)
......@@ -104,23 +102,15 @@ QString BuildableHelperLibrary::qtVersionForQMake(const QString &qmakePath)
if (qmakePath.isEmpty())
return QString();
QProcess qmake;
qmake.start(qmakePath, QStringList(QLatin1String("--version")));
if (!qmake.waitForStarted()) {
qWarning("Cannot start '%s': %s", qPrintable(qmakePath), qPrintable(qmake.errorString()));
return QString();
}
if (!qmake.waitForFinished()) {
SynchronousProcess::stopProcess(qmake);
qWarning("Timeout running '%s'.", qPrintable(qmakePath));
return QString();
}
if (qmake.exitStatus() != QProcess::NormalExit) {
qWarning("'%s' crashed.", qPrintable(qmakePath));
SynchronousProcess qmake;
qmake.setTimeoutS(5);
SynchronousProcessResponse response = qmake.run(qmakePath, QStringList(QLatin1String("--version")));
if (response.result != SynchronousProcessResponse::Finished) {
qWarning() << response.exitMessage(qmakePath, 5);
return QString();
}
const QString output = QString::fromLocal8Bit(qmake.readAllStandardOutput());
const QString output = response.allOutput();
static QRegExp regexp(QLatin1String("(QMake version|QMake version:)[\\s]*([\\d.]*)"),
Qt::CaseInsensitive);
regexp.indexIn(output);
......
......@@ -211,7 +211,7 @@ void ConsoleProcess::stop()
killStub();
if (isRunning()) {
d->m_process.terminate();
if (!d->m_process.waitForFinished(1000)) {
if (!d->m_process.waitForFinished(1000) && d->m_process.state() == QProcess::Running) {
d->m_process.kill();
d->m_process.waitForFinished();
}
......
......@@ -129,16 +129,12 @@ QString BinaryVersionToolTipEventFilter::toolVersion(const QString &binary, cons
{
if (binary.isEmpty())
return QString();
QProcess proc;
proc.start(binary, arguments);
if (!proc.waitForStarted())
SynchronousProcess proc;
proc.setTimeoutS(1);
SynchronousProcessResponse response = proc.run(binary, arguments);
if (response.result != SynchronousProcessResponse::Finished)
return QString();
if (!proc.waitForFinished()) {
SynchronousProcess::stopProcess(proc);
return QString();
}
return QString::fromLocal8Bit(QByteArray(proc.readAllStandardOutput()
+ proc.readAllStandardError()));
return response.allOutput();
}
// Extends BinaryVersionToolTipEventFilter to prepend the existing pathchooser
......
......@@ -137,6 +137,17 @@ QString SynchronousProcessResponse::exitMessage(const QString &binary, int timeo
return QString();
}
QString SynchronousProcessResponse::allOutput() const
{
if (!stdOut.isEmpty() && !stdErr.isEmpty()) {
if (stdOut.endsWith(QLatin1Char('\n')))
return stdOut + stdErr;
else
return stdOut + QLatin1Char('\n') + stdErr;
}
return !stdOut.isEmpty() ? stdOut : stdErr;
}
QTCREATOR_UTILS_EXPORT QDebug operator<<(QDebug str, const SynchronousProcessResponse& r)
{
QDebug nsp = str.nospace();
......@@ -579,9 +590,8 @@ bool SynchronousProcess::readDataFromProcess(QProcess &p, int timeoutS,
bool finished = false;
bool hasData = false;
do {
finished = p.state() == QProcess::NotRunning
|| p.waitForFinished(timeoutS > 0 ? timeoutS * 1000 : -1);
hasData = false;
finished = p.waitForFinished(timeoutS > 0 ? timeoutS * 1000 : -1)
|| p.state() == QProcess::NotRunning;
// First check 'stdout'
if (p.bytesAvailable()) { // applies to readChannel() only
hasData = true;
......@@ -608,13 +618,13 @@ bool SynchronousProcess::readDataFromProcess(QProcess &p, int timeoutS,
bool SynchronousProcess::stopProcess(QProcess &p)
{
if (p.state() != QProcess::Running)
if (p.state() == QProcess::NotRunning)
return true;
p.terminate();
if (p.waitForFinished(300))
if (p.waitForFinished(300) && p.state() == QProcess::Running)
return true;
p.kill();
return p.waitForFinished(300);
return p.waitForFinished(300) || p.state() == QProcess::NotRunning;
}
// Path utilities
......
......@@ -59,6 +59,7 @@ struct QTCREATOR_UTILS_EXPORT SynchronousProcessResponse
// Helper to format an exit message.
QString exitMessage(const QString &binary, int timeoutS) const;
QString allOutput() const;
Result result;
int exitCode;
......
......@@ -43,10 +43,11 @@
#include <qtsupport/qtkitinformation.h>
#include <utils/qtcprocess.h>
#include <utils/synchronousprocess.h>
#include <QInputDialog>
#include <QMessageBox>
#include <QProcess>
namespace Android {
using namespace Internal;
......@@ -279,29 +280,32 @@ bool AndroidBuildApkStep::verboseOutput() const
QAbstractItemModel *AndroidBuildApkStep::keystoreCertificates()
{
QString rawCerts;
QProcess keytoolProc;
while (!rawCerts.length() || !m_keystorePasswd.length()) {
QStringList params;
params << QLatin1String("-list") << QLatin1String("-v") << QLatin1String("-keystore") << m_keystorePath.toUserOutput() << QLatin1String("-storepass");
QStringList params
= { QLatin1String("-list"), QLatin1String("-v"), QLatin1String("-keystore"),
m_keystorePath.toUserOutput(), QLatin1String("-storepass") };
if (!m_keystorePasswd.length())
keystorePassword();
if (!m_keystorePasswd.length())
return 0;
return nullptr;
params << m_keystorePasswd;
params << QLatin1String("-J-Duser.language=en");
keytoolProc.start(AndroidConfigurations::currentConfig().keytoolPath().toString(), params);
if (!keytoolProc.waitForStarted() || !keytoolProc.waitForFinished()) {
Utils::SynchronousProcess keytoolProc;
keytoolProc.setTimeoutS(30);
const Utils::SynchronousProcessResponse response
= keytoolProc.run(AndroidConfigurations::currentConfig().keytoolPath().toString(), params);
if (response.result != Utils::SynchronousProcessResponse::Finished) {
QMessageBox::critical(0, tr("Error"),
tr("Failed to run keytool."));
return 0;
return nullptr;
}
if (keytoolProc.exitCode()) {
QMessageBox::critical(0, tr("Error"),
tr("Invalid password."));
if (response.exitCode != 0) {
QMessageBox::critical(0, tr("Error"), tr("Invalid password."));
m_keystorePasswd.clear();
}
rawCerts = QString::fromLatin1(keytoolProc.readAllStandardOutput());
rawCerts = response.stdOut;
}
return new CertificatesModel(rawCerts, this);
}
......
......@@ -27,8 +27,9 @@
#include "androidconfigurations.h"
#include "ui_androidcreatekeystorecertificate.h"
#include <utils/synchronousprocess.h>
#include <QFileDialog>
#include <QProcess>
#include <QMessageBox>
using namespace Android::Internal;
......@@ -162,6 +163,7 @@ void AndroidCreateKeystoreCertificate::on_buttonBox_accepted()
if (ui->stateNameLineEdit->text().length())
distinguishedNames += QLatin1String(", S=") + ui->stateNameLineEdit->text().replace(QLatin1Char(','), QLatin1String("\\,"));
const QString command = AndroidConfigurations::currentConfig().keytoolPath().toString();
QStringList params;
params << QLatin1String("-genkey") << QLatin1String("-keyalg") << QLatin1String("RSA")
<< QLatin1String("-keystore") << m_keystoreFilePath.toString()
......@@ -172,16 +174,13 @@ void AndroidCreateKeystoreCertificate::on_buttonBox_accepted()
<< QLatin1String("-keypass") << certificatePassword()
<< QLatin1String("-dname") << distinguishedNames;
QProcess genKeyCertProc;
genKeyCertProc.start(AndroidConfigurations::currentConfig().keytoolPath().toString(), params );
if (!genKeyCertProc.waitForStarted() || !genKeyCertProc.waitForFinished())
return;
Utils::SynchronousProcess genKeyCertProc;
genKeyCertProc.setTimeoutS(15);
Utils::SynchronousProcessResponse response = genKeyCertProc.run(command, params);
if (genKeyCertProc.exitCode()) {
QMessageBox::critical(this, tr("Error")
, QString::fromLatin1(genKeyCertProc.readAllStandardOutput())
+ QString::fromLatin1(genKeyCertProc.readAllStandardError()));
if (response.result != Utils::SynchronousProcessResponse::Finished || response.exitCode != 0) {
QMessageBox::critical(this, tr("Error"),
response.exitMessage(command, 15) + QLatin1Char('\n') + response.allOutput());
return;
}
accept();
......
......@@ -50,6 +50,7 @@
#include <utils/algorithm.h>
#include <utils/qtcassert.h>
#include <utils/qtcprocess.h>
#include <utils/synchronousprocess.h>
#include <QInputDialog>
#include <QMessageBox>
......@@ -354,7 +355,10 @@ AndroidDeployQtStep::DeployResult AndroidDeployQtStep::runDeploy(QFutureInterfac
.arg(QDir::toNativeSeparators(m_command), args),
BuildStep::MessageOutput);
while (m_process->state() != QProcess::NotRunning && !m_process->waitForFinished(200)) {
while (!m_process->waitForFinished(200)) {
if (m_process->state() == QProcess::NotRunning)
break;
if (fi.isCanceled()) {
m_process->kill();
m_process->waitForFinished();
......@@ -464,25 +468,12 @@ void AndroidDeployQtStep::run(QFutureInterface<bool> &fi)
void AndroidDeployQtStep::runCommand(const QString &program, const QStringList &arguments)
{
QProcess buildProc;
Utils::SynchronousProcess buildProc;
buildProc.setTimeoutS(2 * 60);
emit addOutput(tr("Package deploy: Running command \"%1 %2\".").arg(program).arg(arguments.join(QLatin1Char(' '))), BuildStep::MessageOutput);
buildProc.start(program, arguments);
if (!buildProc.waitForStarted()) {
emit addOutput(tr("Packaging error: Could not start command \"%1 %2\". Reason: %3")
.arg(program).arg(arguments.join(QLatin1Char(' '))).arg(buildProc.errorString()), BuildStep::ErrorMessageOutput);
return;
}
if (!buildProc.waitForFinished(2 * 60 * 1000)
|| buildProc.error() != QProcess::UnknownError
|| buildProc.exitCode() != 0) {
QString mainMessage = tr("Packaging error: Command \"%1 %2\" failed.")
.arg(program).arg(arguments.join(QLatin1Char(' ')));
if (buildProc.error() != QProcess::UnknownError)
mainMessage += QLatin1Char(' ') + tr("Reason: %1").arg(buildProc.errorString());
else
mainMessage += tr("Exit code: %1").arg(buildProc.exitCode());
emit addOutput(mainMessage, BuildStep::ErrorMessageOutput);
}
Utils::SynchronousProcessResponse response = buildProc.run(program, arguments);
if (response.result != Utils::SynchronousProcessResponse::Finished || response.exitCode != 0)
emit addOutput(response.exitMessage(program, 2 * 60), BuildStep::ErrorMessageOutput);
}
AndroidDeviceInfo AndroidDeployQtStep::deviceInfo() const
......
......@@ -32,9 +32,7 @@
#include <projectexplorer/abstractprocessstep.h>
#include <qtsupport/baseqtversion.h>
namespace Utils {
class QtcProcess;
}
namespace Utils { class QtcProcess; }
QT_BEGIN_NAMESPACE
class QAbstractItemModel;
......
......@@ -51,6 +51,7 @@
#include <qtsupport/qtkitinformation.h>
#include <qtsupport/qtsupportconstants.h>
#include <utils/algorithm.h>
#include <utils/synchronousprocess.h>
#include <QDir>
#include <QFileSystemWatcher>
......@@ -345,13 +346,13 @@ void AndroidManager::installQASIPackage(ProjectExplorer::Target *target, const Q
QStringList arguments = AndroidDeviceInfo::adbSelector(deviceSerialNumber);
arguments << QLatin1String("install") << QLatin1String("-r ") << packagePath;
process->connect(process, SIGNAL(finished(int)), process, SLOT(deleteLater()));
connect(process, static_cast<void (QProcess::*)(int)>(&QProcess::finished),
process, &QObject::deleteLater);
const QString adb = AndroidConfigurations::currentConfig().adbToolPath().toString();
Core::MessageManager::write(adb + QLatin1Char(' ') + arguments.join(QLatin1Char(' ')));
process->start(adb, arguments);
if (!process->waitForFinished(500))
if (!process->waitForStarted(500) && process->state() != QProcess::Running)
delete process;
}
bool AndroidManager::checkKeystorePassword(const QString &keystorePath, const QString &keystorePasswd)
......@@ -364,16 +365,10 @@ bool AndroidManager::checkKeystorePassword(const QString &keystorePath, const QS
<< keystorePath
<< QLatin1String("--storepass")
<< keystorePasswd;
QProcess proc;
proc.start(AndroidConfigurations::currentConfig().keytoolPath().toString(), arguments);
if (!proc.waitForStarted(10000))
return false;
if (!proc.waitForFinished(10000)) {
proc.kill();
proc.waitForFinished();
return false;
}
return proc.exitCode() == 0;
Utils::SynchronousProcess proc;
proc.setTimeoutS(10);
Utils::SynchronousProcessResponse response = proc.run(AndroidConfigurations::currentConfig().keytoolPath().toString(), arguments);
return (response.result == Utils::SynchronousProcessResponse::Finished && response.exitCode == 0);
}
bool AndroidManager::checkCertificatePassword(const QString &keystorePath, const QString &keystorePasswd, const QString &alias, const QString &certificatePasswd)
......@@ -393,16 +388,11 @@ bool AndroidManager::checkCertificatePassword(const QString &keystorePath, const
else
arguments << certificatePasswd;
QProcess proc;
proc.start(AndroidConfigurations::currentConfig().keytoolPath().toString(), arguments);
if (!proc.waitForStarted(10000))
return false;
if (!proc.waitForFinished(10000)) {
proc.kill();
proc.waitForFinished();
return false;
}
return proc.exitCode() == 0;
Utils::SynchronousProcess proc;
proc.setTimeoutS(10);
Utils::SynchronousProcessResponse response
= proc.run(AndroidConfigurations::currentConfig().keytoolPath().toString(), arguments);
return response.result == Utils::SynchronousProcessResponse::Finished && response.exitCode == 0;
}
bool AndroidManager::checkForQt51Files(Utils::FileName fileName)
......
......@@ -37,6 +37,7 @@
#include <qtsupport/qtkitinformation.h>
#include <utils/qtcassert.h>
#include <utils/runextensions.h>
#include <utils/synchronousprocess.h>
#include <QApplication>
#include <QDir>
......@@ -169,10 +170,11 @@ AndroidRunner::AndroidRunner(QObject *parent,
// Detect busybox, as we need to pass -w to ps to get wide output.
QProcess psProc;
psProc.start(m_adb, selector() << _("shell") << _("readlink") << _("$(which ps)"));
psProc.waitForFinished();
QByteArray which = psProc.readAll();
Utils::SynchronousProcess psProc;
psProc.setTimeoutS(5);
Utils::SynchronousProcessResponse response
= psProc.run(m_adb, selector() << _("shell") << _("readlink") << _("$(which ps)"));
const QString which = response.allOutput();
m_isBusyBox = which.startsWith("busybox");
m_checkPIDTimer.setInterval(1000);
......@@ -302,10 +304,8 @@ void AndroidRunner::checkPID()
void AndroidRunner::forceStop()
{
QProcess proc;
proc.start(m_adb, selector() << _("shell") << _("am") << _("force-stop")
<< m_androidRunnable.packageName);
proc.waitForFinished();
runAdb(selector() << _("shell") << _("am") << _("force-stop") << m_androidRunnable.packageName,
nullptr, 30);
// try killing it via kill -9
const QByteArray out = runPs();
......@@ -334,34 +334,22 @@ void AndroidRunner::asyncStart()
{
QMutexLocker locker(&m_mutex);
forceStop();
QString errorMessage;
if (m_useCppDebugger) {
// Remove pong file.
QProcess adb;
adb.start(m_adb, selector() << _("shell") << _("rm") << m_pongFile);
adb.waitForFinished();
}
if (m_useCppDebugger)
runAdb(selector() << _("shell") << _("rm") << m_pongFile); // Remove pong file.
foreach (const QStringList &entry, m_androidRunnable.beforeStartADBCommands) {
QProcess adb;
adb.start(m_adb, selector() << entry);
adb.waitForFinished();
}
foreach (const QStringList &entry, m_androidRunnable.beforeStartADBCommands)
runAdb(selector() << entry);
QStringList args = selector();
args << _("shell") << _("am") << _("start") << _("-n") << m_androidRunnable.intentName;
if (m_useCppDebugger) {
QProcess adb;
adb.start(m_adb, selector() << _("forward")
<< QString::fromLatin1("tcp:%1").arg(m_localGdbServerPort.number())
<< _("localfilesystem:") + m_gdbserverSocket);
if (!adb.waitForStarted()) {
emit remoteProcessFinished(tr("Failed to forward C++ debugging ports. Reason: %1.").arg(adb.errorString()));
return;
}
if (!adb.waitForFinished(10000)) {
emit remoteProcessFinished(tr("Failed to forward C++ debugging ports."));
if (!runAdb(selector() << _("forward")
<< QString::fromLatin1("tcp:%1").arg(m_localGdbServerPort.number())
<< _("localfilesystem:") + m_gdbserverSocket, &errorMessage)) {
emit remoteProcessFinished(tr("Failed to forward C++ debugging ports. Reason: %1.").arg(errorMessage));
return;
}
......@@ -380,15 +368,9 @@ void AndroidRunner::asyncStart()
args << _("-e") << _("gdbserver_socket") << m_gdbserverSocket;
if (m_handShakeMethod == SocketHandShake) {
QProcess adb;
const QString port = QString::fromLatin1("tcp:%1").arg(socketHandShakePort);
adb.start(m_adb, selector() << _("forward") << port << _("localabstract:") + pingPongSocket);
if (!adb.waitForStarted()) {
emit remoteProcessFinished(tr("Failed to forward ping pong ports. Reason: %1.").arg(adb.errorString()));
return;
}
if (!adb.waitForFinished()) {
emit remoteProcessFinished(tr("Failed to forward ping pong ports."));
if (!runAdb(selector() << _("forward") << port << _("localabstract:") + pingPongSocket, &errorMessage)) {
emit remoteProcessFinished(tr("Failed to forward ping pong ports. Reason: %1.").arg(errorMessage));
return;
}
}
......@@ -397,14 +379,8 @@ void AndroidRunner::asyncStart()
if (m_qmlDebugServices != QmlDebug::NoQmlDebugServices) {
// currently forward to same port on device and host
const QString port = QString::fromLatin1("tcp:%1").arg(m_qmlPort.number());
QProcess adb;
adb.start(m_adb, selector() << _("forward") << port << port);
if (!adb.waitForStarted()) {
emit remoteProcessFinished(tr("Failed to forward QML debugging ports. Reason: %1.").arg(adb.errorString()));
return;
}
if (!adb.waitForFinished()) {
emit remoteProcessFinished(tr("Failed to forward QML debugging ports."));
if (!runAdb(selector() << _("forward") << port << port, &errorMessage)) {
emit remoteProcessFinished(tr("Failed to forward QML debugging ports. Reason: %1.").arg(errorMessage));
return;
}
......@@ -414,15 +390,8 @@ void AndroidRunner::asyncStart()
.arg(m_qmlPort.number()).arg(QmlDebug::qmlDebugServices(m_qmlDebugServices));
}
QProcess adb;
adb.start(m_adb, args);
if (!adb.waitForStarted()) {
emit remoteProcessFinished(tr("Failed to start the activity. Reason: %1.").arg(adb.errorString()));
return;
}
if (!adb.waitForFinished(10000)) {
adb.terminate();
emit remoteProcessFinished(tr("Unable to start \"%1\".").arg(m_androidRunnable.packageName));
if (!runAdb(args, &errorMessage)) {
emit remoteProcessFinished(tr("Failed to start the activity. Reason: %1.").arg(errorMessage));
return;
}
......@@ -476,9 +445,7 @@ void AndroidRunner::asyncStart()
tmp.open();
tmp.close();
QProcess process;
process.start(m_adb, selector() << _("pull") << m_pingFile << tmp.fileName());
process.waitForFinished();
runAdb(selector() << _("pull") << m_pingFile << tmp.fileName());
QFile res(tmp.fileName());
const bool doBreak = res.size();
......@@ -510,18 +477,28 @@ bool AndroidRunner::adbShellAmNeedsQuotes()
// The command will fail with a complaint about the "--dummy"
// option on newer SDKs, and with "No intent supplied" on older ones.
// In case the test itself fails assume a new SDK.
QProcess adb;
adb.start(m_adb, selector() << _("shell") << _("am") << _("start")
<< _("-e") << _("dummy") <<_("dummy --dummy"));
if (!adb.waitForStarted())
Utils::SynchronousProcess adb;
adb.setTimeoutS(10);
Utils::SynchronousProcessResponse response
= adb.run(m_adb, selector() << _("shell") << _("am") << _("start")
<< _("-e") << _("dummy") <<_("dummy --dummy"));
if (response.result == Utils::SynchronousProcessResponse::StartFailed
|| response.result != Utils::SynchronousProcessResponse::Finished)
return true;
if (!adb.waitForFinished(10000))
return true;
const QString output = response.allOutput();
return output.contains(QLatin1String("Error: No intent supplied"));
}
QByteArray output = adb.readAllStandardError() + adb.readAllStandardOutput();
bool oldSdk = output.contains("Error: No intent supplied");
return !oldSdk;
bool AndroidRunner::runAdb(const QStringList &args, QString *errorMessage, int timeoutS)
{
Utils::SynchronousProcess adb;
adb.setTimeoutS(timeoutS);
Utils::SynchronousProcessResponse response
= adb.run(m_adb, args);
if (errorMessage)
*errorMessage = response.exitMessage(m_adb, timeoutS);
return response.result == Utils::SynchronousProcessResponse::Finished;
}
void AndroidRunner::handleRemoteDebuggerRunning()
......@@ -535,9 +512,7 @@ void AndroidRunner::handleRemoteDebuggerRunning()
QTemporaryFile tmp(QDir::tempPath() + _("/pingpong"));
tmp.open();
QProcess process;
process.start(m_adb, selector() << _("push") << tmp.fileName() << m_pongFile);
process.waitForFinished();
runAdb(selector() << _("push") << tmp.fileName() << m_pongFile);
}
QTC_CHECK(m_processPID != -1);
}
......@@ -558,11 +533,8 @@ void AndroidRunner::stop()
m_adbLogcatProcess.waitForFinished();
m_psProc.kill();
m_psProc.waitForFinished();
foreach (const QStringList &entry, m_androidRunnable.afterFinishADBCommands) {
QProcess adb;
adb.start(m_adb, selector() << entry);
adb.waitForFinished();
}
foreach (const QStringList &entry, m_androidRunnable.afterFinishADBCommands)
runAdb(selector() << entry);
}
void AndroidRunner::logcatProcess(const QByteArray &text, QByteArray &buffer, bool onlyError)
......@@ -622,19 +594,9 @@ void AndroidRunner::logcatReadStandardOutput()
void AndroidRunner::adbKill(qint64 pid)
{
{
QProcess process;
process.start(m_adb, selector() << _("shell")
<< _("kill") << QLatin1String("-9") << QString::number(pid));
process.waitForFinished();
}
{
QProcess process;
process.start(m_adb, selector() << _("shell")
<< _("run-as") << m_androidRunnable.packageName
<< _("kill") << QLatin1String("-9") << QString::number(pid));
process.waitForFinished();
}