Commit 08bc6c00 authored by ck's avatar ck

Maemo: Get rid of MaemoDebugRunControl.

Use Debugger::DebuggerRunControl directly instead of wrapping it
into another RunControl.

Reviewed-by: hjk
parent db99f828
......@@ -924,7 +924,8 @@ public slots:
QVariant configValue(const QString &name) const
{ return settings()->value(name); }
DebuggerRunControl *createDebugger(const DebuggerStartParameters &sp);
DebuggerRunControl *createDebugger(const DebuggerStartParameters &sp,
ProjectExplorer::RunConfiguration *rc = 0);
void startDebugger(ProjectExplorer::RunControl *runControl);
void displayDebugger(ProjectExplorer::RunControl *runControl);
......@@ -1921,9 +1922,10 @@ void DebuggerPluginPrivate::showToolTip(ITextEditor *editor, const QPoint &point
}
DebuggerRunControl *
DebuggerPluginPrivate::createDebugger(const DebuggerStartParameters &sp)
DebuggerPluginPrivate::createDebugger(const DebuggerStartParameters &sp,
ProjectExplorer::RunConfiguration *rc)
{
return m_debuggerRunControlFactory->create(sp);
return m_debuggerRunControlFactory->create(sp, rc);
}
void DebuggerPluginPrivate::displayDebugger(ProjectExplorer::RunControl *rc)
......@@ -2643,9 +2645,10 @@ QWidget *DebuggerPlugin::mainWindow() const
}
DebuggerRunControl *
DebuggerPlugin::createDebugger(const DebuggerStartParameters &sp)
DebuggerPlugin::createDebugger(const DebuggerStartParameters &sp,
ProjectExplorer::RunConfiguration *rc)
{
return instance()->d->createDebugger(sp);
return instance()->d->createDebugger(sp, rc);
}
void DebuggerPlugin::startDebugger(ProjectExplorer::RunControl *runControl)
......
......@@ -44,6 +44,7 @@ class Snapshot;
}
namespace ProjectExplorer {
class RunConfiguration;
class RunControl;
}
......@@ -82,7 +83,8 @@ public:
void readSettings();
void writeSettings() const;
static DebuggerRunControl *createDebugger(const DebuggerStartParameters &sp);
static DebuggerRunControl *createDebugger(const DebuggerStartParameters &sp,
ProjectExplorer::RunConfiguration *rc = 0);
static void startDebugger(ProjectExplorer::RunControl *runControl);
static void displayDebugger(ProjectExplorer::RunControl *runControl);
......
......@@ -179,7 +179,6 @@ static QByteArray parsePlainConsoleStream(const GdbResponse &response)
GdbEngine::GdbEngine(const DebuggerStartParameters &startParameters)
: DebuggerEngine(startParameters)
{
m_gdbAdapter = 0;
m_progress = 0;
m_commandTimer = new QTimer(this);
......@@ -189,6 +188,7 @@ GdbEngine::GdbEngine(const DebuggerStartParameters &startParameters)
// Needs no resetting in initializeVariables()
m_busy = false;
initializeVariables();
m_gdbAdapter = createAdapter();
connect(theDebuggerAction(AutoDerefPointers), SIGNAL(valueChanged(QVariant)),
this, SLOT(setAutoDerefPointers(QVariant)));
......@@ -1754,7 +1754,6 @@ void GdbEngine::setupEngine()
//qDebug() << "GDB START DEBUGGER";
QTC_ASSERT(state() == EngineSetupRequested, qDebug() << state());
QTC_ASSERT(m_debuggingHelperState == DebuggingHelperUninitialized, /**/);
QTC_ASSERT(m_gdbAdapter == 0, /**/);
m_progress = new QFutureInterface<void>();
m_progress->setProgressRange(0, 100);
......@@ -1763,7 +1762,6 @@ void GdbEngine::setupEngine()
fp->setKeepOnFinish(false);
m_progress->reportStarted();
m_gdbAdapter = createAdapter();
//qDebug() << "CREATED ADAPTER: " << m_gdbAdapter;
if (m_gdbAdapter->dumperHandling() != AbstractGdbAdapter::DumperNotAvailable) {
......
......@@ -83,13 +83,14 @@ enum DebuggingHelperState
};
class GdbEngine : public DebuggerEngine
class DEBUGGER_EXPORT GdbEngine : public DebuggerEngine
{
Q_OBJECT
public:
explicit GdbEngine(const DebuggerStartParameters &startParameters);
~GdbEngine();
AbstractGdbAdapter *gdbAdapter() const { return m_gdbAdapter; }
private:
friend class AbstractGdbAdapter;
......
......@@ -62,6 +62,8 @@ RemoteGdbServerAdapter::RemoteGdbServerAdapter(GdbEngine *engine, int toolChainT
this, SLOT(readUploadStandardOutput()));
connect(&m_uploadProc, SIGNAL(readyReadStandardError()),
this, SLOT(readUploadStandardError()));
connect(&m_uploadProc, SIGNAL(finished(int)), this,
SLOT(uploadProcFinished()));
}
AbstractGdbAdapter::DumperHandling RemoteGdbServerAdapter::dumperHandling() const
......@@ -86,22 +88,13 @@ void RemoteGdbServerAdapter::startAdapter()
{
QTC_ASSERT(state() == EngineSetupRequested, qDebug() << state());
showMessage(_("TRYING TO START ADAPTER"));
// FIXME: make asynchroneous
// Start the remote server
if (startParameters().serverStartScript.isEmpty()) {
showMessage(_("No server start script given. "
"Assuming server runs already."), StatusBar);
showMessage(_("No server start script given. "), StatusBar);
emit requestSetup();
} else {
m_uploadProc.start(_("/bin/sh ") + startParameters().serverStartScript);
m_uploadProc.waitForStarted();
}
if (!m_engine->startGdb(QStringList(), startParameters().debuggerCommand))
// FIXME: cleanup missing
return;
m_engine->handleAdapterStarted();
}
void RemoteGdbServerAdapter::uploadProcError(QProcess::ProcessError error)
......@@ -154,6 +147,15 @@ void RemoteGdbServerAdapter::readUploadStandardError()
showMessage(msg, AppError);
}
void RemoteGdbServerAdapter::uploadProcFinished()
{
if (m_uploadProc.exitStatus() == QProcess::NormalExit
&& m_uploadProc.exitCode() == 0)
handleSetupDone();
else
handleSetupFailed(m_uploadProc.errorString());
}
void RemoteGdbServerAdapter::setupInferior()
{
QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state());
......@@ -245,5 +247,20 @@ void RemoteGdbServerAdapter::shutdownAdapter()
m_engine->notifyAdapterShutdownOk();
}
void RemoteGdbServerAdapter::handleSetupDone()
{
QTC_ASSERT(state() == EngineSetupRequested, qDebug() << state());
if (m_engine->startGdb(QStringList(), startParameters().debuggerCommand))
m_engine->handleAdapterStarted();
}
void RemoteGdbServerAdapter::handleSetupFailed(const QString &reason)
{
QTC_ASSERT(state() == EngineSetupRequested, qDebug() << state());
m_engine->handleAdapterStartFailed(reason);
}
} // namespace Internal
} // namespace Debugger
......@@ -43,12 +43,14 @@ namespace Internal {
//
///////////////////////////////////////////////////////////////////////
class RemoteGdbServerAdapter : public AbstractGdbAdapter
class DEBUGGER_EXPORT RemoteGdbServerAdapter : public AbstractGdbAdapter
{
Q_OBJECT
public:
RemoteGdbServerAdapter(GdbEngine *engine, int toolChainType, QObject *parent = 0);
void handleSetupDone();
void handleSetupFailed(const QString &reason);
private:
DumperHandling dumperHandling() const;
......@@ -62,9 +64,14 @@ private:
AbstractGdbProcess *gdbProc() { return &m_gdbProc; }
signals:
void requestSetup();
private:
Q_SLOT void readUploadStandardOutput();
Q_SLOT void readUploadStandardError();
Q_SLOT void uploadProcError(QProcess::ProcessError error);
Q_SLOT void uploadProcFinished();
void handleSetTargetAsync(const GdbResponse &response);
void handleFileExecAndSymbols(const GdbResponse &response);
......
......@@ -48,13 +48,7 @@ void RemotePlainGdbAdapter::startAdapter()
QTC_ASSERT(state() == EngineSetupRequested, qDebug() << state());
showMessage(QLatin1String("TRYING TO START ADAPTER"));
if (!startParameters().workingDirectory.isEmpty())
m_gdbProc.setWorkingDirectory(startParameters().workingDirectory);
if (!startParameters().environment.isEmpty())
m_gdbProc.setEnvironment(startParameters().environment);
if (m_engine->startGdb(QStringList(), m_engine->startParameters().debuggerCommand))
m_engine->handleAdapterStarted();
emit requestSetup();
}
void RemotePlainGdbAdapter::interruptInferior()
......@@ -97,5 +91,25 @@ void RemotePlainGdbAdapter::shutdownAdapter()
m_engine->notifyAdapterShutdownOk();
}
void RemotePlainGdbAdapter::handleSetupDone()
{
QTC_ASSERT(state() == EngineSetupRequested, qDebug() << state());
if (!startParameters().workingDirectory.isEmpty())
m_gdbProc.setWorkingDirectory(startParameters().workingDirectory);
if (!startParameters().environment.isEmpty())
m_gdbProc.setEnvironment(startParameters().environment);
if (m_engine->startGdb(QStringList(), m_engine->startParameters().debuggerCommand))
m_engine->handleAdapterStarted();
}
void RemotePlainGdbAdapter::handleSetupFailed(const QString &reason)
{
QTC_ASSERT(state() == EngineSetupRequested, qDebug() << state());
m_engine->handleAdapterStartFailed(reason);
}
} // namespace Internal
} // namespace Debugger
......@@ -36,13 +36,18 @@
namespace Debugger {
namespace Internal {
class RemotePlainGdbAdapter : public AbstractPlainGdbAdapter
class DEBUGGER_EXPORT RemotePlainGdbAdapter : public AbstractPlainGdbAdapter
{
Q_OBJECT
public:
friend class RemoteGdbProcess;
RemotePlainGdbAdapter(GdbEngine *engine, QObject *parent = 0);
void handleSetupDone();
void handleSetupFailed(const QString &reason);
signals:
void requestSetup();
private:
void startAdapter();
......
/****************************************************************************
**
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the Qt Creator.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
**
** 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, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "maemodebugsupport.h"
#include "maemodeployables.h"
#include "maemodeploystep.h"
#include "maemoglobal.h"
#include "maemorunconfiguration.h"
#include "maemosshrunner.h"
#include <coreplugin/ssh/sftpchannel.h>
#include <debugger/debuggerengine.h>
#include <debugger/debuggerplugin.h>
#include <debugger/debuggerrunner.h>
#include <debugger/gdb/remotegdbserveradapter.h>
#include <debugger/gdb/remoteplaingdbadapter.h>
#include <projectexplorer/toolchain.h>
#include <QtCore/QFileInfo>
using namespace Core;
using namespace Debugger;
using namespace Debugger::Internal;
using namespace ProjectExplorer;
namespace Qt4ProjectManager {
namespace Internal {
RunControl *MaemoDebugSupport::createDebugRunControl(MaemoRunConfiguration *runConfig)
{
DebuggerStartParameters params;
const MaemoDeviceConfig &devConf = runConfig->deviceConfig();
#ifdef USE_GDBSERVER
params.startMode = AttachToRemote;
params.executable = runConfig->localExecutableFilePath();
params.debuggerCommand = runConfig->gdbCmd();
params.remoteChannel = devConf.server.host + QLatin1Char(':')
+ gdbServerPort(runConfig, devConf);
params.remoteArchitecture = QLatin1String("arm");
#else
params.startMode = StartRemoteGdb;
params.executable = runConfig->remoteExecutableFilePath();
params.debuggerCommand = MaemoGlobal::remoteCommandPrefix(runConfig->remoteExecutableFilePath())
+ QLatin1String(" /usr/bin/gdb");
params.connParams = devConf.server;
#endif
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);
return debuggerRunControl;
}
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))
{
GdbEngine *engine = qobject_cast<GdbEngine *>(m_runControl->engine());
Q_ASSERT(engine);
m_gdbAdapter = qobject_cast<GdbAdapter *>(engine->gdbAdapter());
Q_ASSERT(m_gdbAdapter);
connect(m_gdbAdapter, SIGNAL(requestSetup()), this,
SLOT(handleAdapterSetupRequested()));
connect(m_runControl, SIGNAL(finished()), this,
SLOT(handleDebuggingFinished()));
#ifdef USE_GDBSERVER
m_runner->addProcsToKill(QStringList() << QLatin1String("gdbserver"));
#else
m_runner->addProcsToKill(QStringList() << QLatin1String("gdb"));
#endif
}
MaemoDebugSupport::~MaemoDebugSupport() {}
void MaemoDebugSupport::handleAdapterSetupRequested()
{
if (!m_deviceConfig.isValid()) {
handleAdapterSetupFailed(tr("No device configuration set for run configuration."));
return;
}
m_adapterStarted = false;
m_stopped = false;
m_runControl->showMessage(tr("Preparing remote side ..."), AppStuff);
disconnect(m_runner, 0, this, 0);
connect(m_runner, SIGNAL(error(QString)), this,
SLOT(handleSshError(QString)));
connect(m_runner, SIGNAL(readyForExecution()), this,
SLOT(startExecution()));
m_runner->start();
}
void MaemoDebugSupport::handleSshError(const QString &error)
{
if (!m_stopped && !m_adapterStarted)
handleAdapterSetupFailed(error);
}
void MaemoDebugSupport::startExecution()
{
if (m_stopped)
return;
const QString &dumperLib = m_runConfig->dumperLib();
if (!dumperLib.isEmpty()
&& m_runConfig->deployStep()->currentlyNeedsDeployment(m_deviceConfig.server.host,
MaemoDeployable(dumperLib, uploadDir(m_deviceConfig)))) {
m_uploader = m_runner->connection()->createSftpChannel();
connect(m_uploader.data(), SIGNAL(initialized()), this,
SLOT(handleSftpChannelInitialized()));
connect(m_uploader.data(), SIGNAL(initializationFailed(QString)), this,
SLOT(handleSftpChannelInitializationFailed(QString)));
connect(m_uploader.data(), SIGNAL(finished(Core::SftpJobId, QString)),
this, SLOT(handleSftpJobFinished(Core::SftpJobId, QString)));
m_uploader->initialize();
} else {
startDebugging();
}
}
void MaemoDebugSupport::handleSftpChannelInitialized()
{
if (m_stopped)
return;
const QString dumperLib = m_runConfig->dumperLib();
const QString fileName = QFileInfo(dumperLib).fileName();
const QString remoteFilePath = uploadDir(m_deviceConfig) + '/' + fileName;
m_uploadJob = m_uploader->uploadFile(dumperLib, remoteFilePath,
SftpOverwriteExisting);
if (m_uploadJob == SftpInvalidJob) {
handleAdapterSetupFailed(tr("Upload failed: Could not open file '%1'")
.arg(dumperLib));
} else {
m_runControl->showMessage(tr("Started uploading debugging helpers ('%1').")
.arg(dumperLib), AppStuff);
}
}
void MaemoDebugSupport::handleSftpChannelInitializationFailed(const QString &error)
{
if (m_stopped)
return;
handleAdapterSetupFailed(error);
}
void MaemoDebugSupport::handleSftpJobFinished(Core::SftpJobId job,
const QString &error)
{
if (m_stopped)
return;
if (job != m_uploadJob) {
qWarning("Warning: Unknown debugging helpers upload job %d finished.", job);
return;
}
if (!error.isEmpty()) {
handleAdapterSetupFailed(tr("Could not upload debugging helpers: %1.")
.arg(error));
} else {
m_runConfig->deployStep()->setDeployed(m_deviceConfig.server.host,
MaemoDeployable(m_runConfig->dumperLib(), uploadDir(m_deviceConfig)));
m_runControl->showMessage(tr("Finished uploading debugging helpers."), AppStuff);
startDebugging();
}
m_uploadJob = SftpInvalidJob;
}
void MaemoDebugSupport::startDebugging()
{
#ifdef USE_GDBSERVER
connect(m_runner, SIGNAL(remoteErrorOutput(QByteArray)), this,
SLOT(handleRemoteErrorOutput(QByteArray)));
connect(m_runner, SIGNAL(remoteOutput(QByteArray)), this,
SLOT(handleRemoteOutput(QByteArray)));
connect(m_runner, SIGNAL(remoteProcessStarted()), this,
SLOT(handleRemoteProcessStarted()));
const QString &remoteExe = m_runConfig->remoteExecutableFilePath();
m_runner->startExecution(QString::fromLocal8Bit("%1 gdbserver :%2 %3 %4")
.arg(MaemoGlobal::remoteCommandPrefix(remoteExe))
.arg(gdbServerPort(m_runConfig, m_deviceConfig))
.arg(remoteExe).arg(m_runConfig->arguments()
.join(QLatin1String(" "))).toUtf8());
#else
stopSsh();
handleAdapterSetupDone();
#endif
}
void MaemoDebugSupport::handleRemoteProcessStarted()
{
handleAdapterSetupDone();
}
void MaemoDebugSupport::handleDebuggingFinished()
{
m_stopped = true;
stopSsh();
}
void MaemoDebugSupport::handleRemoteOutput(const QByteArray &output)
{
m_runControl->showMessage(QString::fromUtf8(output), AppOutput);
}
void MaemoDebugSupport::handleRemoteErrorOutput(const QByteArray &output)
{
m_runControl->showMessage(QString::fromUtf8(output), AppOutput);
}
void MaemoDebugSupport::stopSsh()
{
disconnect(m_runner, 0, this, 0);
if (m_uploader) {
disconnect(m_uploader.data(), 0, this, 0);
m_uploader->closeChannel();
}
m_runner->stop();
}
void MaemoDebugSupport::handleAdapterSetupFailed(const QString &error)
{
m_gdbAdapter->handleSetupFailed(tr("Initial setup failed: %1").arg(error));
m_stopped = true;
stopSsh();
}
void MaemoDebugSupport::handleAdapterSetupDone()
{
m_adapterStarted = true;
m_gdbAdapter->handleSetupDone();
}
QString MaemoDebugSupport::gdbServerPort(const MaemoRunConfiguration *rc,
const MaemoDeviceConfig &devConf)
{
// During configuration we don't know which port to use, so we display
// something in the config dialog, but we will make sure we use
// the right port from the information file.
return devConf.type == MaemoDeviceConfig::Physical
? QString::number(devConf.gdbServerPort)
: rc->runtimeGdbServerPort();
}
QString MaemoDebugSupport::uploadDir(const MaemoDeviceConfig &devConf)
{
return MaemoGlobal::homeDirOnDevice(devConf.server.uname);
}
} // namespace Internal
} // namespace Qt4ProjectManager
/****************************************************************************
**
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the Qt Creator.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
**
** 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, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef MAEMODEBUGSUPPORT_H
#define MAEMODEBUGSUPPORT_H