summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVikas Pachdha <vikas.pachdha@qt.io>2018-12-20 18:40:34 +0100
committerVikas Pachdha <vikas.pachdha@qt.io>2019-02-01 08:17:56 +0000
commit59de3fcb6416dc0387e85a1852d1226ae507b7fe (patch)
tree366aa2110114b3a928ce97ab39b09e6c35f7f84b
parentd886285ff0f9931b39a6069bc5260cf2148757eb (diff)
downloadqt-creator-59de3fcb6416dc0387e85a1852d1226ae507b7fe.tar.gz
Android: Fix gdbserver upload for Windows when using Armv8 arch
The gdbserver is not uploaded to device for armv7 as lib symlink is available and we can use the gdbserver packaged with the apk Task-number: QTCREATORBUG-21317 Change-Id: I263eb48bbf3cf05b969db934a928185dba10373b Reviewed-by: Eike Ziller <eike.ziller@qt.io> Reviewed-by: hjk <hjk@qt.io>
-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,