forked from qt-creator/qt-creator
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>
This commit is contained in:
@@ -53,6 +53,7 @@
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
Q_LOGGING_CATEGORY(androidRunWorkerLog, "qtc.android.run.androidrunnerworker", QtWarningMsg)
|
Q_LOGGING_CATEGORY(androidRunWorkerLog, "qtc.android.run.androidrunnerworker", QtWarningMsg)
|
||||||
|
static const int GdbTempFileMaxCounter = 20;
|
||||||
}
|
}
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
@@ -274,17 +275,58 @@ bool AndroidRunnerWorker::runAdb(const QStringList &args, int timeoutS, const QB
|
|||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AndroidRunnerWorker::uploadFile(const QString &from, const QString &to, const QString &flags)
|
bool AndroidRunnerWorker::uploadGdbServer()
|
||||||
{
|
{
|
||||||
QFile f(from);
|
// Push the gdbserver to temp location and then to package dir.
|
||||||
if (!f.open(QIODevice::ReadOnly))
|
// 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;
|
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());
|
// Copy gdbserver from temp location to app directory
|
||||||
if (!res || m_lastRunAdbRawOutput.contains("base64: not found"))
|
if (!runAdb({"shell", "run-as", m_packageName, "cp" , *tempGdbServerPath, "./gdbserver"})) {
|
||||||
|
qCDebug(androidRunWorkerLog) << "Gdbserver copy from temp directory failed";
|
||||||
return false;
|
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)
|
void AndroidRunnerWorker::adbKill(qint64 pid)
|
||||||
@@ -428,29 +470,31 @@ void AndroidRunnerWorker::asyncStartHelper()
|
|||||||
// e.g. on Android 8 with NDK 10e
|
// e.g. on Android 8 with NDK 10e
|
||||||
runAdb({"shell", "run-as", m_packageName, "chmod", "a+x", packageDir});
|
runAdb({"shell", "run-as", m_packageName, "chmod", "a+x", packageDir});
|
||||||
|
|
||||||
QString gdbServerExecutable;
|
QString gdbServerExecutable = "gdbserver";
|
||||||
QString gdbServerPrefix = "./lib/";
|
QString gdbServerPrefix = "./lib/";
|
||||||
if (m_gdbserverPath.isEmpty() || !uploadFile(m_gdbserverPath, "gdbserver")) {
|
auto findGdbServer = [this, &gdbServerExecutable, gdbServerPrefix](const QString& gdbEx) {
|
||||||
// upload failed - check for old devices
|
if (!packageFileExists(gdbServerPrefix + gdbEx))
|
||||||
if (runAdb({"shell", "run-as", m_packageName, "ls", "lib/"})) {
|
return false;
|
||||||
for (const auto &line: m_lastRunAdbRawOutput.split('\n')) {
|
gdbServerExecutable = gdbEx;
|
||||||
if (line.indexOf("gdbserver") != -1/* || line.indexOf("lldb-server") != -1*/) {
|
return true;
|
||||||
gdbServerExecutable = QString::fromUtf8(line.trimmed());
|
};
|
||||||
break;
|
|
||||||
}
|
if (!findGdbServer("gdbserver") && !findGdbServer("libgdbserver.so")) {
|
||||||
}
|
// Armv8. symlink lib is not available.
|
||||||
}
|
// Kill the previous instances of gdbserver. Do this before copying the gdbserver.
|
||||||
if (gdbServerExecutable.isEmpty()) {
|
runAdb({"shell", "run-as", m_packageName, "killall", gdbServerExecutable});
|
||||||
|
if (!m_gdbserverPath.isEmpty() && uploadGdbServer()) {
|
||||||
|
gdbServerPrefix = "./";
|
||||||
|
} else {
|
||||||
emit remoteProcessFinished(tr("Cannot find/copy C++ debug server."));
|
emit remoteProcessFinished(tr("Cannot find/copy C++ debug server."));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
gdbServerPrefix = "./";
|
qCDebug(androidRunWorkerLog) << "Found GDB server under ./lib";
|
||||||
gdbServerExecutable = "gdbserver";
|
runAdb({"shell", "run-as", m_packageName, "killall", gdbServerExecutable});
|
||||||
}
|
}
|
||||||
|
|
||||||
QString gdbServerSocket = packageDir + "/debug-socket";
|
QString gdbServerSocket = packageDir + "/debug-socket";
|
||||||
runAdb({"shell", "run-as", m_packageName, "killall", gdbServerExecutable});
|
|
||||||
runAdb({"shell", "run-as", m_packageName, "rm", gdbServerSocket});
|
runAdb({"shell", "run-as", m_packageName, "rm", gdbServerSocket});
|
||||||
|
|
||||||
std::unique_ptr<QProcess, Deleter> gdbServerProcess(new QProcess, deleter);
|
std::unique_ptr<QProcess, Deleter> gdbServerProcess(new QProcess, deleter);
|
||||||
|
@@ -48,7 +48,6 @@ public:
|
|||||||
~AndroidRunnerWorker() override;
|
~AndroidRunnerWorker() override;
|
||||||
bool adbShellAmNeedsQuotes();
|
bool adbShellAmNeedsQuotes();
|
||||||
bool runAdb(const QStringList &args, int timeoutS = 10, const QByteArray &writeData = {});
|
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);
|
void adbKill(qint64 pid);
|
||||||
QStringList selector() const;
|
QStringList selector() const;
|
||||||
void forceStop();
|
void forceStop();
|
||||||
@@ -71,8 +70,11 @@ signals:
|
|||||||
void remoteOutput(const QString &output);
|
void remoteOutput(const QString &output);
|
||||||
void remoteErrorOutput(const QString &output);
|
void remoteErrorOutput(const QString &output);
|
||||||
|
|
||||||
protected:
|
private:
|
||||||
void asyncStartHelper();
|
void asyncStartHelper();
|
||||||
|
bool deviceFileExists(const QString &filePath);
|
||||||
|
bool packageFileExists(const QString& filePath);
|
||||||
|
bool uploadGdbServer();
|
||||||
|
|
||||||
enum class JDBState {
|
enum class JDBState {
|
||||||
Idle,
|
Idle,
|
||||||
|
Reference in New Issue
Block a user