Commit b9580e3c authored by hjk's avatar hjk Committed by hjk

debugger: let debugger attach to currently running process

Change-Id: I4aab1aa84a3dc9211d84d59be76005a8e841239e
(cherry picked from commit 55e399b524721e3561b6c7faae8aef84bf064565)
Reviewed-on: http://codereview.qt.nokia.com/251Reviewed-by: default avatarQt Sanity Bot <qt_sanity_bot@ovi.com>
Reviewed-by: default avatarhjk <qthjk@ovi.com>
parent eb1336da
...@@ -520,6 +520,8 @@ void DebuggerEngine::startDebugger(DebuggerRunControl *runControl) ...@@ -520,6 +520,8 @@ void DebuggerEngine::startDebugger(DebuggerRunControl *runControl)
d->m_inferiorPid = d->m_startParameters.attachPID > 0 d->m_inferiorPid = d->m_startParameters.attachPID > 0
? d->m_startParameters.attachPID : 0; ? d->m_startParameters.attachPID : 0;
if (d->m_inferiorPid)
d->m_runControl->setApplicationProcessHandle(ProcessHandle(d->m_inferiorPid));
if (!d->m_startParameters.environment.size()) if (!d->m_startParameters.environment.size())
d->m_startParameters.environment = Utils::Environment(); d->m_startParameters.environment = Utils::Environment();
...@@ -1174,6 +1176,7 @@ void DebuggerEngine::notifyInferiorPid(qint64 pid) ...@@ -1174,6 +1176,7 @@ void DebuggerEngine::notifyInferiorPid(qint64 pid)
return; return;
d->m_inferiorPid = pid; d->m_inferiorPid = pid;
if (pid) { if (pid) {
d->m_runControl->setApplicationProcessHandle(ProcessHandle(pid));
showMessage(tr("Taking notice of pid %1").arg(pid)); showMessage(tr("Taking notice of pid %1").arg(pid));
if (d->m_startParameters.startMode == StartInternal if (d->m_startParameters.startMode == StartInternal
|| d->m_startParameters.startMode == StartExternal || d->m_startParameters.startMode == StartExternal
......
...@@ -688,9 +688,10 @@ public slots: ...@@ -688,9 +688,10 @@ public slots:
void startRemoteApplication(); void startRemoteApplication();
void startRemoteEngine(); void startRemoteEngine();
void attachExternalApplication(); void attachExternalApplication();
Q_SLOT void attachExternalApplication(ProjectExplorer::RunControl *rc);
void attachExternalApplication(qint64 pid, const QString &binary, void attachExternalApplication(qint64 pid, const QString &binary,
const ProjectExplorer::Abi &abi = ProjectExplorer::Abi(), const ProjectExplorer::Abi &abi,
const QString &debuggerCommand = QString()); const QString &debuggerCommand);
void runScheduled(); void runScheduled();
void attachCore(); void attachCore();
void attachCore(const QString &core, const QString &exeFileName, void attachCore(const QString &core, const QString &exeFileName,
...@@ -1065,6 +1066,7 @@ DebuggerPluginPrivate::DebuggerPluginPrivate(DebuggerPlugin *plugin) : ...@@ -1065,6 +1066,7 @@ DebuggerPluginPrivate::DebuggerPluginPrivate(DebuggerPlugin *plugin) :
m_dummyEngine(0), m_dummyEngine(0),
m_globalDebuggerOptions(new GlobalDebuggerOptions) m_globalDebuggerOptions(new GlobalDebuggerOptions)
{ {
setObjectName("DebuggerCore");
qRegisterMetaType<WatchData>("WatchData"); qRegisterMetaType<WatchData>("WatchData");
qRegisterMetaType<ContextData>("ContextData"); qRegisterMetaType<ContextData>("ContextData");
qRegisterMetaType<DebuggerStartParameters>("DebuggerStartParameters"); qRegisterMetaType<DebuggerStartParameters>("DebuggerStartParameters");
...@@ -1434,6 +1436,18 @@ void DebuggerPluginPrivate::attachExternalApplication(qint64 pid, const QString ...@@ -1434,6 +1436,18 @@ void DebuggerPluginPrivate::attachExternalApplication(qint64 pid, const QString
startDebugger(rc); startDebugger(rc);
} }
void DebuggerPluginPrivate::attachExternalApplication(ProjectExplorer::RunControl *rc)
{
DebuggerStartParameters sp;
sp.attachPID = rc->applicationProcessHandle().pid();
sp.displayName = tr("Debugger attached to %1").arg(rc->displayName());
sp.startMode = AttachExternal;
//sp.toolChainAbi = abiOfBinary(sp.executable);
sp.toolChainAbi = ProjectExplorer::Abi::hostAbi(); // FIXME: Extract from RunControl?
if (DebuggerRunControl *rc = createDebugger(sp))
startDebugger(rc);
}
void DebuggerPluginPrivate::attachCore() void DebuggerPluginPrivate::attachCore()
{ {
AttachCoreDialog dlg(mainWindow()); AttachCoreDialog dlg(mainWindow());
...@@ -2538,6 +2552,8 @@ void DebuggerPluginPrivate::extensionsInitialized() ...@@ -2538,6 +2552,8 @@ void DebuggerPluginPrivate::extensionsInitialized()
Core::ActionManager *am = core->actionManager(); Core::ActionManager *am = core->actionManager();
QTC_ASSERT(am, return); QTC_ASSERT(am, return);
m_plugin->addObject(this);
const Context globalcontext(CC::C_GLOBAL); const Context globalcontext(CC::C_GLOBAL);
const Context cppDebuggercontext(C_CPPDEBUGGER); const Context cppDebuggercontext(C_CPPDEBUGGER);
const Context qmlDebuggerContext(C_QMLDEBUGGER); const Context qmlDebuggerContext(C_QMLDEBUGGER);
...@@ -3128,6 +3144,7 @@ void DebuggerPluginPrivate::showModuleSymbols(const QString &moduleName, ...@@ -3128,6 +3144,7 @@ void DebuggerPluginPrivate::showModuleSymbols(const QString &moduleName,
void DebuggerPluginPrivate::aboutToShutdown() void DebuggerPluginPrivate::aboutToShutdown()
{ {
m_plugin->removeObject(this);
disconnect(sessionManager(), disconnect(sessionManager(),
SIGNAL(startupProjectChanged(ProjectExplorer::Project*)), SIGNAL(startupProjectChanged(ProjectExplorer::Project*)),
this, 0); this, 0);
......
...@@ -46,6 +46,8 @@ ...@@ -46,6 +46,8 @@
#include <aggregation/aggregate.h> #include <aggregation/aggregate.h>
#include <texteditor/fontsettings.h> #include <texteditor/fontsettings.h>
#include <texteditor/texteditorsettings.h> #include <texteditor/texteditorsettings.h>
#include <extensionsystem/pluginmanager.h>
#include <extensionsystem/invoker.h>
#include <utils/qtcassert.h> #include <utils/qtcassert.h>
#include <utils/outputformatter.h> #include <utils/outputformatter.h>
...@@ -62,6 +64,11 @@ enum { debug = 0 }; ...@@ -62,6 +64,11 @@ enum { debug = 0 };
using namespace ProjectExplorer; using namespace ProjectExplorer;
using namespace ProjectExplorer::Internal; using namespace ProjectExplorer::Internal;
static QObject *debuggerCore()
{
return ExtensionSystem::PluginManager::instance()->getObjectByName("DebuggerCore");
}
AppOutputPane::RunControlTab::RunControlTab(RunControl *rc, Core::OutputWindow *w) : AppOutputPane::RunControlTab::RunControlTab(RunControl *rc, Core::OutputWindow *w) :
runControl(rc), window(w), asyncClosing(false) runControl(rc), window(w), asyncClosing(false)
{ {
...@@ -72,7 +79,8 @@ AppOutputPane::AppOutputPane() : ...@@ -72,7 +79,8 @@ AppOutputPane::AppOutputPane() :
m_tabWidget(new QTabWidget), m_tabWidget(new QTabWidget),
m_stopAction(new QAction(QIcon(QLatin1String(Constants::ICON_STOP)), tr("Stop"), this)), m_stopAction(new QAction(QIcon(QLatin1String(Constants::ICON_STOP)), tr("Stop"), this)),
m_reRunButton(new QToolButton), m_reRunButton(new QToolButton),
m_stopButton(new QToolButton) m_stopButton(new QToolButton),
m_attachButton(new QToolButton)
{ {
// Rerun // Rerun
m_reRunButton->setIcon(QIcon(ProjectExplorer::Constants::ICON_RUN_SMALL)); m_reRunButton->setIcon(QIcon(ProjectExplorer::Constants::ICON_RUN_SMALL));
...@@ -97,6 +105,15 @@ AppOutputPane::AppOutputPane() : ...@@ -97,6 +105,15 @@ AppOutputPane::AppOutputPane() :
connect(m_stopAction, SIGNAL(triggered()), connect(m_stopAction, SIGNAL(triggered()),
this, SLOT(stopRunControl())); this, SLOT(stopRunControl()));
// Attach
m_attachButton->setToolTip(tr("Attach debugger to this process"));
m_attachButton->setEnabled(false);
m_attachButton->setIcon(QIcon(ProjectExplorer::Constants::ICON_DEBUG_SMALL));
m_attachButton->setAutoRaise(true);
connect(m_attachButton, SIGNAL(clicked()),
this, SLOT(attachToRunControl()));
// Spacer (?) // Spacer (?)
QVBoxLayout *layout = new QVBoxLayout; QVBoxLayout *layout = new QVBoxLayout;
...@@ -185,7 +202,7 @@ QWidget *AppOutputPane::outputWidget(QWidget *) ...@@ -185,7 +202,7 @@ QWidget *AppOutputPane::outputWidget(QWidget *)
QList<QWidget*> AppOutputPane::toolBarWidgets() const QList<QWidget*> AppOutputPane::toolBarWidgets() const
{ {
return QList<QWidget*>() << m_reRunButton << m_stopButton; return QList<QWidget*>() << m_reRunButton << m_stopButton << m_attachButton;
} }
QString AppOutputPane::displayName() const QString AppOutputPane::displayName() const
...@@ -313,6 +330,15 @@ void AppOutputPane::reRunRunControl() ...@@ -313,6 +330,15 @@ void AppOutputPane::reRunRunControl()
tab.runControl->start(); tab.runControl->start();
} }
void AppOutputPane::attachToRunControl()
{
const int index = currentIndex();
QTC_ASSERT(index != -1, return);
ProjectExplorer::RunControl *rc = m_runControlTabs.at(index).runControl;
QTC_ASSERT(rc->isRunning(), return);
ExtensionSystem::Invoker<void>(debuggerCore(), "attachExternalApplication", rc);
}
void AppOutputPane::stopRunControl() void AppOutputPane::stopRunControl()
{ {
const int index = currentIndex(); const int index = currentIndex();
...@@ -399,6 +425,7 @@ void AppOutputPane::tabChanged(int i) ...@@ -399,6 +425,7 @@ void AppOutputPane::tabChanged(int i)
if (i == -1) { if (i == -1) {
m_stopAction->setEnabled(false); m_stopAction->setEnabled(false);
m_reRunButton->setEnabled(false); m_reRunButton->setEnabled(false);
m_attachButton->setEnabled(false);
} else { } else {
const int index = indexOf(m_tabWidget->widget(i)); const int index = indexOf(m_tabWidget->widget(i));
QTC_ASSERT(index != -1, return; ) QTC_ASSERT(index != -1, return; )
...@@ -407,6 +434,7 @@ void AppOutputPane::tabChanged(int i) ...@@ -407,6 +434,7 @@ void AppOutputPane::tabChanged(int i)
m_stopAction->setEnabled(rc->isRunning()); m_stopAction->setEnabled(rc->isRunning());
m_reRunButton->setEnabled(!rc->isRunning()); m_reRunButton->setEnabled(!rc->isRunning());
m_reRunButton->setIcon(rc->icon()); m_reRunButton->setIcon(rc->icon());
m_attachButton->setEnabled(debuggerCore());
} }
} }
...@@ -416,6 +444,7 @@ void AppOutputPane::runControlStarted() ...@@ -416,6 +444,7 @@ void AppOutputPane::runControlStarted()
if (current && current == sender()) { if (current && current == sender()) {
m_reRunButton->setEnabled(false); m_reRunButton->setEnabled(false);
m_stopAction->setEnabled(true); m_stopAction->setEnabled(true);
m_attachButton->setEnabled(debuggerCore());
m_reRunButton->setIcon(current->icon()); m_reRunButton->setIcon(current->icon());
} }
} }
...@@ -437,6 +466,7 @@ void AppOutputPane::runControlFinished() ...@@ -437,6 +466,7 @@ void AppOutputPane::runControlFinished()
if (current && current == sender()) { if (current && current == sender()) {
m_reRunButton->setEnabled(true); m_reRunButton->setEnabled(true);
m_stopAction->setEnabled(false); m_stopAction->setEnabled(false);
m_attachButton->setEnabled(false);
m_reRunButton->setIcon(current->icon()); m_reRunButton->setIcon(current->icon());
} }
// Check for asynchronous close. Close the tab. // Check for asynchronous close. Close the tab.
......
...@@ -97,6 +97,7 @@ public slots: ...@@ -97,6 +97,7 @@ public slots:
private slots: private slots:
void reRunRunControl(); void reRunRunControl();
void stopRunControl(); void stopRunControl();
void attachToRunControl();
bool closeTab(int index); bool closeTab(int index);
void tabChanged(int); void tabChanged(int);
void runControlStarted(); void runControlStarted();
...@@ -132,6 +133,7 @@ private: ...@@ -132,6 +133,7 @@ private:
QAction *m_stopAction; QAction *m_stopAction;
QToolButton *m_reRunButton; QToolButton *m_reRunButton;
QToolButton *m_stopButton; QToolButton *m_stopButton;
QToolButton *m_attachButton;
}; };
} // namespace Internal } // namespace Internal
......
...@@ -109,6 +109,7 @@ void LocalApplicationRunControl::start() ...@@ -109,6 +109,7 @@ void LocalApplicationRunControl::start()
emit finished(); emit finished();
} else { } else {
m_applicationLauncher.start(m_runMode, m_executable, m_commandLineArguments); m_applicationLauncher.start(m_runMode, m_executable, m_commandLineArguments);
setApplicationProcessHandle(ProcessHandle(m_applicationLauncher.applicationPID()));
QString msg = tr("Starting %1...\n").arg(QDir::toNativeSeparators(m_executable)); QString msg = tr("Starting %1...\n").arg(QDir::toNativeSeparators(m_executable));
appendMessage(msg, Utils::NormalMessageFormat); appendMessage(msg, Utils::NormalMessageFormat);
} }
......
...@@ -71,6 +71,7 @@ private: ...@@ -71,6 +71,7 @@ private:
QString m_executable; QString m_executable;
QString m_commandLineArguments; QString m_commandLineArguments;
ProjectExplorer::ApplicationLauncher::Mode m_runMode; ProjectExplorer::ApplicationLauncher::Mode m_runMode;
ProcessHandle m_applicationProcessHandle;
}; };
} // namespace Internal } // namespace Internal
......
...@@ -150,6 +150,12 @@ IRunConfigurationFactory *findRunConfigurationFactory(RunConfigurationFactoryMat ...@@ -150,6 +150,12 @@ IRunConfigurationFactory *findRunConfigurationFactory(RunConfigurationFactoryMat
} // namespace } // namespace
/*!
\class ProjectExplorer::ProcessHandle
\brief Helper class to describe a process.
*/
/*! /*!
\class ProjectExplorer::RunConfiguration \class ProjectExplorer::RunConfiguration
\brief Base class for a run configuration. A run configuration specifies how a \brief Base class for a run configuration. A run configuration specifies how a
...@@ -351,6 +357,7 @@ Utils::OutputFormatter *RunConfiguration::createOutputFormatter() const ...@@ -351,6 +357,7 @@ Utils::OutputFormatter *RunConfiguration::createOutputFormatter() const
return new Utils::OutputFormatter(); return new Utils::OutputFormatter();
} }
/*! /*!
\class ProjectExplorer::IRunConfigurationFactory \class ProjectExplorer::IRunConfigurationFactory
...@@ -492,6 +499,16 @@ QString RunControl::displayName() const ...@@ -492,6 +499,16 @@ QString RunControl::displayName() const
return m_displayName; return m_displayName;
} }
ProcessHandle RunControl::applicationProcessHandle() const
{
return m_applicationProcessHandle;
}
void RunControl::setApplicationProcessHandle(const ProcessHandle &handle)
{
m_applicationProcessHandle = handle;
}
bool RunControl::promptToStop(bool *optionalPrompt) const bool RunControl::promptToStop(bool *optionalPrompt) const
{ {
QTC_ASSERT(isRunning(), return true;) QTC_ASSERT(isRunning(), return true;)
......
...@@ -51,6 +51,20 @@ class IRunConfigurationAspect; ...@@ -51,6 +51,20 @@ class IRunConfigurationAspect;
class RunControl; class RunControl;
class Target; class Target;
// FIXME: This should also contain a handle to an remote device if used.
class PROJECTEXPLORER_EXPORT ProcessHandle
{
public:
explicit ProcessHandle(quint64 pid = 0) : m_pid(pid) {}
bool isValid() const { return m_pid != 0; }
void setPid(quint64 pid) { m_pid = pid; }
quint64 pid() const { return m_pid; }
private:
quint64 m_pid;
};
// Documentation inside. // Documentation inside.
class PROJECTEXPLORER_EXPORT RunConfiguration : public ProjectConfiguration class PROJECTEXPLORER_EXPORT RunConfiguration : public ProjectConfiguration
{ {
...@@ -210,6 +224,9 @@ public: ...@@ -210,6 +224,9 @@ public:
virtual QString displayName() const; virtual QString displayName() const;
virtual QIcon icon() const = 0; virtual QIcon icon() const = 0;
ProcessHandle applicationProcessHandle() const;
void setApplicationProcessHandle(const ProcessHandle &handle);
bool sameRunConfiguration(const RunControl *other) const; bool sameRunConfiguration(const RunControl *other) const;
Utils::OutputFormatter *outputFormatter(); Utils::OutputFormatter *outputFormatter();
...@@ -240,6 +257,9 @@ private: ...@@ -240,6 +257,9 @@ private:
const QWeakPointer<RunConfiguration> m_runConfiguration; const QWeakPointer<RunConfiguration> m_runConfiguration;
Utils::OutputFormatter *m_outputFormatter; Utils::OutputFormatter *m_outputFormatter;
// A handle to the actual application process.
ProcessHandle m_applicationProcessHandle;
#ifdef Q_OS_MAC #ifdef Q_OS_MAC
//these two are used to bring apps in the foreground on Mac //these two are used to bring apps in the foreground on Mac
qint64 m_internalPid; qint64 m_internalPid;
...@@ -251,5 +271,6 @@ private: ...@@ -251,5 +271,6 @@ private:
// Allow a RunConfiguration to be stored in a QVariant // Allow a RunConfiguration to be stored in a QVariant
Q_DECLARE_METATYPE(ProjectExplorer::RunConfiguration*) Q_DECLARE_METATYPE(ProjectExplorer::RunConfiguration*)
Q_DECLARE_METATYPE(ProjectExplorer::RunControl*)
#endif // RUNCONFIGURATION_H #endif // RUNCONFIGURATION_H
...@@ -96,7 +96,7 @@ void QmlProjectRunControl::start() ...@@ -96,7 +96,7 @@ void QmlProjectRunControl::start()
{ {
m_applicationLauncher.start(ApplicationLauncher::Gui, m_executable, m_applicationLauncher.start(ApplicationLauncher::Gui, m_executable,
m_commandLineArguments); m_commandLineArguments);
setApplicationProcessHandle(ProcessHandle(m_applicationLauncher.applicationPID()));
emit started(); emit started();
QString msg = tr("Starting %1 %2\n") QString msg = tr("Starting %1 %2\n")
.arg(QDir::toNativeSeparators(m_executable), m_commandLineArguments); .arg(QDir::toNativeSeparators(m_executable), m_commandLineArguments);
......
...@@ -348,13 +348,14 @@ S60EmulatorRunControl::S60EmulatorRunControl(S60EmulatorRunConfiguration *runCon ...@@ -348,13 +348,14 @@ S60EmulatorRunControl::S60EmulatorRunControl(S60EmulatorRunConfiguration *runCon
this, SLOT(slotAppendMessage(QString, Utils::OutputFormat))); this, SLOT(slotAppendMessage(QString, Utils::OutputFormat)));
connect(&m_applicationLauncher, SIGNAL(processExited(int)), connect(&m_applicationLauncher, SIGNAL(processExited(int)),
this, SLOT(processExited(int))); this, SLOT(processExited(int)));
connect(&m_applicationLauncher, SIGNAL(bringToForegroundRequested(qint64)), connect(&m_applicationLauncher, SIGNAL(bringToForegroundRequested(quint64)),
this, SLOT(bringApplicationToForeground(qint64))); this, SLOT(bringApplicationToForeground(quint64)));
} }
void S60EmulatorRunControl::start() void S60EmulatorRunControl::start()
{ {
m_applicationLauncher.start(ApplicationLauncher::Gui, m_executable, QString()); m_applicationLauncher.start(ApplicationLauncher::Gui, m_executable, QString());
setApplicationProcessHandle(ProcessHandle(m_applicationLauncher.applicationPID()));
emit started(); emit started();
QString msg = tr("Starting %1...\n").arg(QDir::toNativeSeparators(m_executable)); QString msg = tr("Starting %1...\n").arg(QDir::toNativeSeparators(m_executable));
......
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