diff --git a/src/libs/qmldebug/qmldebugconstants.h b/src/libs/qmldebug/qmldebugconstants.h index 0431d707b8b..b1d59e39740 100644 --- a/src/libs/qmldebug/qmldebugconstants.h +++ b/src/libs/qmldebug/qmldebugconstants.h @@ -40,6 +40,7 @@ const char STR_UNABLE_TO_LISTEN[] = "Unable to listen "; const char STR_IGNORING_DEBUGGER[] = "Ignoring \"-qmljsdebugger="; const char STR_IGNORING_DEBUGGER2[] = "Ignoring\"-qmljsdebugger="; // There is (was?) a bug in one of the error strings - safest to handle both const char STR_CONNECTION_ESTABLISHED[] = "Connection established"; +const char STR_CONNECTING_TO_SOCKET[] = "Connecting to socket"; const char QDECLARATIVE_ENGINE[] = "QDeclarativeEngine"; diff --git a/src/libs/qmldebug/qmloutputparser.cpp b/src/libs/qmldebug/qmloutputparser.cpp index ed65274a1dd..e0e2e1d3c63 100644 --- a/src/libs/qmldebug/qmloutputparser.cpp +++ b/src/libs/qmldebug/qmloutputparser.cpp @@ -79,6 +79,7 @@ void QmlOutputParser::processOutput(const QString &output) static QString debuggingNotEnabled = QLatin1String(Constants::STR_IGNORING_DEBUGGER); static QString debuggingNotEnabled2 = QLatin1String(Constants::STR_IGNORING_DEBUGGER2); static QString connectionEstablished = QLatin1String(Constants::STR_CONNECTION_ESTABLISHED); + static QString connectingToSocket = QLatin1String(Constants::STR_CONNECTING_TO_SOCKET); if (status.startsWith(waitingForConnection)) { status.remove(0, waitingForConnection.size()); // chop of 'Waiting for connection ' @@ -100,6 +101,8 @@ void QmlOutputParser::processOutput(const QString &output) emit errorMessage(tr("The application is not set up for QML/JS debugging.")); } else if (status.startsWith(connectionEstablished)) { emit connectionEstablishedMessage(); + } else if (status.startsWith(connectingToSocket)) { + emit connectingToSocketMessage(); } else { emit unknownMessage(status); } diff --git a/src/libs/qmldebug/qmloutputparser.h b/src/libs/qmldebug/qmloutputparser.h index ecac308ef33..5390ecf77cd 100644 --- a/src/libs/qmldebug/qmloutputparser.h +++ b/src/libs/qmldebug/qmloutputparser.h @@ -49,6 +49,7 @@ public: signals: void waitingForConnectionOnPort(quint16 port); void connectionEstablishedMessage(); + void connectingToSocketMessage(); void errorMessage(const QString &detailedError); void unknownMessage(const QString &unknownMessage); void noOutputMessage(); diff --git a/src/plugins/analyzerbase/analyzerstartparameters.h b/src/plugins/analyzerbase/analyzerstartparameters.h index 3eab41f734c..c840095eefa 100644 --- a/src/plugins/analyzerbase/analyzerstartparameters.h +++ b/src/plugins/analyzerbase/analyzerstartparameters.h @@ -62,6 +62,7 @@ public: QString workingDirectory; QString sysroot; QString analyzerHost; + QString analyzerSocket; quint16 analyzerPort = 0; }; diff --git a/src/plugins/qmlprofiler/localqmlprofilerrunner.cpp b/src/plugins/qmlprofiler/localqmlprofilerrunner.cpp index 2d59e4e3a19..9d49420f27e 100644 --- a/src/plugins/qmlprofiler/localqmlprofilerrunner.cpp +++ b/src/plugins/qmlprofiler/localqmlprofilerrunner.cpp @@ -44,6 +44,7 @@ #include #include +#include using namespace QmlProfiler; using namespace ProjectExplorer; @@ -71,7 +72,7 @@ Analyzer::AnalyzerRunControl *LocalQmlProfilerRunner::createLocalRunControl( conf.executableArguments = sp.debuggeeArgs; conf.workingDirectory = sp.workingDirectory; conf.environment = sp.environment; - + conf.socket = sp.analyzerSocket; conf.port = sp.analyzerPort; if (conf.executable.isEmpty()) { @@ -92,6 +93,17 @@ Analyzer::AnalyzerRunControl *LocalQmlProfilerRunner::createLocalRunControl( return rc; } +QString LocalQmlProfilerRunner::findFreeSocket() +{ + QTemporaryFile file; + if (file.open()) { + return file.fileName(); + } else { + qWarning() << "Could not open a temporary file to find a debug socket."; + return QString(); + } +} + quint16 LocalQmlProfilerRunner::findFreePort(QString &host) { QTcpServer server; @@ -121,15 +133,21 @@ LocalQmlProfilerRunner::~LocalQmlProfilerRunner() void LocalQmlProfilerRunner::start() { - QString arguments = QmlDebug::qmlDebugTcpArguments(QmlDebug::QmlProfilerServices, - m_configuration.port); + QString arguments = m_configuration.socket.isEmpty() ? + QmlDebug::qmlDebugTcpArguments(QmlDebug::QmlProfilerServices, + m_configuration.port) : + QmlDebug::qmlDebugLocalArguments(QmlDebug::QmlProfilerServices, + m_configuration.socket); + if (!m_configuration.executableArguments.isEmpty()) arguments += QLatin1Char(' ') + m_configuration.executableArguments; - if (QmlProfilerPlugin::debugOutput) - qWarning("QmlProfiler: Launching %s:%d", qPrintable(m_configuration.executable), - m_configuration.port); + if (QmlProfilerPlugin::debugOutput) { + qWarning("QmlProfiler: Launching %s:%s", qPrintable(m_configuration.executable), + qPrintable(m_configuration.socket.isEmpty() ? + QString::number(m_configuration.port) : m_configuration.socket)); + } m_launcher.setWorkingDirectory(m_configuration.workingDirectory); m_launcher.setEnvironment(m_configuration.environment); diff --git a/src/plugins/qmlprofiler/localqmlprofilerrunner.h b/src/plugins/qmlprofiler/localqmlprofilerrunner.h index 57063e7b4fc..1094ad482bd 100644 --- a/src/plugins/qmlprofiler/localqmlprofilerrunner.h +++ b/src/plugins/qmlprofiler/localqmlprofilerrunner.h @@ -53,6 +53,7 @@ public: QString executable; QString executableArguments; quint16 port; + QString socket; QString workingDirectory; Utils::Environment environment; }; @@ -63,6 +64,7 @@ public: QString *errorMessage); static quint16 findFreePort(QString &host); + static QString findFreeSocket(); ~LocalQmlProfilerRunner(); diff --git a/src/plugins/qmlprofiler/qmlprofilerclientmanager.cpp b/src/plugins/qmlprofiler/qmlprofilerclientmanager.cpp index 887ba0f3b74..00110b060f8 100644 --- a/src/plugins/qmlprofiler/qmlprofilerclientmanager.cpp +++ b/src/plugins/qmlprofiler/qmlprofilerclientmanager.cpp @@ -58,6 +58,7 @@ public: QTimer connectionTimer; int connectionAttempts; + QString localSocket; QString tcpHost; quint64 tcpPort; QString sysroot; @@ -107,6 +108,13 @@ void QmlProfilerClientManager::setTcpConnection(QString host, quint64 port) disconnectClient(); } +void QmlProfilerClientManager::setLocalSocket(QString file) +{ + d->localSocket = file; + d->tcpPort = 0; + connectLocalClient(file); +} + void QmlProfilerClientManager::clearBufferedData() { if (d->qmlclientplugin) @@ -118,7 +126,7 @@ void QmlProfilerClientManager::discardPendingData() clearBufferedData(); } -void QmlProfilerClientManager::connectClient(quint16 port) +void QmlProfilerClientManager::connectTcpClient(quint16 port) { if (d->connection) { if (port == d->tcpPort) { @@ -129,22 +137,28 @@ void QmlProfilerClientManager::connectClient(quint16 port) } } - d->connection = new QmlDebugConnection; - enableServices(); - connect(d->connection, &QmlDebugConnection::connected, - this, &QmlProfilerClientManager::qmlDebugConnectionOpened); - connect(d->connection, &QmlDebugConnection::disconnected, - this, &QmlProfilerClientManager::qmlDebugConnectionClosed); - connect(d->connection, &QmlDebugConnection::socketError, - this, &QmlProfilerClientManager::qmlDebugConnectionError); - connect(d->connection, &QmlDebugConnection::socketStateChanged, - this, &QmlProfilerClientManager::qmlDebugConnectionStateChanged); + createConnection(); d->connectionTimer.start(); d->tcpPort = port; } -void QmlProfilerClientManager::enableServices() +void QmlProfilerClientManager::connectLocalClient(const QString &file) { + if (d->connection) { + if (file == d->localSocket) + return; + else + delete d->connection; + } + + createConnection(); + d->localSocket = file; + d->connection->startLocalServer(file); +} + +void QmlProfilerClientManager::createConnection() +{ + d->connection = new QmlDebugConnection; QTC_ASSERT(d->profilerState, return); disconnectClientSignals(); @@ -155,6 +169,14 @@ void QmlProfilerClientManager::enableServices() d->profilerState->requestedFeatures()); d->qmlclientplugin->setFlushInterval(d->flushInterval); connectClientSignals(); + connect(d->connection, &QmlDebugConnection::connected, + this, &QmlProfilerClientManager::qmlDebugConnectionOpened); + connect(d->connection, &QmlDebugConnection::disconnected, + this, &QmlProfilerClientManager::qmlDebugConnectionClosed); + connect(d->connection, &QmlDebugConnection::socketError, + this, &QmlProfilerClientManager::qmlDebugConnectionError); + connect(d->connection, &QmlDebugConnection::socketStateChanged, + this, &QmlProfilerClientManager::qmlDebugConnectionStateChanged); } void QmlProfilerClientManager::connectClientSignals() diff --git a/src/plugins/qmlprofiler/qmlprofilerclientmanager.h b/src/plugins/qmlprofiler/qmlprofilerclientmanager.h index 9eae3e0cad5..3167f98579d 100644 --- a/src/plugins/qmlprofiler/qmlprofilerclientmanager.h +++ b/src/plugins/qmlprofiler/qmlprofilerclientmanager.h @@ -52,6 +52,7 @@ public: void registerProfilerStateManager(QmlProfilerStateManager *profilerState); void setTcpConnection(QString host, quint64 port); + void setLocalSocket(QString file); void clearBufferedData(); void discardPendingData(); @@ -65,7 +66,8 @@ signals: void connectionClosed(); public slots: - void connectClient(quint16 port); + void connectTcpClient(quint16 port); + void connectLocalClient(const QString &file); void disconnectClient(); private slots: @@ -89,7 +91,7 @@ private: void connectToClient(); - void enableServices(); + void createConnection(); void connectClientSignals(); void disconnectClientSignals(); diff --git a/src/plugins/qmlprofiler/qmlprofilerruncontrol.cpp b/src/plugins/qmlprofiler/qmlprofilerruncontrol.cpp index c6dd5523219..e34687114d7 100644 --- a/src/plugins/qmlprofiler/qmlprofilerruncontrol.cpp +++ b/src/plugins/qmlprofiler/qmlprofilerruncontrol.cpp @@ -96,6 +96,8 @@ QmlProfilerRunControl::QmlProfilerRunControl(const AnalyzerStartParameters &sp, this, &QmlProfilerRunControl::processIsRunning); connect(&d->m_outputParser, &QmlDebug::QmlOutputParser::noOutputMessage, this, [this](){processIsRunning(0);}); + connect(&d->m_outputParser, &QmlDebug::QmlOutputParser::connectingToSocketMessage, + this, [this](){processIsRunning(0);}); connect(&d->m_outputParser, &QmlDebug::QmlOutputParser::errorMessage, this, &QmlProfilerRunControl::wrongSetupMessageBox); } @@ -113,7 +115,7 @@ bool QmlProfilerRunControl::startEngine() if (startParameters().analyzerPort != 0) emit processRunning(startParameters().analyzerPort); - else + else if (startParameters().analyzerSocket.isEmpty()) d->m_noDebugOutputTimer.start(); d->m_profilerState->setCurrentState(QmlProfilerStateManager::AppRunning); diff --git a/src/plugins/qmlprofiler/qmlprofilerruncontrolfactory.cpp b/src/plugins/qmlprofiler/qmlprofilerruncontrolfactory.cpp index a0bf9a6199f..de4d0205cac 100644 --- a/src/plugins/qmlprofiler/qmlprofilerruncontrolfactory.cpp +++ b/src/plugins/qmlprofiler/qmlprofilerruncontrolfactory.cpp @@ -44,6 +44,8 @@ #include #include #include +#include +#include #include @@ -79,7 +81,19 @@ static AnalyzerStartParameters createQmlProfilerStartParameters(RunConfiguration sp.debuggee = rc->executable(); sp.debuggeeArgs = rc->commandLineArguments(); sp.displayName = rc->displayName(); - sp.analyzerPort = LocalQmlProfilerRunner::findFreePort(sp.analyzerHost); + + const QtSupport::BaseQtVersion *version = + QtSupport::QtKitInformation::qtVersion(runConfiguration->target()->kit()); + if (version) { + QtSupport::QtVersionNumber versionNumber = version->qtVersion(); + if (versionNumber.majorVersion >= 5 && versionNumber.minorVersion >= 6) + sp.analyzerSocket = LocalQmlProfilerRunner::findFreeSocket(); + else + sp.analyzerPort = LocalQmlProfilerRunner::findFreePort(sp.analyzerHost); + } else { + qWarning() << "Running QML profiler on Kit without Qt version??"; + sp.analyzerPort = LocalQmlProfilerRunner::findFreePort(sp.analyzerHost); + } return sp; } diff --git a/src/plugins/qmlprofiler/qmlprofilertool.cpp b/src/plugins/qmlprofiler/qmlprofilertool.cpp index d262bb3327b..c80795ebf63 100644 --- a/src/plugins/qmlprofiler/qmlprofilertool.cpp +++ b/src/plugins/qmlprofiler/qmlprofilertool.cpp @@ -214,10 +214,10 @@ AnalyzerRunControl *QmlProfilerTool::createRunControl(const AnalyzerStartParamet engine->registerProfilerStateManager(d->m_profilerState); - bool isTcpConnection = true; - // FIXME: Check that there's something sensible in sp.connParams - if (isTcpConnection) + if (!sp.analyzerSocket.isEmpty()) + d->m_profilerConnections->setLocalSocket(sp.analyzerSocket); + else d->m_profilerConnections->setTcpConnection(sp.analyzerHost, sp.analyzerPort); // @@ -232,8 +232,9 @@ AnalyzerRunControl *QmlProfilerTool::createRunControl(const AnalyzerStartParamet populateFileFinder(projectDirectory, sp.sysroot); - connect(engine, &QmlProfilerRunControl::processRunning, - d->m_profilerConnections, &QmlProfilerClientManager::connectClient); + if (sp.analyzerSocket.isEmpty()) + connect(engine, &QmlProfilerRunControl::processRunning, + d->m_profilerConnections, &QmlProfilerClientManager::connectTcpClient); connect(d->m_profilerConnections, &QmlProfilerClientManager::connectionFailed, engine, &QmlProfilerRunControl::cancelProcess);