diff options
author | Eike Ziller <eike.ziller@qt.io> | 2025-01-27 16:26:59 +0100 |
---|---|---|
committer | Eike Ziller <eike.ziller@qt.io> | 2025-01-28 07:36:15 +0000 |
commit | 54e897396452ae9145e19a6685a59a91a46254b8 (patch) | |
tree | ca830e5cb463709846187939936b3b8859c87e3a | |
parent | 99185d04ec355f1046e9cc6fa45df247f5080536 (diff) |
iOS: Fix debugging and QML profiling on Simulatorv16.0.0-beta1
Fixes a crash that was introduced by a6aa050890789f689f3780cc5481f6e0340b5468 - the simulator device is not derived from IosDevice, so we may not assume that. Re-implement IosSimulator::portsGatheringRecipe - the base implementation tries to run netstat "on" the simulator device, instead do the same just locally, since the ports for the simulator are effectively local ports. Also remove the custom port range for the same reason. Fixes: QTCREATORBUG-32416 Change-Id: I7294d0c20e94bafb9eb4590b7faaf6652792cbb1 Reviewed-by: Jarek Kobus <jaroslaw.kobus@qt.io>
-rw-r--r-- | src/plugins/ios/iosconstants.h | 2 | ||||
-rw-r--r-- | src/plugins/ios/iosrunner.cpp | 31 | ||||
-rw-r--r-- | src/plugins/ios/iossimulator.cpp | 36 | ||||
-rw-r--r-- | src/plugins/ios/iossimulator.h | 10 |
4 files changed, 37 insertions, 42 deletions
diff --git a/src/plugins/ios/iosconstants.h b/src/plugins/ios/iosconstants.h index 12f2f4ef739..87003fec954 100644 --- a/src/plugins/ios/iosconstants.h +++ b/src/plugins/ios/iosconstants.h @@ -30,8 +30,6 @@ const char IosCmakeGenerator[] = "IosCmakeGenerator"; const quint16 IOS_DEVICE_PORT_START = 30000; const quint16 IOS_DEVICE_PORT_END = 31000; -const quint16 IOS_SIMULATOR_PORT_START = 30000; -const quint16 IOS_SIMULATOR_PORT_END = 31000; const char EXTRA_INFO_KEY[] = "extraInfo"; diff --git a/src/plugins/ios/iosrunner.cpp b/src/plugins/ios/iosrunner.cpp index 61f4a52d14d..53dee22e590 100644 --- a/src/plugins/ios/iosrunner.cpp +++ b/src/plugins/ios/iosrunner.cpp @@ -632,18 +632,8 @@ void IosRunner::start() reportFailure(); return; } - if (m_device->type() == Ios::Constants::IOS_DEVICE_TYPE) { - if (m_qmlDebugServices != NoQmlDebugServices) - m_qmlServerPort = Port(runControl()->qmlChannel().port()); - } else { - IosSimulator::ConstPtr sim = std::dynamic_pointer_cast<const IosSimulator>(m_device); - if (!sim) { - reportFailure(); - return; - } - if (m_qmlDebugServices != NoQmlDebugServices) - m_qmlServerPort = sim->nextPort(); - } + if (m_qmlDebugServices != NoQmlDebugServices) + m_qmlServerPort = Port(runControl()->qmlChannel().port()); m_toolHandler = new IosToolHandler(m_deviceType, this); connect(m_toolHandler, &IosToolHandler::appOutput, @@ -899,6 +889,10 @@ IosDebugSupport::IosDebugSupport(RunControl *runControl) setId("IosDebugSupport"); IosDevice::ConstPtr dev = std::dynamic_pointer_cast<const IosDevice>(runControl->device()); + const bool isIosDeviceType = runControl->device()->type() == Ios::Constants::IOS_DEVICE_TYPE; + const bool isIosDeviceInstance = bool(dev); + // type info and device class must match + QTC_ASSERT(isIosDeviceInstance == isIosDeviceType, return); DebuggerRunParameters &rp = runParameters(); // TODO cannot use setupPortsGatherer() from DebuggerRunTool, because that also requests // the "debugChannel", which then results in runControl trying to retrieve ports&URL for that @@ -907,8 +901,7 @@ IosDebugSupport::IosDebugSupport(RunControl *runControl) if (rp.isQmlDebugging()) runControl->requestQmlChannel(); - if (dev->type() == Ios::Constants::IOS_SIMULATOR_TYPE - || dev->handler() == IosDevice::Handler::IosTool) { + if (!isIosDeviceInstance /*== simulator */ || dev->handler() == IosDevice::Handler::IosTool) { m_iosRunner = new IosRunner(runControl); m_iosRunner->setCppDebugging(rp.isCppDebugging()); m_iosRunner->setQmlDebugging(rp.isQmlDebugging() ? QmlDebuggerServices : NoQmlDebugServices); @@ -920,7 +913,7 @@ IosDebugSupport::IosDebugSupport(RunControl *runControl) addStartDependency(m_deviceCtlRunner); } - if (runControl->device()->type() == Ios::Constants::IOS_DEVICE_TYPE) { + if (isIosDeviceInstance) { if (dev->handler() == IosDevice::Handler::DeviceCtl) { QTC_CHECK(IosDeviceManager::isDeviceCtlDebugSupported()); rp.setStartMode(AttachToIosDevice); @@ -950,8 +943,12 @@ void IosDebugSupport::start() rp.setContinueAfterAttach(true); IosDevice::ConstPtr dev = std::dynamic_pointer_cast<const IosDevice>(runControl()->device()); - if (dev->type() == Ios::Constants::IOS_DEVICE_TYPE - && dev->handler() == IosDevice::Handler::DeviceCtl) { + const bool isIosDeviceType = runControl()->device()->type() == Ios::Constants::IOS_DEVICE_TYPE; + const bool isIosDeviceInstance = bool(dev); + // type info and device class must match + QTC_ASSERT(isIosDeviceInstance == isIosDeviceType, reportFailure(Tr::tr("Internal error.")); + return); + if (isIosDeviceInstance && dev->handler() == IosDevice::Handler::DeviceCtl) { const auto msgOnlyCppDebuggingSupported = [] { return Tr::tr("Only C++ debugging is supported for devices with iOS 17 and later."); }; diff --git a/src/plugins/ios/iossimulator.cpp b/src/plugins/ios/iossimulator.cpp index a5f3fbb3464..7247a23a749 100644 --- a/src/plugins/ios/iossimulator.cpp +++ b/src/plugins/ios/iossimulator.cpp @@ -9,10 +9,12 @@ #include <utils/port.h> #include <utils/qtcprocess.h> +#include <utils/url.h> #include <QMapIterator> using namespace ProjectExplorer; +using namespace Tasking; using namespace Utils; namespace Ios::Internal { @@ -22,7 +24,6 @@ const char iosDeviceTypeTypeKey[] = "type"; const char iosDeviceTypeIdentifierKey[] = "identifier"; IosSimulator::IosSimulator(Id id) - : m_lastPort(Constants::IOS_SIMULATOR_PORT_START) { setupId(IDevice::AutoDetected, id); setType(Constants::IOS_SIMULATOR_TYPE); @@ -47,24 +48,23 @@ IDeviceWidget *IosSimulator::createWidget() return nullptr; } -Utils::Port IosSimulator::nextPort() const +ExecutableItem IosSimulator::portsGatheringRecipe(const Storage<PortsOutputData> &output) const { - for (int i = 0; i < 100; ++i) { - // use qrand instead? - if (++m_lastPort >= Constants::IOS_SIMULATOR_PORT_END) - m_lastPort = Constants::IOS_SIMULATOR_PORT_START; - Utils::Process portVerifier; - // this is a bit too broad (it does not check just listening sockets, but also connections - // to that port from this computer) - portVerifier.setCommand({"lsof", {"-n", "-P", "-i", QString(":%1").arg(m_lastPort)}}); - portVerifier.start(); - if (!portVerifier.waitForFinished()) - break; - if (portVerifier.exitStatus() != QProcess::NormalExit - || portVerifier.exitCode() != 0) - break; - } - return Utils::Port(m_lastPort); + // This is the same as in IDevice::portsGatheringRecipe, but running netstat locally + const Storage<PortsInputData> input; + const auto onSetup = [this, input] { + const CommandLine cmd = CommandLine{"netstat", {"-a", "-n"}}; + *input = {freePorts(), cmd}; + }; + return Group{input, onGroupSetup(onSetup), portsFromProcessRecipe(input, output)}; +} + +QUrl IosSimulator::toolControlChannel(const ControlChannelHint &) const +{ + QUrl url; + url.setScheme(Utils::urlTcpScheme()); + url.setHost("localhost"); + return url; } // IosDeviceType diff --git a/src/plugins/ios/iossimulator.h b/src/plugins/ios/iossimulator.h index a93a0ec8601..5af917ad40e 100644 --- a/src/plugins/ios/iossimulator.h +++ b/src/plugins/ios/iossimulator.h @@ -47,16 +47,16 @@ public: ProjectExplorer::IDevice::DeviceInfo deviceInformation() const override; ProjectExplorer::IDeviceWidget *createWidget() override; - Utils::Port nextPort() const; -protected: +private: + Tasking::ExecutableItem portsGatheringRecipe( + const Tasking::Storage<Utils::PortsOutputData> &output) const override; + QUrl toolControlChannel(const ControlChannelHint &) const override; + friend class IosSimulatorFactory; friend class IosConfigurations; IosSimulator(); IosSimulator(Utils::Id id); - -private: - mutable quint16 m_lastPort; }; class IosSimulatorFactory final : public ProjectExplorer::IDeviceFactory |