forked from qt-creator/qt-creator
Android: use unix socket for lldb-server communication
This makes the communication between lldb on host and lldb-server on target more robust. Fixes: QTCREATORBUG-32953 Change-Id: I042ca6e52785cca2ab70a5db8144e15b697a2293 Reviewed-by: hjk <hjk@qt.io> Reviewed-by: Alessandro Portale <alessandro.portale@qt.io> Reviewed-by: Jarek Kobus <jaroslaw.kobus@qt.io>
This commit is contained in:
@@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
#include "androidconfigurations.h"
|
#include "androidconfigurations.h"
|
||||||
#include "androidconstants.h"
|
#include "androidconstants.h"
|
||||||
|
#include "androiddevice.h"
|
||||||
#include "androidrunner.h"
|
#include "androidrunner.h"
|
||||||
#include "androidqtversion.h"
|
#include "androidqtversion.h"
|
||||||
#include "androidutils.h"
|
#include "androidutils.h"
|
||||||
@@ -14,6 +15,7 @@
|
|||||||
#include <debugger/debuggerruncontrol.h>
|
#include <debugger/debuggerruncontrol.h>
|
||||||
|
|
||||||
#include <projectexplorer/buildconfiguration.h>
|
#include <projectexplorer/buildconfiguration.h>
|
||||||
|
#include <projectexplorer/devicesupport/devicekitaspects.h>
|
||||||
#include <projectexplorer/project.h>
|
#include <projectexplorer/project.h>
|
||||||
#include <projectexplorer/projectnodes.h>
|
#include <projectexplorer/projectnodes.h>
|
||||||
#include <projectexplorer/target.h>
|
#include <projectexplorer/target.h>
|
||||||
@@ -135,6 +137,10 @@ public:
|
|||||||
const QString devicePreferredAbi = apkDevicePreferredAbi(bc);
|
const QString devicePreferredAbi = apkDevicePreferredAbi(bc);
|
||||||
rp.setToolChainAbi(androidAbi2Abi(devicePreferredAbi));
|
rp.setToolChainAbi(androidAbi2Abi(devicePreferredAbi));
|
||||||
|
|
||||||
|
const IDevice::ConstPtr device = RunDeviceKitAspect::device(kit);
|
||||||
|
const AndroidDevice *androidDevice = static_cast<const AndroidDevice *>(device.get());
|
||||||
|
rp.modifyDebuggerEnvironment({{"ANDROID_SERIAL", androidDevice->serialNumber()}});
|
||||||
|
|
||||||
auto qt = static_cast<AndroidQtVersion *>(qtVersion);
|
auto qt = static_cast<AndroidQtVersion *>(qtVersion);
|
||||||
const int minimumNdk = qt ? qt->minimumNDK() : 0;
|
const int minimumNdk = qt ? qt->minimumNDK() : 0;
|
||||||
|
|
||||||
|
@@ -79,8 +79,9 @@ Group androidRecipe(RunControl *runControl)
|
|||||||
auto iface = runStorage().activeStorage();
|
auto iface = runStorage().activeStorage();
|
||||||
QObject::connect(iface, &RunInterface::canceled, glue, &RunnerInterface::cancel);
|
QObject::connect(iface, &RunInterface::canceled, glue, &RunnerInterface::cancel);
|
||||||
|
|
||||||
QObject::connect(glue, &RunnerInterface::started, runControl, [runControl, iface](qint64 pid) {
|
QObject::connect(glue, &RunnerInterface::started, runControl, [runControl, iface](qint64 pid, const QString &packageDir) {
|
||||||
runControl->setAttachPid(ProcessHandle(pid));
|
runControl->setAttachPid(ProcessHandle(pid));
|
||||||
|
runControl->setDebugChannel(QString("unix-abstract-connect://%1/debug-socket").arg(packageDir));
|
||||||
emit iface->started();
|
emit iface->started();
|
||||||
});
|
});
|
||||||
QObject::connect(glue, &RunnerInterface::finished, runControl, [runControl](const QString &errorString) {
|
QObject::connect(glue, &RunnerInterface::finished, runControl, [runControl](const QString &errorString) {
|
||||||
|
@@ -153,6 +153,7 @@ public:
|
|||||||
RunnerInterface *m_glue = nullptr;
|
RunnerInterface *m_glue = nullptr;
|
||||||
|
|
||||||
QString m_packageName;
|
QString m_packageName;
|
||||||
|
QString m_packageDir;
|
||||||
QString m_intentName;
|
QString m_intentName;
|
||||||
QStringList m_beforeStartAdbCommands;
|
QStringList m_beforeStartAdbCommands;
|
||||||
QStringList m_afterFinishAdbCommands;
|
QStringList m_afterFinishAdbCommands;
|
||||||
@@ -642,7 +643,7 @@ static ExecutableItem uploadDebugServerRecipe(const Storage<RunnerStorage> &stor
|
|||||||
|
|
||||||
const auto onDebugSetupFinished = [storage] {
|
const auto onDebugSetupFinished = [storage] {
|
||||||
storage->m_glue->runControl()->setQmlChannel(storage->m_qmlServer);
|
storage->m_glue->runControl()->setQmlChannel(storage->m_qmlServer);
|
||||||
emit storage->m_glue->started(storage->m_processPID);
|
emit storage->m_glue->started(storage->m_processPID, storage->m_packageDir);
|
||||||
};
|
};
|
||||||
|
|
||||||
return Group {
|
return Group {
|
||||||
@@ -674,23 +675,22 @@ static ExecutableItem startNativeDebuggingRecipe(const Storage<RunnerStorage> &s
|
|||||||
return storage->m_useCppDebugger ? SetupResult::Continue : SetupResult::StopWithSuccess;
|
return storage->m_useCppDebugger ? SetupResult::Continue : SetupResult::StopWithSuccess;
|
||||||
};
|
};
|
||||||
|
|
||||||
const Storage<QString> packageDirStorage;
|
|
||||||
const Storage<QString> debugServerFileStorage;
|
const Storage<QString> debugServerFileStorage;
|
||||||
|
|
||||||
const auto onAppDirSetup = [storage](Process &process) {
|
const auto onAppDirSetup = [storage](Process &process) {
|
||||||
process.setCommand(storage->adbCommand({storage->packageArgs(), "/system/bin/sh", "-c", "pwd"}));
|
process.setCommand(storage->adbCommand({storage->packageArgs(), "/system/bin/sh", "-c", "pwd"}));
|
||||||
};
|
};
|
||||||
const auto onAppDirDone = [storage, packageDirStorage](const Process &process, DoneWith result) {
|
const auto onAppDirDone = [storage](const Process &process, DoneWith result) {
|
||||||
if (result == DoneWith::Success)
|
if (result == DoneWith::Success)
|
||||||
*packageDirStorage = process.stdOut();
|
storage->m_packageDir = process.stdOut().trimmed();
|
||||||
else
|
else
|
||||||
emit storage->m_glue->finished(Tr::tr("Failed to find application directory."));
|
emit storage->m_glue->finished(Tr::tr("Failed to find application directory."));
|
||||||
};
|
};
|
||||||
|
|
||||||
// Add executable flag to package dir. Gdb can't connect to running server on device on
|
// Add executable flag to package dir. Gdb can't connect to running server on device on
|
||||||
// e.g. on Android 8 with NDK 10e
|
// e.g. on Android 8 with NDK 10e
|
||||||
const auto onChmodSetup = [storage, packageDirStorage](Process &process) {
|
const auto onChmodSetup = [storage](Process &process) {
|
||||||
process.setCommand(storage->adbCommand({storage->packageArgs(), "chmod", "a+x", packageDirStorage->trimmed()}));
|
process.setCommand(storage->adbCommand({storage->packageArgs(), "chmod", "a+x", storage->m_packageDir.trimmed()}));
|
||||||
};
|
};
|
||||||
const auto onServerPathCheck = [storage] {
|
const auto onServerPathCheck = [storage] {
|
||||||
if (storage->m_debugServerPath.exists())
|
if (storage->m_debugServerPath.exists())
|
||||||
@@ -718,14 +718,19 @@ static ExecutableItem startNativeDebuggingRecipe(const Storage<RunnerStorage> &s
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const auto onDebugServerSetup = [storage, packageDirStorage, debugServerFileStorage](Process &process) {
|
const auto onRemoveDebugSocketSetup = [storage](Process &process) {
|
||||||
|
const QString serverSocket = storage->m_packageDir + "/debug-socket";
|
||||||
|
process.setCommand(storage->adbCommand({storage->packageArgs(), "rm", serverSocket}));
|
||||||
|
};
|
||||||
|
|
||||||
|
const auto onDebugServerSetup = [storage, debugServerFileStorage](Process &process) {
|
||||||
|
const QString serverSocket = storage->m_packageDir + "/debug-socket";
|
||||||
process.setCommand(storage->adbCommand(
|
process.setCommand(storage->adbCommand(
|
||||||
{storage->packageArgs(), *debugServerFileStorage, "platform",
|
{storage->packageArgs(), *debugServerFileStorage, "platform",
|
||||||
"--listen", QString("*:%1").arg(storage->debugPortString())}));
|
"--listen", QString("unix-abstract://%1").arg(serverSocket)}));
|
||||||
};
|
};
|
||||||
|
|
||||||
return Group {
|
return Group {
|
||||||
packageDirStorage,
|
|
||||||
debugServerFileStorage,
|
debugServerFileStorage,
|
||||||
onGroupSetup(onSetup),
|
onGroupSetup(onSetup),
|
||||||
ProcessTask(onAppDirSetup, onAppDirDone),
|
ProcessTask(onAppDirSetup, onAppDirDone),
|
||||||
@@ -733,6 +738,7 @@ static ExecutableItem startNativeDebuggingRecipe(const Storage<RunnerStorage> &s
|
|||||||
Sync(onServerPathCheck),
|
Sync(onServerPathCheck),
|
||||||
killAll("lldb-server"),
|
killAll("lldb-server"),
|
||||||
uploadDebugServer("./lldb-server"),
|
uploadDebugServer("./lldb-server"),
|
||||||
|
ProcessTask(onRemoveDebugSocketSetup) || successItem,
|
||||||
ProcessTask(onDebugServerSetup)
|
ProcessTask(onDebugServerSetup)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -772,7 +778,7 @@ static ExecutableItem pidRecipe(const Storage<RunnerStorage> &storage)
|
|||||||
qCDebug(androidRunWorkerLog) << "Process ID changed to:" << storage->m_processPID;
|
qCDebug(androidRunWorkerLog) << "Process ID changed to:" << storage->m_processPID;
|
||||||
if (!storage->m_useCppDebugger) {
|
if (!storage->m_useCppDebugger) {
|
||||||
storage->m_glue->runControl()->setQmlChannel(storage->m_qmlServer);
|
storage->m_glue->runControl()->setQmlChannel(storage->m_qmlServer);
|
||||||
emit storage->m_glue->started(storage->m_processPID);
|
emit storage->m_glue->started(storage->m_processPID, storage->m_packageDir);
|
||||||
}
|
}
|
||||||
return DoneResult::Success;
|
return DoneResult::Success;
|
||||||
}
|
}
|
||||||
|
@@ -38,7 +38,7 @@ signals:
|
|||||||
void canceled();
|
void canceled();
|
||||||
|
|
||||||
// business logic -> GUI
|
// business logic -> GUI
|
||||||
void started(qint64 pid);
|
void started(qint64 pid, const QString &packageDir);
|
||||||
void finished(const QString &errorMessage);
|
void finished(const QString &errorMessage);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
Reference in New Issue
Block a user