Commit ae4c35bd authored by Christian Kandeler's avatar Christian Kandeler

Maemo: Support QML-only debugging.

Reviewed-by: kh1
parent 82f4e73c
......@@ -38,6 +38,7 @@
#include "gdb/gdbengine.h"
#include "gdb/remotegdbserveradapter.h"
#include "gdb/remoteplaingdbadapter.h"
#include "qml/qmlengine.h"
#include "qml/qmlcppengine.h"
#ifdef Q_OS_WIN
......@@ -435,6 +436,9 @@ void DebuggerRunControl::createEngine(const DebuggerStartParameters &startParams
break;
case QmlEngineType:
d->m_engine = Internal::createQmlEngine(sp);
connect(qobject_cast<QmlEngine *>(d->m_engine),
SIGNAL(remoteStartupRequested()), this,
SIGNAL(engineRequestSetup()));
break;
case QmlCppEngineType:
d->m_engine = Internal::createQmlCppEngine(sp);
......@@ -463,10 +467,10 @@ void DebuggerRunControl::initGdbEngine(Internal::GdbEngine *engine)
Internal::AbstractGdbAdapter *adapter = engine->gdbAdapter();
if (RemotePlainGdbAdapter *rpga = qobject_cast<RemotePlainGdbAdapter *>(adapter)) {
connect(rpga, SIGNAL(requestSetup()), this,
SIGNAL(gdbAdapterRequestSetup()));
SIGNAL(engineRequestSetup()));
} else if (RemoteGdbServerAdapter *rgsa = qobject_cast<RemoteGdbServerAdapter *>(adapter)) {
connect(rgsa, SIGNAL(requestSetup()),
this, SIGNAL(gdbAdapterRequestSetup()));
this, SIGNAL(engineRequestSetup()));
}
}
......@@ -650,27 +654,35 @@ Internal::AbstractGdbAdapter *DebuggerRunControl::gdbAdapter() const
return engine->gdbAdapter();
}
void DebuggerRunControl::remoteGdbHandleSetupDone()
void DebuggerRunControl::handleRemoteSetupDone()
{
Internal::AbstractGdbAdapter *adapter = gdbAdapter();
QTC_ASSERT(adapter, return);
if (RemotePlainGdbAdapter *rpga = qobject_cast<RemotePlainGdbAdapter *>(adapter)) {
rpga->handleSetupDone();
} else if (RemoteGdbServerAdapter *rgsa = qobject_cast<RemoteGdbServerAdapter *>(adapter)) {
rgsa->handleSetupDone();
if (QmlEngine *qmlEngine = qobject_cast<QmlEngine *>(d->m_engine)) {
qmlEngine->handleRemoteSetupDone();
} else if (Internal::AbstractGdbAdapter *adapter = gdbAdapter()) {
if (RemotePlainGdbAdapter *rpga = qobject_cast<RemotePlainGdbAdapter *>(adapter)) {
rpga->handleSetupDone();
} else if (RemoteGdbServerAdapter *rgsa = qobject_cast<RemoteGdbServerAdapter *>(adapter)) {
rgsa->handleSetupDone();
} else {
QTC_ASSERT(false, /* */ );
}
} else {
QTC_ASSERT(false, /* */ );
}
}
void DebuggerRunControl::remoteGdbHandleSetupFailed(const QString &message)
void DebuggerRunControl::handleRemoteSetupFailed(const QString &message)
{
Internal::AbstractGdbAdapter *adapter = gdbAdapter();
QTC_ASSERT(adapter, return);
if (RemotePlainGdbAdapter *rpga = qobject_cast<RemotePlainGdbAdapter *>(adapter)) {
rpga->handleSetupFailed(message);
} else if (RemoteGdbServerAdapter *rgsa = qobject_cast<RemoteGdbServerAdapter *>(adapter)) {
rgsa->handleSetupFailed(message);
if (QmlEngine *qmlEngine = qobject_cast<QmlEngine *>(d->m_engine)) {
qmlEngine->handleRemoteSetupFailed(message);
} else if (Internal::AbstractGdbAdapter *adapter = gdbAdapter()) {
if (RemotePlainGdbAdapter *rpga = qobject_cast<RemotePlainGdbAdapter *>(adapter)) {
rpga->handleSetupFailed(message);
} else if (RemoteGdbServerAdapter *rgsa = qobject_cast<RemoteGdbServerAdapter *>(adapter)) {
rgsa->handleSetupFailed(message);
} else {
QTC_ASSERT(false, /* */ );
}
} else {
QTC_ASSERT(false, /* */ );
}
......
......@@ -116,8 +116,8 @@ public:
void showMessage(const QString &msg, int channel);
void remoteGdbHandleSetupDone();
void remoteGdbHandleSetupFailed(const QString &message);
void handleRemoteSetupDone();
void handleRemoteSetupFailed(const QString &message);
static bool checkDebugConfiguration(int toolChain,
QString *errorMessage,
......@@ -125,7 +125,7 @@ public:
QString *settingsPage = 0);
signals:
void gdbAdapterRequestSetup();
void engineRequestSetup();
public slots:
void emitAddToOutputWindow(const QString &line, bool onStdErr);
......
......@@ -168,19 +168,23 @@ void QmlEngine::setupInferior()
{
QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state());
connect(&d->m_applicationLauncher, SIGNAL(processExited(int)),
this, SLOT(disconnected()));
connect(&d->m_applicationLauncher, SIGNAL(appendMessage(QString,bool)),
runControl(), SLOT(emitAppendMessage(QString,bool)));
connect(&d->m_applicationLauncher, SIGNAL(appendOutput(QString, bool)),
runControl(), SLOT(emitAddToOutputWindow(QString, bool)));
connect(&d->m_applicationLauncher, SIGNAL(bringToForegroundRequested(qint64)),
runControl(), SLOT(bringApplicationToForeground(qint64)));
d->m_applicationLauncher.setEnvironment(startParameters().environment);
d->m_applicationLauncher.setWorkingDirectory(startParameters().workingDirectory);
notifyInferiorSetupOk();
if (startParameters().startMode == AttachToRemote) {
emit remoteStartupRequested();
} else {
connect(&d->m_applicationLauncher, SIGNAL(processExited(int)),
this, SLOT(disconnected()));
connect(&d->m_applicationLauncher, SIGNAL(appendMessage(QString,bool)),
runControl(), SLOT(emitAppendMessage(QString,bool)));
connect(&d->m_applicationLauncher, SIGNAL(appendOutput(QString, bool)),
runControl(), SLOT(emitAddToOutputWindow(QString, bool)));
connect(&d->m_applicationLauncher, SIGNAL(bringToForegroundRequested(qint64)),
runControl(), SLOT(bringApplicationToForeground(qint64)));
d->m_applicationLauncher.setEnvironment(startParameters().environment);
d->m_applicationLauncher.setWorkingDirectory(startParameters().workingDirectory);
notifyInferiorSetupOk();
}
}
void QmlEngine::connectionEstablished()
......@@ -227,6 +231,18 @@ void QmlEngine::runEngine()
plugin()->showMessage(tr("QML Debugger connecting..."), StatusBar);
}
void QmlEngine::handleRemoteSetupDone()
{
notifyInferiorSetupOk();
}
void QmlEngine::handleRemoteSetupFailed(const QString &message)
{
QMessageBox::critical(0,tr("Failed to start application"),
tr("Application startup failed: %1").arg(message));
notifyInferiorSetupFailed();
}
void QmlEngine::shutdownInferiorAsSlave()
{
resetLocation();
......
......@@ -48,6 +48,9 @@ public:
explicit QmlEngine(const DebuggerStartParameters &startParameters);
virtual ~QmlEngine();
void handleRemoteSetupDone();
void handleRemoteSetupFailed(const QString &message);
void setAttachToRunningExternalApp(bool value);
void shutdownInferiorAsSlave();
void shutdownEngineAsSlave();
......@@ -59,6 +62,9 @@ public slots:
void messageReceived(const QByteArray &message);
void disconnected();
signals:
void remoteStartupRequested();
private:
// DebuggerEngine implementation
bool isSynchronous() const { return false; }
......
......@@ -67,40 +67,41 @@ RunControl *MaemoDebugSupport::createDebugRunControl(MaemoRunConfiguration *runC
params.qmlServerAddress = runConfig->deviceConfig().server.host;
params.qmlServerPort = qmlServerPort(runConfig);
}
if (runConfig->useRemoteGdb()) {
params.startMode = StartRemoteGdb;
params.executable = runConfig->remoteExecutableFilePath();
params.debuggerCommand
= MaemoGlobal::remoteCommandPrefix(runConfig->remoteExecutableFilePath())
+ environment(runConfig) + QLatin1String(" /usr/bin/gdb");
params.connParams = devConf.server;
params.localMountDir = runConfig->localDirToMountForRemoteGdb();
params.remoteMountPoint = MaemoGlobal::remoteProjectSourcesMountPoint();
const QString execDirAbs
= QDir::fromNativeSeparators(QFileInfo(runConfig->localExecutableFilePath()).path());
const QString execDirRel
= QDir(params.localMountDir).relativeFilePath(execDirAbs);
params.remoteSourcesDir = QString(params.remoteMountPoint
+ QLatin1Char('/') + execDirRel).toUtf8();
if (runConfig->useCppDebugger()) {
params.processArgs = runConfig->arguments();
params.sysRoot = runConfig->sysRoot();
params.toolChainType = ToolChain::GCC_MAEMO;
params.dumperLibrary = runConfig->dumperLib();
params.remoteDumperLib = uploadDir(devConf).toUtf8() + '/'
+ QFileInfo(runConfig->dumperLib()).fileName().toUtf8();
if (runConfig->useRemoteGdb()) {
params.startMode = StartRemoteGdb;
params.executable = runConfig->remoteExecutableFilePath();
params.debuggerCommand
= MaemoGlobal::remoteCommandPrefix(runConfig->remoteExecutableFilePath())
+ environment(runConfig) + QLatin1String(" /usr/bin/gdb");
params.connParams = devConf.server;
params.localMountDir = runConfig->localDirToMountForRemoteGdb();
params.remoteMountPoint = MaemoGlobal::remoteProjectSourcesMountPoint();
const QString execDirAbs
= QDir::fromNativeSeparators(QFileInfo(runConfig->localExecutableFilePath()).path());
const QString execDirRel
= QDir(params.localMountDir).relativeFilePath(execDirAbs);
params.remoteSourcesDir = QString(params.remoteMountPoint
+ QLatin1Char('/') + execDirRel).toUtf8();
} else {
params.startMode = AttachToRemote;
params.executable = runConfig->localExecutableFilePath();
params.debuggerCommand = runConfig->gdbCmd();
params.remoteChannel = devConf.server.host + QLatin1Char(':')
+ QString::number(gdbServerPort(runConfig));
params.useServerStartScript = true;
params.remoteArchitecture = QLatin1String("arm");
}
} else {
params.startMode = AttachToRemote;
params.executable = runConfig->localExecutableFilePath();
params.debuggerCommand = runConfig->gdbCmd();
params.remoteChannel = devConf.server.host + QLatin1Char(':')
+ QString::number(gdbServerPort(runConfig));
params.useServerStartScript = true;
params.remoteArchitecture = QLatin1String("arm");
}
params.processArgs = runConfig->arguments();
params.sysRoot = runConfig->sysRoot();
params.toolChainType = ToolChain::GCC_MAEMO;
params.dumperLibrary = runConfig->dumperLib();
params.remoteDumperLib = uploadDir(devConf).toUtf8() + '/'
+ QFileInfo(runConfig->dumperLib()).fileName().toUtf8();
DebuggerRunControl * const debuggerRunControl
= DebuggerPlugin::createDebugger(params, runConfig);
new MaemoDebugSupport(runConfig, debuggerRunControl);
......@@ -111,9 +112,11 @@ MaemoDebugSupport::MaemoDebugSupport(MaemoRunConfiguration *runConfig,
DebuggerRunControl *runControl)
: QObject(runControl), m_runControl(runControl), m_runConfig(runConfig),
m_deviceConfig(m_runConfig->deviceConfig()),
m_runner(new MaemoSshRunner(this, m_runConfig, true))
m_runner(new MaemoSshRunner(this, m_runConfig, true)),
m_qmlOnlyDebugging(m_runConfig->useQmlDebugger() && !m_runConfig->useCppDebugger())
{
connect(m_runControl, SIGNAL(gdbAdapterRequestSetup()), this, SLOT(handleAdapterSetupRequested()));
connect(m_runControl, SIGNAL(adapterRequestSetup()), this,
SLOT(handleAdapterSetupRequested()));
connect(m_runControl, SIGNAL(finished()), this,
SLOT(handleDebuggingFinished()));
}
......@@ -154,7 +157,7 @@ void MaemoDebugSupport::startExecution()
return;
const QString &dumperLib = m_runConfig->dumperLib();
if (!dumperLib.isEmpty()
if (!m_qmlOnlyDebugging && !dumperLib.isEmpty()
&& m_runConfig->deployStep()->currentlyNeedsDeployment(m_deviceConfig.server.host,
MaemoDeployable(dumperLib, uploadDir(m_deviceConfig)))) {
m_uploader = m_runner->connection()->createSftpChannel();
......@@ -232,11 +235,16 @@ void MaemoDebugSupport::startDebugging()
connect(m_runner, SIGNAL(remoteProcessStarted()), this,
SLOT(handleRemoteProcessStarted()));
const QString &remoteExe = m_runConfig->remoteExecutableFilePath();
m_runner->startExecution(QString::fromLocal8Bit("%1 %2 gdbserver :%3 %4 %5")
.arg(MaemoGlobal::remoteCommandPrefix(remoteExe))
.arg(environment(m_runConfig)).arg(gdbServerPort(m_runConfig))
.arg(remoteExe).arg(m_runConfig->arguments()
.join(QLatin1String(" "))).toUtf8());
const QString cmdPrefix = MaemoGlobal::remoteCommandPrefix(remoteExe);
const QString env = environment(m_runConfig);
const QString args = m_runConfig->arguments().join(QLatin1String(" "));
const QString remoteCommandLine = m_qmlOnlyDebugging
? QString::fromLocal8Bit("%1 %2 %3 %4").arg(cmdPrefix).arg(env)
.arg(remoteExe).arg(args)
: QString::fromLocal8Bit("%1 %2 gdbserver :%3 %4 %5")
.arg(cmdPrefix).arg(env).arg(gdbServerPort(m_runConfig))
.arg(remoteExe).arg(args);
m_runner->startExecution(remoteCommandLine.toUtf8());
}
}
......@@ -278,8 +286,7 @@ void MaemoDebugSupport::stopSsh()
void MaemoDebugSupport::handleAdapterSetupFailed(const QString &error)
{
m_runControl->remoteGdbHandleSetupFailed(tr("Initial setup failed: %1").arg(error));
m_runControl->handleRemoteSetupFailed(tr("Initial setup failed: %1").arg(error));
m_stopped = true;
stopSsh();
}
......@@ -287,7 +294,7 @@ void MaemoDebugSupport::handleAdapterSetupFailed(const QString &error)
void MaemoDebugSupport::handleAdapterSetupDone()
{
m_adapterStarted = true;
m_runControl->remoteGdbHandleSetupDone();
m_runControl->handleRemoteSetupDone();
}
int MaemoDebugSupport::gdbServerPort(const MaemoRunConfiguration *rc)
......@@ -298,7 +305,8 @@ int MaemoDebugSupport::gdbServerPort(const MaemoRunConfiguration *rc)
int MaemoDebugSupport::qmlServerPort(const MaemoRunConfiguration *rc)
{
MaemoPortList portList = rc->freePorts();
portList.getNext();
if (rc->useCppDebugger())
portList.getNext();
return portList.getNext();
}
......@@ -319,7 +327,8 @@ QString MaemoDebugSupport::uploadDir(const MaemoDeviceConfig &devConf)
bool MaemoDebugSupport::useGdb() const
{
return m_runControl->engine()->startParameters().startMode == StartRemoteGdb;
return m_runControl->engine()->startParameters().startMode == StartRemoteGdb
&& !m_qmlOnlyDebugging;
}
} // namespace Internal
......
......@@ -92,10 +92,11 @@ private:
void startDebugging();
bool useGdb() const;
Debugger::DebuggerRunControl *m_runControl;
Debugger::DebuggerRunControl * const m_runControl;
MaemoRunConfiguration * const m_runConfig;
const MaemoDeviceConfig m_deviceConfig;
MaemoSshRunner * const m_runner;
const bool m_qmlOnlyDebugging;
QSharedPointer<Core::SftpChannel> m_uploader;
Core::SftpJobId m_uploadJob;
......
......@@ -88,6 +88,8 @@ MaemoRunConfiguration::MaemoRunConfiguration(Qt4Target *parent,
void MaemoRunConfiguration::init()
{
setDefaultDisplayName(defaultDisplayName());
setUseCppDebugger(true);
setUseQmlDebugger(false);
m_remoteMounts = new MaemoRemoteMountsModel(this);
connect(target(),
......
......@@ -115,6 +115,8 @@ public:
ProjectExplorer::Environment systemEnvironment() const;
void setSystemEnvironment(const ProjectExplorer::Environment &environment);
int portsUsedByDebuggers() const { return useCppDebugger() + useQmlDebugger(); }
signals:
void deviceConfigurationChanged(ProjectExplorer::Target *target);
void targetInformationChanged() const;
......
......@@ -51,7 +51,6 @@
#include <qt4projectmanager/qt4target.h>
#include <utils/detailswidget.h>
#include <QtGui/QCheckBox>
#include <QtGui/QComboBox>
#include <QtGui/QFileDialog>
#include <QtGui/QFormLayout>
......@@ -123,9 +122,22 @@ void MaemoRunConfigurationWidget::addGenericWidgets(QVBoxLayout *mainLayout)
m_argsLineEdit = new QLineEdit(m_runConfiguration->arguments().join(" "));
formLayout->addRow(tr("Arguments:"), m_argsLineEdit);
m_qmlCheckBox = new QCheckBox(tr("Also debug QML parts"));
m_qmlCheckBox->setChecked(m_runConfiguration->useQmlDebugger());
formLayout->addRow(new QLabel(tr("Debugging:")), m_qmlCheckBox);
QHBoxLayout * const debugButtonsLayout = new QHBoxLayout;
m_debugCppOnlyButton = new QRadioButton(tr("C++ only"));
m_debugQmlOnlyButton = new QRadioButton(tr("QML only"));
m_debugCppAndQmlButton = new QRadioButton(tr("C++ and QML"));
debugButtonsLayout->addWidget(m_debugCppOnlyButton);
debugButtonsLayout->addWidget(m_debugQmlOnlyButton);
debugButtonsLayout->addWidget(m_debugCppAndQmlButton);
formLayout->addRow(tr("Debugging type:"), debugButtonsLayout);
if (m_runConfiguration->useCppDebugger()) {
if (m_runConfiguration->useQmlDebugger())
m_debugCppAndQmlButton->setChecked(true);
else
m_debugCppOnlyButton->setChecked(true);
} else {
m_debugQmlOnlyButton->setChecked(true);
}
connect(addDevConfLabel, SIGNAL(linkActivated(QString)), this,
SLOT(showSettingsDialog(QString)));
......@@ -133,8 +145,12 @@ void MaemoRunConfigurationWidget::addGenericWidgets(QVBoxLayout *mainLayout)
SLOT(showSettingsDialog(QString)));
connect(m_argsLineEdit, SIGNAL(textEdited(QString)), this,
SLOT(argumentsEdited(QString)));
connect(m_qmlCheckBox, SIGNAL(toggled(bool)), this,
SLOT(handleQmlDebuggingChanged(bool)));
connect(m_debugCppOnlyButton, SIGNAL(toggled(bool)), this,
SLOT(handleDebuggingTypeChanged()));
connect(m_debugQmlOnlyButton, SIGNAL(toggled(bool)), this,
SLOT(handleDebuggingTypeChanged()));
connect(m_debugCppAndQmlButton, SIGNAL(toggled(bool)), this,
SLOT(handleDebuggingTypeChanged()));
connect(m_runConfiguration, SIGNAL(targetInformationChanged()), this,
SLOT(updateTargetInformation()));
connect(m_runConfiguration->deployStep()->deployables(),
......@@ -432,9 +448,12 @@ void MaemoRunConfigurationWidget::handleRemoteMountsChanged()
updateMountWarning();
}
void MaemoRunConfigurationWidget::handleQmlDebuggingChanged(bool debugQml)
void MaemoRunConfigurationWidget::handleDebuggingTypeChanged()
{
m_runConfiguration->setUseQmlDebugger(debugQml);
m_runConfiguration->setUseCppDebugger(m_debugCppOnlyButton->isChecked()
|| m_debugCppAndQmlButton->isChecked());
m_runConfiguration->setUseQmlDebugger(m_debugQmlOnlyButton->isChecked()
|| m_debugCppAndQmlButton->isChecked());
updateMountWarning();
}
......@@ -452,8 +471,8 @@ void MaemoRunConfigurationWidget::updateMountWarning()
"to run this configuration.", 0, availablePortCount)
.arg(mountDirCount);
} else if (mountDirCount > 0) {
const int portsLeftByDebuggers
= availablePortCount - 1 - m_runConfiguration->useQmlDebugger();
const int portsLeftByDebuggers = availablePortCount
- m_runConfiguration->portsUsedByDebuggers();
if (mountDirCount > portsLeftByDebuggers) {
mountWarning = tr("WARNING: You want to mount %1 directories, "
"but only %n ports on the device will be available "
......
......@@ -38,12 +38,12 @@
#include <QtGui/QWidget>
QT_BEGIN_NAMESPACE
class QCheckBox;
class QComboBox;
class QLabel;
class QLineEdit;
class QModelIndex;
class QPushButton;
class QRadioButton;
class QTableView;
class QToolButton;
class QVBoxLayout;
......@@ -88,7 +88,7 @@ private slots:
void systemEnvironmentChanged();
void userEnvironmentChangesChanged(const QList<ProjectExplorer::EnvironmentItem> &userChanges);
void handleRemoteMountsChanged();
void handleQmlDebuggingChanged(bool debugQml);
void handleDebuggingTypeChanged();
void handleDeploySpecsChanged();
void handleBuildConfigChanged();
void handleToolchainChanged();
......@@ -104,7 +104,9 @@ private:
QLabel *m_localExecutableLabel;
QLabel *m_remoteExecutableLabel;
QLabel *m_devConfLabel;
QCheckBox *m_qmlCheckBox;
QRadioButton *m_debugCppOnlyButton;
QRadioButton *m_debugQmlOnlyButton;
QRadioButton *m_debugCppAndQmlButton;
QLabel *m_mountWarningLabel;
QTableView *m_mountView;
QToolButton *m_removeMountButton;
......
......@@ -172,7 +172,7 @@ bool MaemoRunControlFactory::canRun(RunConfiguration *runConfiguration,
? maemoRunConfig->remoteMounts()->validMountSpecificationCount()
: 0;
if (mode == ProjectExplorer::Constants::DEBUGMODE)
return freePortCount > mountDirCount + runConfiguration->useQmlDebugger();
return freePortCount >= mountDirCount + maemoRunConfig->portsUsedByDebuggers();
if (mode == ProjectExplorer::Constants::RUNMODE)
return freePortCount >= mountDirCount;
return false;
......
......@@ -192,7 +192,7 @@ void MaemoSshRunner::handleUnmounted()
m_mounter->resetMountSpecifications();
MaemoPortList portList = m_devConfig.freePorts();
if (m_debugging) { // gdbserver and QML inspector need one port each.
if (!m_runConfig->useRemoteGdb())
if (m_runConfig->useCppDebugger() && !m_runConfig->useRemoteGdb())
portList.getNext();
if (m_runConfig->useQmlDebugger())
portList.getNext();
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment