summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/plugins/android/androidrunnerworker.cpp90
-rw-r--r--src/plugins/android/androidrunnerworker.h6
2 files changed, 71 insertions, 25 deletions
diff --git a/src/plugins/android/androidrunnerworker.cpp b/src/plugins/android/androidrunnerworker.cpp
index a4b6772f61..37191848fd 100644
--- a/src/plugins/android/androidrunnerworker.cpp
+++ b/src/plugins/android/androidrunnerworker.cpp
@@ -53,6 +53,7 @@
namespace {
Q_LOGGING_CATEGORY(androidRunWorkerLog, "qtc.android.run.androidrunnerworker", QtWarningMsg)
+static const int GdbTempFileMaxCounter = 20;
}
using namespace std;
@@ -274,17 +275,58 @@ bool AndroidRunnerWorker::runAdb(const QStringList &args, int timeoutS, const QB
return success;
}
-bool AndroidRunnerWorker::uploadFile(const QString &from, const QString &to, const QString &flags)
+bool AndroidRunnerWorker::uploadGdbServer()
{
- QFile f(from);
- if (!f.open(QIODevice::ReadOnly))
+ // Push the gdbserver to temp location and then to package dir.
+ // the files can't be pushed directly to package because of permissions.
+ qCDebug(androidRunWorkerLog) << "Uploading GdbServer";
+
+ bool foundUnique = true;
+ auto cleanUp = [this, &foundUnique] (QString *p) {
+ if (foundUnique && !runAdb({"shell", "rm", "-f", *p}))
+ qCDebug(androidRunWorkerLog) << "Gdbserver cleanup failed.";
+ delete p;
+ };
+ std::unique_ptr<QString, decltype (cleanUp)>
+ tempGdbServerPath(new QString("/data/local/tmp/%1"), cleanUp);
+
+ // Get a unique temp file name for gdbserver copy
+ int count = 0;
+ while (deviceFileExists(tempGdbServerPath->arg(++count))) {
+ if (count > GdbTempFileMaxCounter) {
+ qCDebug(androidRunWorkerLog) << "Can not get temporary file name";
+ foundUnique = false;
+ return false;
+ }
+ }
+ *tempGdbServerPath = tempGdbServerPath->arg(count);
+
+ // Copy gdbserver to temp location
+ if (!runAdb({"push", m_gdbserverPath , *tempGdbServerPath})) {
+ qCDebug(androidRunWorkerLog) << "Gdbserver upload to temp directory failed";
return false;
- runAdb({"shell", "run-as", m_packageName, "rm", to});
- const QByteArray data = f.readAll();
- const bool res = runAdb({"shell", "run-as", m_packageName, QString("sh -c 'base64 -d > %1'").arg(to)}, 60, data.toBase64());
- if (!res || m_lastRunAdbRawOutput.contains("base64: not found"))
+ }
+
+ // Copy gdbserver from temp location to app directory
+ if (!runAdb({"shell", "run-as", m_packageName, "cp" , *tempGdbServerPath, "./gdbserver"})) {
+ qCDebug(androidRunWorkerLog) << "Gdbserver copy from temp directory failed";
return false;
- return runAdb({"shell", "run-as", m_packageName, "chmod", flags, to});
+ }
+ QTC_ASSERT(runAdb({"shell", "run-as", m_packageName, "chmod", "+x", "./gdbserver"}),
+ qCDebug(androidRunWorkerLog) << "Gdbserver chmod +x failed.");
+ return true;
+}
+
+bool AndroidRunnerWorker::deviceFileExists(const QString &filePath)
+{
+ return runAdb({"shell", "ls", filePath, "2>/dev/null"})
+ && !m_lastRunAdbRawOutput.trimmed().isEmpty();
+}
+
+bool AndroidRunnerWorker::packageFileExists(const QString &filePath)
+{
+ return runAdb({"shell", "run-as", m_packageName, "ls", filePath, "2>/dev/null"})
+ && !m_lastRunAdbRawOutput.trimmed().isEmpty();
}
void AndroidRunnerWorker::adbKill(qint64 pid)
@@ -428,29 +470,31 @@ void AndroidRunnerWorker::asyncStartHelper()
// e.g. on Android 8 with NDK 10e
runAdb({"shell", "run-as", m_packageName, "chmod", "a+x", packageDir});
- QString gdbServerExecutable;
+ QString gdbServerExecutable = "gdbserver";
QString gdbServerPrefix = "./lib/";
- if (m_gdbserverPath.isEmpty() || !uploadFile(m_gdbserverPath, "gdbserver")) {
- // upload failed - check for old devices
- if (runAdb({"shell", "run-as", m_packageName, "ls", "lib/"})) {
- for (const auto &line: m_lastRunAdbRawOutput.split('\n')) {
- if (line.indexOf("gdbserver") != -1/* || line.indexOf("lldb-server") != -1*/) {
- gdbServerExecutable = QString::fromUtf8(line.trimmed());
- break;
- }
- }
- }
- if (gdbServerExecutable.isEmpty()) {
+ auto findGdbServer = [this, &gdbServerExecutable, gdbServerPrefix](const QString& gdbEx) {
+ if (!packageFileExists(gdbServerPrefix + gdbEx))
+ return false;
+ gdbServerExecutable = gdbEx;
+ return true;
+ };
+
+ if (!findGdbServer("gdbserver") && !findGdbServer("libgdbserver.so")) {
+ // Armv8. symlink lib is not available.
+ // Kill the previous instances of gdbserver. Do this before copying the gdbserver.
+ runAdb({"shell", "run-as", m_packageName, "killall", gdbServerExecutable});
+ if (!m_gdbserverPath.isEmpty() && uploadGdbServer()) {
+ gdbServerPrefix = "./";
+ } else {
emit remoteProcessFinished(tr("Cannot find/copy C++ debug server."));
return;
}
} else {
- gdbServerPrefix = "./";
- gdbServerExecutable = "gdbserver";
+ qCDebug(androidRunWorkerLog) << "Found GDB server under ./lib";
+ runAdb({"shell", "run-as", m_packageName, "killall", gdbServerExecutable});
}
QString gdbServerSocket = packageDir + "/debug-socket";
- runAdb({"shell", "run-as", m_packageName, "killall", gdbServerExecutable});
runAdb({"shell", "run-as", m_packageName, "rm", gdbServerSocket});
std::unique_ptr<QProcess, Deleter> gdbServerProcess(new QProcess, deleter);
diff --git a/src/plugins/android/androidrunnerworker.h b/src/plugins/android/androidrunnerworker.h
index 18639683ae..39b25a1a29 100644
--- a/src/plugins/android/androidrunnerworker.h
+++ b/src/plugins/android/androidrunnerworker.h
@@ -48,7 +48,6 @@ public:
~AndroidRunnerWorker() override;
bool adbShellAmNeedsQuotes();
bool runAdb(const QStringList &args, int timeoutS = 10, const QByteArray &writeData = {});
- bool uploadFile(const QString &from, const QString &to, const QString &flags = QString("+x"));
void adbKill(qint64 pid);
QStringList selector() const;
void forceStop();
@@ -71,8 +70,11 @@ signals:
void remoteOutput(const QString &output);
void remoteErrorOutput(const QString &output);
-protected:
+private:
void asyncStartHelper();
+ bool deviceFileExists(const QString &filePath);
+ bool packageFileExists(const QString& filePath);
+ bool uploadGdbServer();
enum class JDBState {
Idle,