diff --git a/src/plugins/debugger/attachremotedialog.ui b/src/plugins/debugger/attachremotedialog.ui
index 04a1073492c..0326926a31f 100644
--- a/src/plugins/debugger/attachremotedialog.ui
+++ b/src/plugins/debugger/attachremotedialog.ui
@@ -6,8 +6,8 @@
0
0
- 561
- 866
+ 310
+ 224
@@ -22,58 +22,35 @@
-
+
+ QFormLayout::ExpandingFieldsGrow
+
-
-
+
- Attach to Process ID:
+ Host and Port:
-
-
+
+
+ localhost:5115
+
+
-
-
+
- Filter:
+ Architecture:
-
-
-
-
- 0
-
-
-
-
-
- -
-
-
- ...
-
-
-
-
-
+
- -
-
-
- QAbstractItemView::NoEditTriggers
-
-
-
- -
-
-
- Qt::Horizontal
-
-
-
-
diff --git a/src/plugins/debugger/debuggerdialogs.cpp b/src/plugins/debugger/debuggerdialogs.cpp
index 483ad82a1e6..e404ea88e02 100644
--- a/src/plugins/debugger/debuggerdialogs.cpp
+++ b/src/plugins/debugger/debuggerdialogs.cpp
@@ -51,7 +51,7 @@
namespace Debugger {
- namespace Internal {
+namespace Internal {
bool operator<(const ProcData &p1, const ProcData &p2)
{
@@ -59,7 +59,8 @@ bool operator<(const ProcData &p1, const ProcData &p2)
}
// A filterable process list model
-class ProcessListFilterModel : public QSortFilterProxyModel {
+class ProcessListFilterModel : public QSortFilterProxyModel
+{
public:
explicit ProcessListFilterModel(QObject *parent);
QString processIdAt(const QModelIndex &index) const;
@@ -69,9 +70,9 @@ private:
QStandardItemModel *m_model;
};
-ProcessListFilterModel::ProcessListFilterModel(QObject *parent) :
- QSortFilterProxyModel(parent),
- m_model(new QStandardItemModel(this))
+ProcessListFilterModel::ProcessListFilterModel(QObject *parent)
+ : QSortFilterProxyModel(parent),
+ m_model(new QStandardItemModel(this))
{
QStringList columns;
columns << AttachExternalDialog::tr("Process ID")
@@ -116,6 +117,7 @@ void ProcessListFilterModel::populate(QList processes, const QString &
}
}
+
///////////////////////////////////////////////////////////////////////
//
// AttachCoreDialog
@@ -164,9 +166,10 @@ void AttachCoreDialog::setCoreFile(const QString &fileName)
m_ui->coreFileName->setPath(fileName);
}
+
///////////////////////////////////////////////////////////////////////
//
-// process model helpers
+// Process model helpers
//
///////////////////////////////////////////////////////////////////////
@@ -224,11 +227,11 @@ static QList processList()
//
///////////////////////////////////////////////////////////////////////
-AttachExternalDialog::AttachExternalDialog(QWidget *parent) :
- QDialog(parent),
- m_selfPid(QString::number(QCoreApplication::applicationPid())),
- m_ui(new Ui::AttachExternalDialog),
- m_model(new ProcessListFilterModel(this))
+AttachExternalDialog::AttachExternalDialog(QWidget *parent)
+ : QDialog(parent),
+ m_selfPid(QString::number(QCoreApplication::applicationPid())),
+ m_ui(new Ui::AttachExternalDialog),
+ m_model(new ProcessListFilterModel(this))
{
m_ui->setupUi(this);
okButton()->setDefault(true);
@@ -292,48 +295,26 @@ int AttachExternalDialog::attachPID() const
void AttachExternalDialog::pidChanged(const QString &pid)
{
- okButton()->setEnabled(!pid.isEmpty() && pid != QLatin1String("0") && pid != m_selfPid);
+ bool enabled = !pid.isEmpty() && pid != QLatin1String("0") && pid != m_selfPid;;
+ okButton()->setEnabled(enabled);
}
+
///////////////////////////////////////////////////////////////////////
//
// AttachRemoteDialog
//
///////////////////////////////////////////////////////////////////////
-AttachRemoteDialog::AttachRemoteDialog(QWidget *parent, const QString &pid) :
- QDialog(parent),
- m_ui(new Ui::AttachRemoteDialog),
- m_model(new ProcessListFilterModel(this))
+AttachRemoteDialog::AttachRemoteDialog(QWidget *parent)
+ : QDialog(parent),
+ m_ui(new Ui::AttachRemoteDialog)
{
m_ui->setupUi(this);
m_ui->buttonBox->button(QDialogButtonBox::Ok)->setDefault(true);
- m_defaultPID = pid;
-
- m_ui->procView->setModel(m_model);
- m_ui->procView->setSortingEnabled(true);
-
+
connect(m_ui->buttonBox, SIGNAL(accepted()), this, SLOT(accept()));
connect(m_ui->buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
-
- // Do not use activated, will be single click in Oxygen
- connect(m_ui->procView, SIGNAL(doubleClicked(QModelIndex)),
- this, SLOT(procSelected(QModelIndex)));
-
- QPushButton *refreshButton = new QPushButton(tr("Refresh"));
- connect(refreshButton, SIGNAL(clicked()), this, SLOT(rebuildProcessList()));
- m_ui->buttonBox->addButton(refreshButton, QDialogButtonBox::ActionRole);
-
- connect(m_ui->pidLineEdit, SIGNAL(textChanged(QString)),
- this, SLOT(pidChanged(QString)));
-
- connect(m_ui->filterClearToolButton, SIGNAL(clicked()),
- m_ui->filterLineEdit, SLOT(clear()));
- connect(m_ui->filterLineEdit, SIGNAL(textChanged(QString)),
- m_model, SLOT(setFilterFixedString(QString)));
-
- m_ui->pidLineEdit->setText(m_defaultPID);
- rebuildProcessList();
}
AttachRemoteDialog::~AttachRemoteDialog()
@@ -341,37 +322,36 @@ AttachRemoteDialog::~AttachRemoteDialog()
delete m_ui;
}
-QPushButton *AttachRemoteDialog::okButton() const
+void AttachRemoteDialog::setRemoteChannel(const QString &channel)
{
- return m_ui->buttonBox->button(QDialogButtonBox::Ok);
+ m_ui->channelLineEdit->setText(channel);
}
-void AttachRemoteDialog::rebuildProcessList()
+QString AttachRemoteDialog::remoteChannel() const
{
- m_model->populate(processList());
- m_ui->procView->expandAll();
- m_ui->procView->resizeColumnToContents(0);
- m_ui->procView->resizeColumnToContents(1);
+ return m_ui->channelLineEdit->text();
}
-void AttachRemoteDialog::procSelected(const QModelIndex &index0)
-{
- const QString proccessId = m_model->processIdAt(index0);
- if (!proccessId.isEmpty()) {
- m_ui->pidLineEdit->setText(proccessId);
- if (okButton()->isEnabled())
- okButton()->animateClick();
+void AttachRemoteDialog::setRemoteArchitectures(const QStringList &list)
+{
+ m_ui->architectureComboBox->clear();
+ if (!list.isEmpty()) {
+ m_ui->architectureComboBox->insertItems(0, list);
+ m_ui->architectureComboBox->setCurrentIndex(0);
}
}
-int AttachRemoteDialog::attachPID() const
+void AttachRemoteDialog::setRemoteArchitecture(const QString &arch)
{
- return m_ui->pidLineEdit->text().toInt();
+ int index = m_ui->architectureComboBox->findText(arch);
+ if (index != -1)
+ m_ui->architectureComboBox->setCurrentIndex(index);
}
-void AttachRemoteDialog::pidChanged(const QString &pid)
+QString AttachRemoteDialog::remoteArchitecture() const
{
- okButton()->setEnabled(!pid.isEmpty() && pid != QLatin1String("0"));
+ int index = m_ui->architectureComboBox->currentIndex();
+ return m_ui->architectureComboBox->itemText(index);
}
@@ -426,5 +406,5 @@ QString StartExternalDialog::executableArguments() const
return m_ui->argsEdit->text();
}
-}
-}
+} // namespace Internal
+} // namespace Debugger
diff --git a/src/plugins/debugger/debuggerdialogs.h b/src/plugins/debugger/debuggerdialogs.h
index f263e710c66..c51fc3abe77 100644
--- a/src/plugins/debugger/debuggerdialogs.h
+++ b/src/plugins/debugger/debuggerdialogs.h
@@ -101,30 +101,24 @@ private:
ProcessListFilterModel *m_model;
};
-
class AttachRemoteDialog : public QDialog
{
Q_OBJECT
public:
- explicit AttachRemoteDialog(QWidget *parent, const QString &pid);
+ explicit AttachRemoteDialog(QWidget *parent);
~AttachRemoteDialog();
- int attachPID() const;
-
-private slots:
- void rebuildProcessList();
- void procSelected(const QModelIndex &);
- void pidChanged(const QString &);
+ void setRemoteChannel(const QString &host);
+ void setRemoteArchitecture(const QString &arch);
+ void setRemoteArchitectures(const QStringList &arches);
+ QString remoteChannel() const;
+ QString remoteArchitecture() const;
private:
- inline QPushButton *okButton() const;
Ui::AttachRemoteDialog *m_ui;
- QString m_defaultPID;
- ProcessListFilterModel *m_model;
};
-
class StartExternalDialog : public QDialog
{
Q_OBJECT
diff --git a/src/plugins/debugger/debuggermanager.cpp b/src/plugins/debugger/debuggermanager.cpp
index d77c7b10829..0120ae02d25 100644
--- a/src/plugins/debugger/debuggermanager.cpp
+++ b/src/plugins/debugger/debuggermanager.cpp
@@ -89,6 +89,7 @@ using namespace Debugger::Constants;
static const QString tooltipIName = "tooltip";
+#define _(s) QString::fromLatin1(s)
static const char *stateName(int s)
{
@@ -304,6 +305,11 @@ void DebuggerManager::init()
m_attachCoreAction->setText(tr("Attach to Core..."));
connect(m_attachCoreAction, SIGNAL(triggered()), this, SLOT(attachCore()));
+ m_attachRemoteAction = new QAction(this);
+ m_attachRemoteAction->setText(tr("Attach to Running Remote Application..."));
+ connect(m_attachRemoteAction, SIGNAL(triggered()),
+ this, SLOT(attachRemoteApplication()));
+
m_continueAction = new QAction(this);
m_continueAction->setText(tr("Continue"));
m_continueAction->setIcon(QIcon(":/gdbdebugger/images/debugger_continue_small.png"));
@@ -437,7 +443,7 @@ QList DebuggerManager::initializeEngines(const QStringList
{
QList rc;
gdbEngine = createGdbEngine(this, &rc);
- const bool cdbDisabled = arguments.contains(QLatin1String("-disable-cdb"));
+ const bool cdbDisabled = arguments.contains(_("-disable-cdb"));
winEngine = createWinEngine(this, cdbDisabled, &rc);
scriptEngine = createScriptEngine(this, &rc);
setDebuggerType(GdbDebugger);
@@ -810,12 +816,18 @@ void DebuggerManager::attachCore()
emit debuggingFinished();
}
+void DebuggerManager::attachRemoteApplication()
+{
+ if (!startNewDebugger(AttachRemote))
+ emit debuggingFinished();
+}
+
// Figure out the debugger type of an executable
static bool determineDebuggerType(const QString &executable,
DebuggerManager::DebuggerType *dt,
QString *errorMessage)
{
- if (executable.endsWith(QLatin1String(".js"))) {
+ if (executable.endsWith(_(".js"))) {
*dt = DebuggerManager::ScriptDebugger;
return true;
}
@@ -869,21 +881,21 @@ bool DebuggerManager::startNewDebugger(DebuggerStartMode mode)
case StartExternal: {
StartExternalDialog dlg(mainWindow());
dlg.setExecutableFile(
- configValue(QLatin1String("LastExternalExecutableFile")).toString());
+ configValue(_("LastExternalExecutableFile")).toString());
dlg.setExecutableArguments(
- configValue(QLatin1String("LastExternalExecutableArguments")).toString());
+ configValue(_("LastExternalExecutableArguments")).toString());
if (dlg.exec() != QDialog::Accepted)
return false;
- setConfigValue(QLatin1String("LastExternalExecutableFile"),
+ setConfigValue(_("LastExternalExecutableFile"),
dlg.executableFile());
- setConfigValue(QLatin1String("LastExternalExecutableArguments"),
+ setConfigValue(_("LastExternalExecutableArguments"),
dlg.executableArguments());
m_executable = dlg.executableFile();
m_processArgs = dlg.executableArguments().split(' ');
m_workingDir = QString();
m_attachedPID = -1;
- }
break;
+ }
case AttachExternal: {
AttachExternalDialog dlg(mainWindow());
if (dlg.exec() != QDialog::Accepted)
@@ -897,9 +909,9 @@ bool DebuggerManager::startNewDebugger(DebuggerStartMode mode)
tr("Cannot attach to PID 0"));
return false;
}
- }
break;
- case StartInternal:
+ }
+ case StartInternal: {
if (m_executable.isEmpty()) {
QString startDirectory = m_executable;
if (m_executable.isEmpty()) {
@@ -920,30 +932,46 @@ bool DebuggerManager::startNewDebugger(DebuggerStartMode mode)
m_attachedPID = 0;
} else {
//m_executable = QDir::convertSeparators(m_executable);
- //m_processArgs = sd.processArgs.join(QLatin1String(" "));
+ //m_processArgs = sd.processArgs.join(_(" "));
m_attachedPID = 0;
}
break;
+ }
case AttachCore: {
AttachCoreDialog dlg(mainWindow());
dlg.setExecutableFile(
- configValue(QLatin1String("LastExternalExecutableFile")).toString());
+ configValue(_("LastExternalExecutableFile")).toString());
dlg.setCoreFile(
- configValue(QLatin1String("LastExternalCoreFile")).toString());
+ configValue(_("LastExternalCoreFile")).toString());
if (dlg.exec() != QDialog::Accepted)
return false;
- setConfigValue(QLatin1String("LastExternalExecutableFile"),
+ setConfigValue(_("LastExternalExecutableFile"),
dlg.executableFile());
- setConfigValue(QLatin1String("LastExternalCoreFile"),
+ setConfigValue(_("LastExternalCoreFile"),
dlg.coreFile());
m_executable = dlg.executableFile();
m_coreFile = dlg.coreFile();
m_processArgs.clear();
m_workingDir = QString();
m_attachedPID = -1;
- }
break;
}
+ case AttachRemote: {
+ AttachRemoteDialog dlg(mainWindow());
+ QStringList arches;
+ arches.append(_("i386:x86-64:intel"));
+ dlg.setRemoteArchitectures(arches);
+ dlg.setRemoteChannel(configValue(_("LastRemoteChannel")).toString());
+ dlg.setRemoteArchitecture(configValue(_("LastRemoteArchtecture")).toString());
+ if (dlg.exec() != QDialog::Accepted)
+ return false;
+ setConfigValue(_("LastRemoteChannel"), dlg.remoteChannel());
+ setConfigValue(_("LastRemoteArchitecture"), dlg.remoteArchitecture());
+ m_remoteChannel = dlg.remoteChannel();
+ m_remoteArchitecture = dlg.remoteArchitecture();
+ break;
+ }
+ }
emit debugModeRequested();
@@ -1218,7 +1246,7 @@ void DebuggerManager::setStatus(int status)
if (0 && !isAllowedTransition(m_status, status)) {
const QString msg = QString::fromLatin1("%1: UNEXPECTED TRANSITION: %2 -> %3").
- arg(QLatin1String(Q_FUNC_INFO), QLatin1String(stateName(m_status)), QLatin1String(stateName(status)));
+ arg(_(Q_FUNC_INFO), _(stateName(m_status)), _(stateName(status)));
qWarning("%s", qPrintable(msg));
}
@@ -1242,6 +1270,7 @@ void DebuggerManager::setStatus(int status)
#else
m_attachCoreAction->setEnabled(!started && !starting);
#endif
+ m_attachRemoteAction->setEnabled(!started && !starting);
m_watchAction->setEnabled(ready);
m_breakAction->setEnabled(true);
@@ -1535,7 +1564,7 @@ void DebuggerManager::showQtDumperLibraryWarning(const QString &details)
dialog.setDetailedText(details);
dialog.exec();
if (dialog.clickedButton() == qtPref) {
- Core::ICore::instance()->showOptionsDialog(QLatin1String("Qt4"), QLatin1String("Qt Versions"));
+ Core::ICore::instance()->showOptionsDialog(_("Qt4"), _("Qt Versions"));
} else if (dialog.clickedButton() == helperOff) {
theDebuggerAction(UseDebuggingHelpers)->setValue(qVariantFromValue(false), false);
}
diff --git a/src/plugins/debugger/debuggermanager.h b/src/plugins/debugger/debuggermanager.h
index 67b3e988372..f238b148ab7 100644
--- a/src/plugins/debugger/debuggermanager.h
+++ b/src/plugins/debugger/debuggermanager.h
@@ -111,7 +111,8 @@ enum DebuggerStartMode
StartInternal, // Start current start project's binary
StartExternal, // Start binary found in file system
AttachExternal, // Attach to running process
- AttachCore // Attach to a core file
+ AttachCore, // Attach to a core file
+ AttachRemote // Attach to a remote process
};
class IDebuggerEngine;
@@ -225,6 +226,7 @@ public slots:
void startExternalApplication();
void attachExternalApplication();
void attachCore();
+ void attachRemoteApplication();
void jumpToLineExec();
void runToLineExec();
@@ -358,6 +360,8 @@ public:
QString m_dumperLib;
int m_attachedPID;
bool m_useTerminal;
+ QString m_remoteChannel;
+ QString m_remoteArchitecture;
private:
void init();
@@ -404,6 +408,7 @@ private:
QAction *m_startExternalAction;
QAction *m_attachExternalAction;
QAction *m_attachCoreAction;
+ QAction *m_attachRemoteAction;
QAction *m_continueAction;
QAction *m_stopAction;
QAction *m_resetAction; // FIXME: Should not be needed in a stable release
diff --git a/src/plugins/debugger/debuggerplugin.cpp b/src/plugins/debugger/debuggerplugin.cpp
index 58df17849f7..70ccb01e598 100644
--- a/src/plugins/debugger/debuggerplugin.cpp
+++ b/src/plugins/debugger/debuggerplugin.cpp
@@ -99,6 +99,7 @@ namespace Constants {
const char * const STARTEXTERNAL = "Debugger.StartExternal";
const char * const ATTACHEXTERNAL = "Debugger.AttachExternal";
const char * const ATTACHCORE = "Debugger.AttachCore";
+const char * const ATTACHREMOTE = "Debugger.AttachRemote";
const char * const RUN_TO_LINE = "Debugger.RunToLine";
const char * const RUN_TO_FUNCTION = "Debugger.RunToFunction";
@@ -478,6 +479,15 @@ bool DebuggerPlugin::initialize(const QStringList &arguments, QString *errorMess
mdebug->addAction(cmd, Core::Constants::G_DEFAULT_ONE);
}
+ #if 0
+ // FIXME: not yet functional
+ if (m_manager->m_attachRemoteAction) {
+ cmd = am->registerAction(m_manager->m_attachRemoteAction,
+ Constants::ATTACHREMOTE, globalcontext);
+ mdebug->addAction(cmd, Core::Constants::G_DEFAULT_ONE);
+ }
+ #endif
+
cmd = am->registerAction(m_manager->m_continueAction,
ProjectExplorer::Constants::DEBUG, QList() << m_gdbRunningContext);
diff --git a/src/plugins/debugger/gdbengine.cpp b/src/plugins/debugger/gdbengine.cpp
index 54c598169ff..6085b8c0dd3 100644
--- a/src/plugins/debugger/gdbengine.cpp
+++ b/src/plugins/debugger/gdbengine.cpp
@@ -92,7 +92,14 @@ Q_DECLARE_METATYPE(Debugger::Internal::GdbMi);
#define STRINGIFY_INTERNAL(x) #x
#define STRINGIFY(x) STRINGIFY_INTERNAL(x)
-#define _c(s) QLatin1Char(s)
+struct _c
+{
+ inline _c(char c) : m_c(c) {}
+ inline operator QChar() const { return QLatin1Char(m_c); }
+ char m_c;
+};
+
+#define _c(c) QLatin1Char(c)
#define __(s) QLatin1String(s)
#define _(s) QString::fromLatin1(s)
@@ -1601,6 +1608,8 @@ bool GdbEngine::startDebugger()
if (q->startMode() == AttachCore || q->startMode() == AttachExternal) {
// nothing to do
+ } else if (q->startMode() == AttachRemote) {
+ // nothing to do
} else if (q->m_useTerminal) {
m_stubProc.stop(); // We leave the console open, so recycle it now.
@@ -1726,6 +1735,7 @@ bool GdbEngine::startDebugger()
if (q->startMode() == AttachExternal) {
sendCommand(_("attach ") + QString::number(q->m_attachedPID), GdbAttached);
+ qq->breakHandler()->removeAllBreakpoints();
} else if (q->startMode() == AttachCore) {
QFileInfo fi(q->m_executable);
QString fileName = _c('"') + fi.absoluteFilePath() + _c('"');
@@ -1733,9 +1743,17 @@ bool GdbEngine::startDebugger()
// quoting core name below fails in gdb 6.8-debian
QString coreName = fi2.absoluteFilePath();
sendCommand(_("-file-exec-and-symbols ") + fileName);
- sendCommand(_("target core ") + coreName, GdbTargetCore);
+ sendCommand(_("target core %1").arg(coreName), GdbTargetCore);
+ qq->breakHandler()->removeAllBreakpoints();
+ } else if (q->startMode() == AttachRemote) {
+ sendCommand(_("set architecture %1").arg(q->m_remoteArchitecture));
+ sendCommand(_("target remote %1").arg(q->m_remoteChannel));
+ qq->breakHandler()->setAllPending();
+ //sendCommand(_("info target"), GdbStart);
+ qq->notifyInferiorRunningRequested();
+ sendCommand(_("-exec-continue"), GdbExecContinue);
} else if (q->m_useTerminal) {
- // nothing needed, stub takes care
+ qq->breakHandler()->setAllPending();
} else if (q->startMode() == StartInternal || q->startMode() == StartExternal) {
QFileInfo fi(q->m_executable);
QString fileName = _c('"') + fi.absoluteFilePath() + _c('"');
@@ -1756,13 +1774,8 @@ bool GdbEngine::startDebugger()
qq->notifyInferiorRunningRequested();
sendCommand(_("-exec-run"));
#endif
- }
-
- // set all to "pending"
- if (q->startMode() == AttachExternal || q->startMode() == AttachCore)
- qq->breakHandler()->removeAllBreakpoints();
- else if (q->startMode() == StartInternal || q->startMode() == StartExternal)
qq->breakHandler()->setAllPending();
+ }
return true;
}
diff --git a/tests/manual/gdbdebugger/simple/app.cpp b/tests/manual/gdbdebugger/simple/app.cpp
index a5b0d0c2a6a..35376bac992 100644
--- a/tests/manual/gdbdebugger/simple/app.cpp
+++ b/tests/manual/gdbdebugger/simple/app.cpp
@@ -615,6 +615,9 @@ void testStdList()
flist.push_back(3);
flist.push_back(4);
+ foreach (Foo f, flist)
+ {}
+
std::list vec;
vec.push_back(true);
vec.push_back(false);