Fix debugging on Android arm64/x86_64

On Android 64, there is no lib/ symlink anymore, so we need to upload
gdbserver from QtCreator.

Change-Id: Ib6f6d9b623dc61b72dd434ce1b3b409e880bdeaa
Reviewed-by: Vikas Pachdha <vikas.pachdha@qt.io>
This commit is contained in:
BogDan Vatra
2018-10-01 14:22:49 +03:00
parent 8f987866b6
commit 25264d9bd9
8 changed files with 71 additions and 25 deletions

View File

@@ -29,6 +29,7 @@
#include "androidconstants.h"
#include "androidmanager.h"
#include "androidrunconfiguration.h"
#include "androidgdbserverkitinformation.h"
#include <debugger/debuggerrunconfigurationaspect.h>
#include <projectexplorer/environmentaspect.h>
@@ -42,6 +43,7 @@
#include <utils/temporaryfile.h>
#include <utils/qtcprocess.h>
#include <utils/url.h>
#include <utils/fileutils.h>
#include <QLoggingCategory>
#include <QTcpServer>
@@ -222,6 +224,7 @@ AndroidRunnerWorker::AndroidRunnerWorker(RunWorker *runner, const QString &packa
<< "Extra Start Args:" << m_amStartExtraArgs
<< "Before Start ADB cmds:" << m_beforeStartAdbCommands
<< "After finish ADB cmds:" << m_afterFinishAdbCommands;
m_gdbserverPath = AndroidGdbServerKitInformation::gdbServer(target->kit()).toString();
}
AndroidRunnerWorker::~AndroidRunnerWorker()
@@ -255,13 +258,13 @@ bool AndroidRunnerWorker::adbShellAmNeedsQuotes()
return !oldSdk;
}
bool AndroidRunnerWorker::runAdb(const QStringList &args, int timeoutS)
bool AndroidRunnerWorker::runAdb(const QStringList &args, int timeoutS, const QByteArray &writeData)
{
QStringList adbArgs = selector() + args;
qCDebug(androidRunWorkerLog) << "ADB command: " << m_adb << adbArgs.join(' ');
Utils::SynchronousProcess adb;
adb.setTimeoutS(timeoutS);
Utils::SynchronousProcessResponse response = adb.run(m_adb, adbArgs);
Utils::SynchronousProcessResponse response = adb.run(m_adb, adbArgs, writeData);
m_lastRunAdbError = response.exitMessage(m_adb, timeoutS);
m_lastRunAdbRawOutput = response.allRawOutput();
bool success = response.result == Utils::SynchronousProcessResponse::Finished;
@@ -269,6 +272,18 @@ bool AndroidRunnerWorker::runAdb(const QStringList &args, int timeoutS)
return success;
}
bool AndroidRunnerWorker::uploadFile(const QString &from, const QString &to, const QString &flags)
{
QFile f(from);
if (!f.open(QIODevice::ReadOnly))
return false;
runAdb({"shell", "run-as", m_packageName, "rm", to});
auto res = runAdb({"shell", "run-as", m_packageName, "sh", "-c", QString("'cat > %1'").arg(to)}, 60, f.readAll());
if (!res)
return false;
return runAdb({"shell", "run-as", m_packageName, "chmod", flags, to});
}
void AndroidRunnerWorker::adbKill(qint64 pid)
{
runAdb({"shell", "kill", "-9", QString::number(pid)});
@@ -411,9 +426,15 @@ void AndroidRunnerWorker::asyncStartHelper()
runAdb({"shell", "run-as", m_packageName, "chmod", "a+x", packageDir});
QString gdbServerExecutable;
QString gdbServerPrefix = "./lib/";
if (!runAdb({"shell", "run-as", m_packageName, "ls", "lib/"})) {
emit remoteProcessFinished(tr("Failed to get process path. Reason: %1.").arg(m_lastRunAdbError));
return;
if (m_gdbserverPath.isEmpty()) {
emit remoteProcessFinished(tr("Failed to get process path. Reason: %1.").arg(m_lastRunAdbError));
return;
}
uploadFile(m_gdbserverPath, "gdbserver");
runAdb({"shell", "run-as", m_packageName, "ls"});
gdbServerPrefix = "./";
}
for (const auto &line: m_lastRunAdbRawOutput.split('\n')) {
@@ -433,7 +454,7 @@ void AndroidRunnerWorker::asyncStartHelper()
runAdb({"shell", "run-as", m_packageName, "rm", gdbServerSocket});
std::unique_ptr<QProcess, Deleter> gdbServerProcess(new QProcess, deleter);
gdbServerProcess->start(m_adb, selector() << "shell" << "run-as"
<< m_packageName << "lib/" + gdbServerExecutable
<< m_packageName << gdbServerPrefix + gdbServerExecutable
<< "--multi" << "+" + gdbServerSocket);
if (!gdbServerProcess->waitForStarted()) {
emit remoteProcessFinished(tr("Failed to start C++ debugger."));