From 8b10d977673f67af7df2ea0550a5532f64b8b360 Mon Sep 17 00:00:00 2001 From: Aurindam Jana Date: Tue, 7 May 2013 11:05:22 +0200 Subject: [PATCH] Qnx: Add support for QML Profiler MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: Ib87a39177120458155bbb657ff8c9b09e1a6ccb5 Reviewed-by: Tobias Nätterlund Reviewed-by: Aurindam Jana --- src/plugins/analyzerbase/ianalyzerengine.h | 1 + src/plugins/qmlprofiler/qmlprofilerengine.cpp | 9 +- src/plugins/qmlprofiler/qmlprofilerengine.h | 2 +- src/plugins/qnx/qnx.pro | 4 + src/plugins/qnx/qnx.qbs | 4 + src/plugins/qnx/qnxabstractrunsupport.cpp | 142 ++++++++++++++++++ src/plugins/qnx/qnxabstractrunsupport.h | 102 +++++++++++++ src/plugins/qnx/qnxanalyzesupport.cpp | 134 +++++++++++++++++ src/plugins/qnx/qnxanalyzesupport.h | 74 +++++++++ src/plugins/qnx/qnxdebugsupport.cpp | 81 +++------- src/plugins/qnx/qnxdebugsupport.h | 27 +--- src/plugins/qnx/qnxruncontrolfactory.cpp | 76 ++++++++-- 12 files changed, 560 insertions(+), 96 deletions(-) create mode 100644 src/plugins/qnx/qnxabstractrunsupport.cpp create mode 100644 src/plugins/qnx/qnxabstractrunsupport.h create mode 100644 src/plugins/qnx/qnxanalyzesupport.cpp create mode 100644 src/plugins/qnx/qnxanalyzesupport.h diff --git a/src/plugins/analyzerbase/ianalyzerengine.h b/src/plugins/analyzerbase/ianalyzerengine.h index 233564120a7..deea4638ce9 100644 --- a/src/plugins/analyzerbase/ianalyzerengine.h +++ b/src/plugins/analyzerbase/ianalyzerengine.h @@ -84,6 +84,7 @@ public: StartMode mode() const { return m_sp.startMode; } virtual void notifyRemoteSetupDone(quint16) {} + virtual void notifyRemoteFinished(bool) {} public slots: virtual void logApplicationMessage(const QString &, Utils::OutputFormat) {} diff --git a/src/plugins/qmlprofiler/qmlprofilerengine.cpp b/src/plugins/qmlprofiler/qmlprofilerengine.cpp index 6b0185685f2..02398eff938 100644 --- a/src/plugins/qmlprofiler/qmlprofilerengine.cpp +++ b/src/plugins/qmlprofiler/qmlprofilerengine.cpp @@ -189,7 +189,7 @@ bool QmlProfilerEngine::start() } if (d->m_runner) { - connect(d->m_runner, SIGNAL(stopped()), this, SLOT(processEnded())); + connect(d->m_runner, SIGNAL(stopped()), this, SLOT(notifyRemoteFinished())); connect(d->m_runner, SIGNAL(appendMessage(QString,Utils::OutputFormat)), this, SLOT(logApplicationMessage(QString,Utils::OutputFormat))); d->m_runner->start(); @@ -230,13 +230,16 @@ void QmlProfilerEngine::stop() } } -void QmlProfilerEngine::processEnded() +void QmlProfilerEngine::notifyRemoteFinished(bool success) { QTC_ASSERT(d->m_profilerState, return); switch (d->m_profilerState->currentState()) { case QmlProfilerStateManager::AppRunning : { - d->m_profilerState->setCurrentState(QmlProfilerStateManager::AppDying); + if (success) + d->m_profilerState->setCurrentState(QmlProfilerStateManager::AppDying); + else + d->m_profilerState->setCurrentState(QmlProfilerStateManager::AppKilled); AnalyzerManager::stopTool(); emit finished(); diff --git a/src/plugins/qmlprofiler/qmlprofilerengine.h b/src/plugins/qmlprofiler/qmlprofilerengine.h index fe8cc473137..2a7d24998f4 100644 --- a/src/plugins/qmlprofiler/qmlprofilerengine.h +++ b/src/plugins/qmlprofiler/qmlprofilerengine.h @@ -62,7 +62,7 @@ public slots: void stop(); private slots: - void processEnded(); + void notifyRemoteFinished(bool success = true); void cancelProcess(); void logApplicationMessage(const QString &msg, Utils::OutputFormat format); diff --git a/src/plugins/qnx/qnx.pro b/src/plugins/qnx/qnx.pro index 8f71ef4a232..a50ed1d8b53 100644 --- a/src/plugins/qnx/qnx.pro +++ b/src/plugins/qnx/qnx.pro @@ -33,6 +33,8 @@ SOURCES += qnxplugin.cpp \ qnxdeviceconfigurationwizardpages.cpp \ qnxrunconfiguration.cpp \ qnxruncontrolfactory.cpp \ + qnxabstractrunsupport.cpp \ + qnxanalyzesupport.cpp \ qnxdebugsupport.cpp \ qnxdeploystepfactory.cpp \ qnxdeployconfigurationfactory.cpp \ @@ -123,6 +125,8 @@ HEADERS += qnxplugin.h\ qnxdeviceconfigurationwizardpages.h \ qnxrunconfiguration.h \ qnxruncontrolfactory.h \ + qnxabstractrunsupport.h \ + qnxanalyzesupport.h \ qnxdebugsupport.h \ qnxdeploystepfactory.h \ qnxdeployconfigurationfactory.h \ diff --git a/src/plugins/qnx/qnx.qbs b/src/plugins/qnx/qnx.qbs index 530f180912c..83d168aab32 100644 --- a/src/plugins/qnx/qnx.qbs +++ b/src/plugins/qnx/qnx.qbs @@ -188,6 +188,10 @@ QtcPlugin { "qnxbaseqtconfigwidget.h", "qnxbaseqtconfigwidget.ui", "qnxconstants.h", + "qnxabstractrunsupport.cpp", + "qnxabstractrunsupport.h", + "qnxanalyzesupport.cpp", + "qnxanalyzesupport.h", "qnxdebugsupport.cpp", "qnxdebugsupport.h", "qnxdeployconfiguration.cpp", diff --git a/src/plugins/qnx/qnxabstractrunsupport.cpp b/src/plugins/qnx/qnxabstractrunsupport.cpp new file mode 100644 index 00000000000..cb97aa36f9a --- /dev/null +++ b/src/plugins/qnx/qnxabstractrunsupport.cpp @@ -0,0 +1,142 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +#include "qnxabstractrunsupport.h" +#include "qnxrunconfiguration.h" + +#include +#include +#include +#include +#include +#include + +using namespace ProjectExplorer; +using namespace RemoteLinux; + +using namespace Qnx; +using namespace Qnx::Internal; + +QnxAbstractRunSupport::QnxAbstractRunSupport(QnxRunConfiguration *runConfig, QObject *parent) + : QObject(parent) + , m_remoteExecutable(runConfig->remoteExecutableFilePath()) + , m_commandPrefix(runConfig->commandPrefix()) + , m_device(DeviceKitInformation::device(runConfig->target()->kit())) + , m_state(Inactive) +{ + m_runner = new DeviceApplicationRunner(this); + m_portsGatherer = new DeviceUsedPortsGatherer(this); + + connect(m_portsGatherer, SIGNAL(error(QString)), SLOT(handleError(QString))); + connect(m_portsGatherer, SIGNAL(portListReady()), SLOT(handlePortListReady())); +} + +void QnxAbstractRunSupport::handleAdapterSetupRequested() +{ + QTC_ASSERT(m_state == Inactive, return); + + m_state = GatheringPorts; + m_portsGatherer->start(m_device); +} + +void QnxAbstractRunSupport::handlePortListReady() +{ + QTC_ASSERT(m_state == GatheringPorts, return); + m_portList = m_device->freePorts(); + startExecution(); +} + +void QnxAbstractRunSupport::handleRemoteProcessStarted() +{ + m_state = Running; +} + +void QnxAbstractRunSupport::handleRemoteProcessFinished(bool) +{ +} + +void QnxAbstractRunSupport::setFinished() +{ + if (m_state != GatheringPorts && m_state != Inactive) + m_runner->stop(m_device->processSupport()->killProcessByNameCommandLine(executable()).toUtf8()); + + m_state = Inactive; +} + +QnxAbstractRunSupport::State QnxAbstractRunSupport::state() const +{ + return m_state; +} + +void QnxAbstractRunSupport::setState(QnxAbstractRunSupport::State state) +{ + m_state = state; +} + +DeviceApplicationRunner *QnxAbstractRunSupport::appRunner() const +{ + return m_runner; +} + +QString QnxAbstractRunSupport::commandPrefix() const +{ + return m_commandPrefix; +} + +const IDevice::ConstPtr QnxAbstractRunSupport::device() const +{ + return m_device; +} + +void QnxAbstractRunSupport::handleProgressReport(const QString &) +{ +} + +void QnxAbstractRunSupport::handleRemoteOutput(const QByteArray &) +{ +} + +void QnxAbstractRunSupport::handleError(const QString &) +{ +} + +bool QnxAbstractRunSupport::setPort(int &port) +{ + port = m_portsGatherer->getNextFreePort(&m_portList); + if (port == -1) { + handleError(tr("Not enough free ports on device for debugging.")); + return false; + } + return true; +} + +QString QnxAbstractRunSupport::executable() const +{ + return m_remoteExecutable; +} diff --git a/src/plugins/qnx/qnxabstractrunsupport.h b/src/plugins/qnx/qnxabstractrunsupport.h new file mode 100644 index 00000000000..1e37059774b --- /dev/null +++ b/src/plugins/qnx/qnxabstractrunsupport.h @@ -0,0 +1,102 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +#ifndef QNXABSTRACTRUNSUPPORT_H +#define QNXABSTRACTRUNSUPPORT_H + +#include +#include + +#include +#include + +namespace ProjectExplorer { +class DeviceApplicationRunner; +class DeviceUsedPortsGatherer; +} + +namespace Qnx { +namespace Internal { + +class QnxRunConfiguration; + +class QnxAbstractRunSupport : public QObject +{ + Q_OBJECT +protected: + enum State { + Inactive, + GatheringPorts, + StartingRemoteProcess, + Running + }; +public: + QnxAbstractRunSupport(QnxRunConfiguration *runConfig, QObject *parent = 0); + +protected: + bool setPort(int &port); + virtual void startExecution() = 0; + + virtual QString executable() const; + + void setFinished(); + + State state() const; + void setState(State state); + + ProjectExplorer::DeviceApplicationRunner *appRunner() const; + QString commandPrefix() const; + const ProjectExplorer::IDevice::ConstPtr device() const; + +protected slots: + virtual void handleAdapterSetupRequested(); + + virtual void handleRemoteProcessStarted(); + virtual void handleRemoteProcessFinished(bool); + virtual void handleProgressReport(const QString &progressOutput); + virtual void handleRemoteOutput(const QByteArray &output); + virtual void handleError(const QString &); + +private slots: + void handlePortListReady(); + +private: + ProjectExplorer::DeviceUsedPortsGatherer * m_portsGatherer; + Utils::PortList m_portList; + const QString m_remoteExecutable; + const QString m_commandPrefix; + ProjectExplorer::IDevice::ConstPtr m_device; + ProjectExplorer::DeviceApplicationRunner *m_runner; + State m_state; +}; + +} // namespace Internal +} // namespace Qnx + +#endif // QNXABSTRACTRUNSUPPORT_H diff --git a/src/plugins/qnx/qnxanalyzesupport.cpp b/src/plugins/qnx/qnxanalyzesupport.cpp new file mode 100644 index 00000000000..ac7cea766c9 --- /dev/null +++ b/src/plugins/qnx/qnxanalyzesupport.cpp @@ -0,0 +1,134 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +#include "qnxanalyzesupport.h" + +#include +#include +#include + +#include + +using namespace ProjectExplorer; + +using namespace Qnx; +using namespace Qnx::Internal; + +QnxAnalyzeSupport::QnxAnalyzeSupport(QnxRunConfiguration *runConfig, + Analyzer::IAnalyzerEngine *engine) + : QnxAbstractRunSupport(runConfig, engine) + , m_engine(engine) + , m_qmlPort(-1) +{ + const DeviceApplicationRunner *runner = appRunner(); + connect(runner, SIGNAL(reportError(QString)), SLOT(handleError(QString))); + connect(runner, SIGNAL(remoteProcessStarted()), SLOT(handleRemoteProcessStarted())); + connect(runner, SIGNAL(finished(bool)), SLOT(handleRemoteProcessFinished(bool))); + connect(runner, SIGNAL(reportProgress(QString)), SLOT(handleProgressReport(QString))); + connect(runner, SIGNAL(remoteStdout(QByteArray)), SLOT(handleRemoteOutput(QByteArray))); + connect(runner, SIGNAL(remoteStderr(QByteArray)), SLOT(handleRemoteOutput(QByteArray))); + + connect(m_engine, SIGNAL(starting(const Analyzer::IAnalyzerEngine*)), + SLOT(handleAdapterSetupRequested())); +} + +void QnxAnalyzeSupport::handleAdapterSetupRequested() +{ + QTC_ASSERT(state() == Inactive, return); + + showMessage(tr("Preparing remote side...\n"), Utils::NormalMessageFormat); + QnxAbstractRunSupport::handleAdapterSetupRequested(); +} + +void QnxAnalyzeSupport::startExecution() +{ + if (state() == Inactive) + return; + + if (!setPort(m_qmlPort) && m_qmlPort == -1) + return; + + setState(StartingRemoteProcess); + + const QString args = m_engine->startParameters().debuggeeArgs + + QString::fromLatin1(" -qmljsdebugger=port:%1,block").arg(m_qmlPort); + const QString command = QString::fromLatin1("%1 %2 %3").arg(commandPrefix(), executable(), args); + appRunner()->start(device(), command.toUtf8()); +} + +void QnxAnalyzeSupport::handleRemoteProcessStarted() +{ + QnxAbstractRunSupport::handleRemoteProcessStarted(); + if (m_engine) + m_engine->notifyRemoteSetupDone(m_qmlPort); +} + +void QnxAnalyzeSupport::handleRemoteProcessFinished(bool success) +{ + if (m_engine || state() == Inactive) + return; + + if (!success) + showMessage(tr("The %1 process closed unexpectedly.").arg(executable()), + Utils::NormalMessageFormat); + m_engine->notifyRemoteFinished(success); +} + +void QnxAnalyzeSupport::handleProfilingFinished() +{ + setFinished(); +} + +void QnxAnalyzeSupport::handleProgressReport(const QString &progressOutput) +{ + showMessage(progressOutput + QLatin1Char('\n'), Utils::NormalMessageFormat); +} + +void QnxAnalyzeSupport::handleRemoteOutput(const QByteArray &output) +{ + QTC_ASSERT(state() == Inactive || state() == Running, return); + + showMessage(QString::fromUtf8(output), Utils::StdOutFormat); +} + +void QnxAnalyzeSupport::handleError(const QString &error) +{ + if (state() == Running) { + showMessage(error, Utils::ErrorMessageFormat); + } else if (state() != Inactive) { + showMessage(tr("Initial setup failed: %1").arg(error), Utils::NormalMessageFormat); + setFinished(); + } +} + +void QnxAnalyzeSupport::showMessage(const QString &msg, Utils::OutputFormat format) +{ + if (state() != Inactive && m_engine) + m_engine->logApplicationMessage(msg, format); +} diff --git a/src/plugins/qnx/qnxanalyzesupport.h b/src/plugins/qnx/qnxanalyzesupport.h new file mode 100644 index 00000000000..66fa580abd8 --- /dev/null +++ b/src/plugins/qnx/qnxanalyzesupport.h @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +#ifndef QNXANALYZESUPPORT_H +#define QNXANALYZESUPPORT_H + +#include "qnxabstractrunsupport.h" + +#include +#include + +namespace Analyzer { class IAnalyzerEngine; } + +namespace Qnx { +namespace Internal { + +class QnxRunConfiguration; + +class QnxAnalyzeSupport : public QnxAbstractRunSupport +{ + Q_OBJECT +public: + QnxAnalyzeSupport(QnxRunConfiguration *runConfig, Analyzer::IAnalyzerEngine *engine); + +public slots: + void handleProfilingFinished(); + +private slots: + void handleAdapterSetupRequested(); + + void handleRemoteProcessStarted(); + void handleRemoteProcessFinished(bool success); + void handleProgressReport(const QString &progressOutput); + void handleRemoteOutput(const QByteArray &output); + void handleError(const QString &error); + +private: + void startExecution(); + void showMessage(const QString &, Utils::OutputFormat); + + Analyzer::IAnalyzerEngine *m_engine; + int m_qmlPort; +}; + +} // namespace Internal +} // namespace Qnx + +#endif // QNXANALYZESUPPORT_H diff --git a/src/plugins/qnx/qnxdebugsupport.cpp b/src/plugins/qnx/qnxdebugsupport.cpp index fdc7b447c0a..7b76080fc73 100644 --- a/src/plugins/qnx/qnxdebugsupport.cpp +++ b/src/plugins/qnx/qnxdebugsupport.cpp @@ -40,7 +40,6 @@ #include #include #include -#include #include using namespace ProjectExplorer; @@ -50,66 +49,44 @@ using namespace Qnx; using namespace Qnx::Internal; QnxDebugSupport::QnxDebugSupport(QnxRunConfiguration *runConfig, Debugger::DebuggerEngine *engine) - : QObject(engine) - , m_remoteExecutable(runConfig->remoteExecutableFilePath()) - , m_commandPrefix(runConfig->commandPrefix()) - , m_device(DeviceKitInformation::device(runConfig->target()->kit())) + : QnxAbstractRunSupport(runConfig, engine) , m_engine(engine) , m_pdebugPort(-1) , m_qmlPort(-1) , m_useCppDebugger(runConfig->extraAspect()->useCppDebugger()) , m_useQmlDebugger(runConfig->extraAspect()->useQmlDebugger()) - , m_state(Inactive) { - m_runner = new DeviceApplicationRunner(this); - m_portsGatherer = new DeviceUsedPortsGatherer(this); - - connect(m_portsGatherer, SIGNAL(error(QString)), SLOT(handleError(QString))); - connect(m_portsGatherer, SIGNAL(portListReady()), SLOT(handlePortListReady())); - - connect(m_runner, SIGNAL(reportError(QString)), SLOT(handleError(QString))); - connect(m_runner, SIGNAL(remoteProcessStarted()), this, SLOT(handleRemoteProcessStarted())); - connect(m_runner, SIGNAL(finished(bool)), SLOT(handleRemoteProcessFinished(bool))); - connect(m_runner, SIGNAL(reportProgress(QString)), this, SLOT(handleProgressReport(QString))); - connect(m_runner, SIGNAL(remoteStdout(QByteArray)), this, SLOT(handleRemoteOutput(QByteArray))); - connect(m_runner, SIGNAL(remoteStderr(QByteArray)), this, SLOT(handleRemoteOutput(QByteArray))); + const DeviceApplicationRunner *runner = appRunner(); + connect(runner, SIGNAL(reportError(QString)), SLOT(handleError(QString))); + connect(runner, SIGNAL(remoteProcessStarted()), SLOT(handleRemoteProcessStarted())); + connect(runner, SIGNAL(finished(bool)), SLOT(handleRemoteProcessFinished(bool))); + connect(runner, SIGNAL(reportProgress(QString)), SLOT(handleProgressReport(QString))); + connect(runner, SIGNAL(remoteStdout(QByteArray)), SLOT(handleRemoteOutput(QByteArray))); + connect(runner, SIGNAL(remoteStderr(QByteArray)), SLOT(handleRemoteOutput(QByteArray))); connect(m_engine, SIGNAL(requestRemoteSetup()), this, SLOT(handleAdapterSetupRequested())); } void QnxDebugSupport::handleAdapterSetupRequested() { - QTC_ASSERT(m_state == Inactive, return); + QTC_ASSERT(state() == Inactive, return); - m_state = GatheringPorts; if (m_engine) m_engine->showMessage(tr("Preparing remote side...\n"), Debugger::AppStuff); - m_portsGatherer->start(m_device); -} - -void QnxDebugSupport::handlePortListReady() -{ - QTC_ASSERT(m_state == GatheringPorts, return); - startExecution(); + QnxAbstractRunSupport::handleAdapterSetupRequested(); } void QnxDebugSupport::startExecution() { - if (m_state == Inactive) + if (state() == Inactive) return; - Utils::PortList portList = m_device->freePorts(); - if (m_useCppDebugger) - m_pdebugPort = m_portsGatherer->getNextFreePort(&portList); - if (m_useQmlDebugger) - m_qmlPort = m_portsGatherer->getNextFreePort(&portList); - - if ((m_useCppDebugger && m_pdebugPort == -1) || (m_useQmlDebugger && m_qmlPort == -1)) { - handleError(tr("Not enough free ports on device for debugging.")); + if (m_useCppDebugger && !setPort(m_pdebugPort)) + return; + if (m_useQmlDebugger && !setPort(m_qmlPort)) return; - } - m_state = StartingRemoteProcess; + setState(StartingRemoteProcess); if (m_useQmlDebugger) m_engine->startParameters().processArgs += QString::fromLocal8Bit(" -qmljsdebugger=port:%1,block").arg(m_qmlPort); @@ -117,27 +94,27 @@ void QnxDebugSupport::startExecution() QString remoteCommandLine; if (m_useCppDebugger) remoteCommandLine = QString::fromLatin1("%1 %2 %3") - .arg(m_commandPrefix, executable()).arg(m_pdebugPort); + .arg(commandPrefix(), executable()).arg(m_pdebugPort); else if (m_useQmlDebugger && !m_useCppDebugger) remoteCommandLine = QString::fromLatin1("%1 %2 %3") - .arg(m_commandPrefix, executable(), m_engine->startParameters().processArgs); + .arg(commandPrefix(), executable(), m_engine->startParameters().processArgs); - m_runner->start(m_device, remoteCommandLine.toUtf8()); + appRunner()->start(device(), remoteCommandLine.toUtf8()); } void QnxDebugSupport::handleRemoteProcessStarted() { - m_state = Debugging; + QnxAbstractRunSupport::handleRemoteProcessStarted(); if (m_engine) m_engine->notifyEngineRemoteSetupDone(m_pdebugPort, m_qmlPort); } void QnxDebugSupport::handleRemoteProcessFinished(bool success) { - if (m_engine || m_state == Inactive) + if (m_engine || state() == Inactive) return; - if (m_state == Debugging) { + if (state() == Running) { if (!success) m_engine->notifyInferiorIll(); @@ -152,17 +129,9 @@ void QnxDebugSupport::handleDebuggingFinished() setFinished(); } -void QnxDebugSupport::setFinished() -{ - if (m_state != GatheringPorts && m_state != Inactive) - m_runner->stop(m_device->processSupport()->killProcessByNameCommandLine(executable()).toUtf8()); - - m_state = Inactive; -} - QString QnxDebugSupport::executable() const { - return m_useCppDebugger? QLatin1String(Constants::QNX_DEBUG_EXECUTABLE) : m_remoteExecutable; + return m_useCppDebugger? QLatin1String(Constants::QNX_DEBUG_EXECUTABLE) : QnxAbstractRunSupport::executable(); } void QnxDebugSupport::handleProgressReport(const QString &progressOutput) @@ -173,7 +142,7 @@ void QnxDebugSupport::handleProgressReport(const QString &progressOutput) void QnxDebugSupport::handleRemoteOutput(const QByteArray &output) { - QTC_ASSERT(m_state == Inactive || m_state == Debugging, return); + QTC_ASSERT(state() == Inactive || state() == Running, return); if (m_engine) m_engine->showMessage(QString::fromUtf8(output), Debugger::AppOutput); @@ -181,12 +150,12 @@ void QnxDebugSupport::handleRemoteOutput(const QByteArray &output) void QnxDebugSupport::handleError(const QString &error) { - if (m_state == Debugging) { + if (state() == Running) { if (m_engine) { m_engine->showMessage(error, Debugger::AppError); m_engine->notifyInferiorIll(); } - } else if (m_state != Inactive) { + } else if (state() != Inactive) { setFinished(); if (m_engine) m_engine->notifyEngineRemoteSetupFailed(tr("Initial setup failed: %1").arg(error)); diff --git a/src/plugins/qnx/qnxdebugsupport.h b/src/plugins/qnx/qnxdebugsupport.h index 891b6acd87b..1bcb84016fe 100644 --- a/src/plugins/qnx/qnxdebugsupport.h +++ b/src/plugins/qnx/qnxdebugsupport.h @@ -32,23 +32,16 @@ #ifndef QNX_INTERNAL_QNXDEBUGSUPPORT_H #define QNX_INTERNAL_QNXDEBUGSUPPORT_H -#include - -#include -#include +#include "qnxabstractrunsupport.h" namespace Debugger { class DebuggerEngine; } -namespace ProjectExplorer { -class DeviceApplicationRunner; -class DeviceUsedPortsGatherer; -} namespace Qnx { namespace Internal { class QnxRunConfiguration; -class QnxDebugSupport : public QObject +class QnxDebugSupport : public QnxAbstractRunSupport { Q_OBJECT public: @@ -66,34 +59,18 @@ private slots: void handleProgressReport(const QString &progressOutput); void handleRemoteOutput(const QByteArray &output); void handleError(const QString &error); - void handlePortListReady(); private: void startExecution(); - void setFinished(); QString executable() const; - enum State { - Inactive, - GatheringPorts, - StartingRemoteProcess, - Debugging - }; - - const QString m_remoteExecutable; - const QString m_commandPrefix; - ProjectExplorer::IDevice::ConstPtr m_device; - ProjectExplorer::DeviceApplicationRunner *m_runner; - ProjectExplorer::DeviceUsedPortsGatherer * m_portsGatherer; Debugger::DebuggerEngine *m_engine; int m_pdebugPort; int m_qmlPort; bool m_useCppDebugger; bool m_useQmlDebugger; - - State m_state; }; } // namespace Internal diff --git a/src/plugins/qnx/qnxruncontrolfactory.cpp b/src/plugins/qnx/qnxruncontrolfactory.cpp index 29f58f2715d..d80363b39ff 100644 --- a/src/plugins/qnx/qnxruncontrolfactory.cpp +++ b/src/plugins/qnx/qnxruncontrolfactory.cpp @@ -33,6 +33,7 @@ #include "qnxconstants.h" #include "qnxrunconfiguration.h" #include "qnxdebugsupport.h" +#include "qnxanalyzesupport.h" #include "qnxqtversion.h" #include "qnxruncontrol.h" #include "qnxutils.h" @@ -44,6 +45,10 @@ #include #include #include +#include +#include +#include +#include #include #include #include @@ -51,6 +56,7 @@ #include #include +using namespace Analyzer; using namespace Debugger; using namespace ProjectExplorer; using namespace Qnx; @@ -107,6 +113,32 @@ DebuggerStartParameters createStartParameters(const QnxRunConfiguration *runConf return params; } +AnalyzerStartParameters createAnalyzerStartParameters(const QnxRunConfiguration *runConfig, RunMode mode) +{ + AnalyzerStartParameters params; + Target *target = runConfig->target(); + Kit *k = target->kit(); + + const IDevice::ConstPtr device = DeviceKitInformation::device(k); + if (device.isNull()) + return params; + + if (mode == QmlProfilerRunMode) + params.startMode = StartQmlRemote; + params.debuggee = runConfig->remoteExecutableFilePath(); + params.debuggeeArgs = runConfig->arguments(); + params.connParams = DeviceKitInformation::device(runConfig->target()->kit())->sshParameters(); + params.analyzerCmdPrefix = runConfig->commandPrefix(); + params.displayName = runConfig->displayName(); + params.sysroot = SysRootKitInformation::sysRoot(runConfig->target()->kit()).toString(); + params.analyzerHost = params.connParams.host; + params.analyzerPort = params.connParams.port; + + if (EnvironmentAspect *environment = runConfig->extraAspect()) + params.environment = environment->environment(); + + return params; +} QnxRunControlFactory::QnxRunControlFactory(QObject *parent) : IRunControlFactory(parent) @@ -115,7 +147,7 @@ QnxRunControlFactory::QnxRunControlFactory(QObject *parent) bool QnxRunControlFactory::canRun(RunConfiguration *runConfiguration, RunMode mode) const { - if (mode != NormalRunMode && mode != DebugRunMode) + if (mode != NormalRunMode && mode != DebugRunMode && mode != QmlProfilerRunMode) return false; if (!runConfiguration->isEnabled() @@ -125,7 +157,7 @@ bool QnxRunControlFactory::canRun(RunConfiguration *runConfiguration, RunMode mo const QnxRunConfiguration * const rc = qobject_cast(runConfiguration); - if (mode == DebugRunMode) { + if (mode == DebugRunMode || mode == QmlProfilerRunMode) { const QnxDeviceConfiguration::ConstPtr dev = DeviceKitInformation::device(runConfiguration->target()->kit()) .dynamicCast(); if (dev.isNull()) @@ -141,16 +173,38 @@ RunControl *QnxRunControlFactory::create(RunConfiguration *runConfig, RunMode mo QnxRunConfiguration *rc = qobject_cast(runConfig); Q_ASSERT(rc); - if (mode == NormalRunMode) + switch (mode) { + case NormalRunMode: return new QnxRunControl(rc); + case DebugRunMode: { + const DebuggerStartParameters params = createStartParameters(rc); + DebuggerRunControl * const runControl = DebuggerPlugin::createDebugger(params, rc, errorMessage); + if (!runControl) + return 0; - const DebuggerStartParameters params = createStartParameters(rc); - DebuggerRunControl * const runControl = DebuggerPlugin::createDebugger(params, rc, errorMessage); - if (!runControl) - return 0; + QnxDebugSupport *debugSupport = new QnxDebugSupport(rc, runControl->engine()); + connect(runControl, SIGNAL(finished()), debugSupport, SLOT(handleDebuggingFinished())); - QnxDebugSupport *debugSupport = new QnxDebugSupport(rc, runControl->engine()); - connect(runControl, SIGNAL(finished()), debugSupport, SLOT(handleDebuggingFinished())); - - return runControl; + return runControl; + } + case QmlProfilerRunMode: { + IAnalyzerTool *tool = AnalyzerManager::toolFromRunMode(mode); + if (!tool) { + if (errorMessage) + *errorMessage = tr("No analyzer tool selected."); + return 0; + } + const AnalyzerStartParameters params = createAnalyzerStartParameters(rc, mode); + AnalyzerRunControl * const runControl = new AnalyzerRunControl(tool, params, runConfig); + QnxAnalyzeSupport * const analyzeSupport = new QnxAnalyzeSupport(rc, runControl->engine()); + connect(runControl, SIGNAL(finished()), analyzeSupport, SLOT(handleProfilingFinished())); + return runControl; + } + case NoRunMode: + case CallgrindRunMode: + case MemcheckRunMode: + case DebugRunModeWithBreakOnMain: + QTC_ASSERT(false, return 0); + } + return 0; }