iOS: Fix slow debugger startup on devices

We need to pass the path to the device symbols, that Xcode downloaded
for the device's OS version, as the sysroot to the debugger. Otherwise
debugger startup is very slow.

We already tried to do that, but it looks like, depending on the
devices, this path can contain an architecture specific part, e.g.
"iOS DeviceSupport/13.5.1 (17F80) arm64e" instead of just "iOS
DeviceSupport/13.5.1 (17F80)". It can still be just the latter, so we
get the devices architecture information, try the architecture specific
directory first, and fall back to the architecture agnostic name as
before if the former doesn't exist.

Fixes: QTCREATORBUG-21682
Change-Id: I2efdbfda0282f1cf0f8d10bd4e5217a298027fcf
Reviewed-by: hjk <hjk@qt.io>
Reviewed-by: Eike Ziller <eike.ziller@qt.io>
This commit is contained in:
Eike Ziller
2020-07-08 16:14:40 +02:00
parent bc517e6d92
commit 72bf4cd15f
4 changed files with 38 additions and 21 deletions

View File

@@ -171,6 +171,11 @@ QString IosDevice::osVersion() const
return m_extraInfo.value(QLatin1String("osVersion")); return m_extraInfo.value(QLatin1String("osVersion"));
} }
QString IosDevice::cpuArchitecture() const
{
return m_extraInfo.value("cpuArchitecture");
}
Utils::Port IosDevice::nextPort() const Utils::Port IosDevice::nextPort() const
{ {
// use qrand instead? // use qrand instead?

View File

@@ -59,6 +59,7 @@ public:
QVariantMap toMap() const override; QVariantMap toMap() const override;
QString uniqueDeviceID() const; QString uniqueDeviceID() const;
QString osVersion() const; QString osVersion() const;
QString cpuArchitecture() const;
Utils::Port nextPort() const; Utils::Port nextPort() const;
bool canAutoDetectPorts() const override; bool canAutoDetectPorts() const override;

View File

@@ -436,28 +436,26 @@ void IosDebugSupport::start()
IosDevice::ConstPtr dev = device().dynamicCast<const IosDevice>(); IosDevice::ConstPtr dev = device().dynamicCast<const IosDevice>();
setStartMode(AttachToRemoteProcess); setStartMode(AttachToRemoteProcess);
setIosPlatform("remote-ios"); setIosPlatform("remote-ios");
QString osVersion = dev->osVersion(); const QString osVersion = dev->osVersion();
FilePath deviceSdk1 = FilePath::fromString(QDir::homePath() const QString cpuArchitecture = dev->cpuArchitecture();
+ "/Library/Developer/Xcode/iOS DeviceSupport/" const FilePaths symbolsPathCandidates = {
+ osVersion + "/Symbols"); FilePath::fromString(QDir::homePath() + "/Library/Developer/Xcode/iOS DeviceSupport/"
QString deviceSdk; + osVersion + " " + cpuArchitecture + "/Symbols"),
if (deviceSdk1.isDir()) { FilePath::fromString(QDir::homePath() + "/Library/Developer/Xcode/iOS DeviceSupport/"
deviceSdk = deviceSdk1.toString(); + osVersion + "/Symbols"),
} else { IosConfigurations::developerPath().pathAppended(
const FilePath deviceSdk2 = IosConfigurations::developerPath() "Platforms/iPhoneOS.platform/DeviceSupport/" + osVersion + "/Symbols")};
.pathAppended("Platforms/iPhoneOS.platform/DeviceSupport/" const FilePath deviceSdk = Utils::findOrDefault(symbolsPathCandidates, &FilePath::isDir);
+ osVersion + "/Symbols");
if (deviceSdk2.isDir()) { if (deviceSdk.isEmpty()) {
deviceSdk = deviceSdk2.toString(); TaskHub::addTask(DeploymentTask(
} else { Task::Warning,
TaskHub::addTask(DeploymentTask(Task::Warning, tr( tr("Could not find device specific debug symbols at %1. "
"Could not find device specific debug symbols at %1. " "Debugging initialization will be slow until you open the Organizer window of "
"Debugging initialization will be slow until you open the Organizer window of " "Xcode with the device connected to have the symbols generated.")
"Xcode with the device connected to have the symbols generated.") .arg(symbolsPathCandidates.constFirst().toUserOutput())));
.arg(deviceSdk1.toUserOutput())));
}
} }
setDeviceSymbolsRoot(deviceSdk); setDeviceSymbolsRoot(deviceSdk.toString());
} else { } else {
setStartMode(AttachExternal); setStartMode(AttachExternal);
setIosPlatform("ios-simulator"); setIosPlatform("ios-simulator");

View File

@@ -1593,6 +1593,7 @@ void DevInfoSession::deviceCallbackReturned()
QString developerStatusKey = QLatin1String("developerStatus"); QString developerStatusKey = QLatin1String("developerStatus");
QString deviceConnectedKey = QLatin1String("deviceConnected"); QString deviceConnectedKey = QLatin1String("deviceConnected");
QString osVersionKey = QLatin1String("osVersion"); QString osVersionKey = QLatin1String("osVersion");
QString cpuArchitectureKey = "cpuArchitecture";
bool failure = !device; bool failure = !device;
if (!failure) { if (!failure) {
failure = !connectDevice(); failure = !connectDevice();
@@ -1631,6 +1632,18 @@ void DevInfoSession::deviceCallbackReturned()
0, 0,
CFSTR("BuildVersion")); CFSTR("BuildVersion"));
//CFShow(cfBuildVersion); //CFShow(cfBuildVersion);
CFPropertyListRef cfCpuArchitecture = lib()->deviceCopyValue(device,
0,
CFSTR("CPUArchitecture"));
//CFShow(cfCpuArchitecture);
if (cfCpuArchitecture) {
if (CFGetTypeID(cfCpuArchitecture) == CFStringGetTypeID()) {
res[cpuArchitectureKey] = QString::fromCFString(
reinterpret_cast<CFStringRef>(cfCpuArchitecture));
}
CFRelease(cfCpuArchitecture);
}
//CFShow(cfBuildVersion);
QString versionString; QString versionString;
if (cfProductVersion) { if (cfProductVersion) {
if (CFGetTypeID(cfProductVersion) == CFStringGetTypeID()) if (CFGetTypeID(cfProductVersion) == CFStringGetTypeID())