Commit 2fce747a authored by hjk's avatar hjk

debugger: start work "Target Communication Framework" "frontend"

parent 71a05578
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>AttachTcfDialog</class>
<widget class="QDialog" name="AttachTcfDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>310</width>
<height>224</height>
</rect>
</property>
<property name="windowTitle">
<string>Start Debugger</string>
</property>
<layout class="QVBoxLayout">
<property name="spacing">
<number>6</number>
</property>
<property name="margin">
<number>9</number>
</property>
<item>
<layout class="QFormLayout" name="formLayout">
<property name="fieldGrowthPolicy">
<enum>QFormLayout::ExpandingFieldsGrow</enum>
</property>
<item row="0" column="0">
<widget class="QLabel" name="channelLabel">
<property name="text">
<string>Host and port:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="channelLineEdit">
<property name="text">
<string>localhost:5115</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="architectureLabel">
<property name="text">
<string>Architecture:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QComboBox" name="architectureComboBox"/>
</item>
<item row="2" column="1">
<widget class="QCheckBox" name="useServerStartScriptCheckBox"/>
</item>
<item row="2" column="0">
<widget class="QLabel" name="useServerStartScriptLabel">
<property name="text">
<string>Use server start script:</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="Core::Utils::PathChooser" name="serverStartScript" native="true"/>
</item>
<item row="3" column="0">
<widget class="QLabel" name="serverStartScriptLabel">
<property name="text">
<string>Server start script:</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>Core::Utils::PathChooser</class>
<extends>QWidget</extends>
<header location="global">utils/pathchooser.h</header>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>
......@@ -41,6 +41,7 @@ HEADERS += \
stackhandler.h \
stackwindow.h \
sourcefileswindow.h \
tcfengine.h \
threadswindow.h \
watchhandler.h \
watchwindow.h \
......@@ -72,12 +73,14 @@ SOURCES += \
stackwindow.cpp \
sourcefileswindow.cpp \
threadswindow.cpp \
tcfengine.cpp \
watchhandler.cpp \
watchwindow.cpp \
gdboptionspage.cpp
FORMS += attachexternaldialog.ui \
attachcoredialog.ui \
attachtcfdialog.ui \
breakbyfunction.ui \
breakcondition.ui \
dumperoptionpage.ui \
......
......@@ -31,6 +31,7 @@
#include "ui_attachcoredialog.h"
#include "ui_attachexternaldialog.h"
#include "ui_attachtcfdialog.h"
#include "ui_startexternaldialog.h"
#include "ui_startremotedialog.h"
......@@ -300,6 +301,94 @@ void AttachExternalDialog::pidChanged(const QString &pid)
}
///////////////////////////////////////////////////////////////////////
//
// AttachTcfDialog
//
///////////////////////////////////////////////////////////////////////
AttachTcfDialog::AttachTcfDialog(QWidget *parent)
: QDialog(parent),
m_ui(new Ui::AttachTcfDialog)
{
m_ui->setupUi(this);
m_ui->buttonBox->button(QDialogButtonBox::Ok)->setDefault(true);
m_ui->serverStartScript->setExpectedKind(Core::Utils::PathChooser::File);
m_ui->serverStartScript->setPromptDialogTitle(tr("Select Executable"));
connect(m_ui->useServerStartScriptCheckBox, SIGNAL(toggled(bool)),
this, SLOT(updateState()));
connect(m_ui->buttonBox, SIGNAL(accepted()), this, SLOT(accept()));
connect(m_ui->buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
updateState();
}
AttachTcfDialog::~AttachTcfDialog()
{
delete m_ui;
}
void AttachTcfDialog::setRemoteChannel(const QString &channel)
{
m_ui->channelLineEdit->setText(channel);
}
QString AttachTcfDialog::remoteChannel() const
{
return m_ui->channelLineEdit->text();
}
void AttachTcfDialog::setRemoteArchitectures(const QStringList &list)
{
m_ui->architectureComboBox->clear();
if (!list.isEmpty()) {
m_ui->architectureComboBox->insertItems(0, list);
m_ui->architectureComboBox->setCurrentIndex(0);
}
}
void AttachTcfDialog::setRemoteArchitecture(const QString &arch)
{
int index = m_ui->architectureComboBox->findText(arch);
if (index != -1)
m_ui->architectureComboBox->setCurrentIndex(index);
}
QString AttachTcfDialog::remoteArchitecture() const
{
int index = m_ui->architectureComboBox->currentIndex();
return m_ui->architectureComboBox->itemText(index);
}
void AttachTcfDialog::setServerStartScript(const QString &scriptName)
{
m_ui->serverStartScript->setPath(scriptName);
}
QString AttachTcfDialog::serverStartScript() const
{
return m_ui->serverStartScript->path();
}
void AttachTcfDialog::setUseServerStartScript(bool on)
{
m_ui->useServerStartScriptCheckBox->setChecked(on);
}
bool AttachTcfDialog::useServerStartScript() const
{
return m_ui->useServerStartScriptCheckBox->isChecked();
}
void AttachTcfDialog::updateState()
{
bool enabled = m_ui->useServerStartScriptCheckBox->isChecked();
m_ui->serverStartScriptLabel->setEnabled(enabled);
m_ui->serverStartScript->setEnabled(enabled);
}
///////////////////////////////////////////////////////////////////////
//
// StartExternalDialog
......
......@@ -40,6 +40,7 @@ class QPushButton;
namespace Ui {
class AttachCoreDialog;
class AttachExternalDialog;
class AttachTcfDialog;
class StartExternalDialog;
class StartRemoteDialog;
} // namespace Ui
......@@ -101,6 +102,31 @@ private:
ProcessListFilterModel *m_model;
};
class AttachTcfDialog : public QDialog
{
Q_OBJECT
public:
explicit AttachTcfDialog(QWidget *parent);
~AttachTcfDialog();
void setRemoteChannel(const QString &host);
void setRemoteArchitecture(const QString &arch);
void setRemoteArchitectures(const QStringList &arches);
QString remoteChannel() const;
QString remoteArchitecture() const;
void setServerStartScript(const QString &scriptName);
QString serverStartScript() const;
void setUseServerStartScript(bool on);
bool useServerStartScript() const;
private slots:
void updateState();
private:
Ui::AttachTcfDialog *m_ui;
};
class StartExternalDialog : public QDialog
{
Q_OBJECT
......
......@@ -142,6 +142,7 @@ public:
static IDebuggerEngine *gdbEngine = 0;
static IDebuggerEngine *winEngine = 0;
static IDebuggerEngine *scriptEngine = 0;
static IDebuggerEngine *tcfEngine = 0;
// The creation functions take a list of options pages they can add to.
// This allows for having a "enabled" toggle on the page indepently
......@@ -154,6 +155,7 @@ IDebuggerEngine *createWinEngine(DebuggerManager *, bool /* cmdLineDisabled */,
{ return 0; }
#endif
IDebuggerEngine *createScriptEngine(DebuggerManager *parent, QList<Core::IOptionsPage*> *);
IDebuggerEngine *createTcfEngine(DebuggerManager *parent, QList<Core::IOptionsPage*> *);
DebuggerManager::DebuggerManager()
{
......@@ -165,6 +167,7 @@ DebuggerManager::~DebuggerManager()
delete gdbEngine;
delete winEngine;
delete scriptEngine;
delete tcfEngine;
}
void DebuggerManager::init()
......@@ -435,6 +438,7 @@ QList<Core::IOptionsPage*> DebuggerManager::initializeEngines(const QStringList
const bool cdbDisabled = arguments.contains(_("-disable-cdb"));
winEngine = createWinEngine(this, cdbDisabled, &rc);
scriptEngine = createScriptEngine(this, &rc);
tcfEngine = createTcfEngine(this, &rc);
setDebuggerType(NoDebugger);
if (Debugger::Constants::Internal::debug)
qDebug() << Q_FUNC_INFO << gdbEngine << winEngine << scriptEngine << rc.size();
......@@ -453,6 +457,9 @@ void DebuggerManager::setDebuggerType(DebuggerType type)
case WinDebugger:
m_engine = winEngine;
break;
case TcfDebugger:
m_engine = tcfEngine;
break;
case NoDebugger:
m_engine = 0;
}
......@@ -791,50 +798,43 @@ void DebuggerManager::setConfigValue(const QString &name, const QVariant &value)
}
// Figure out the debugger type of an executable
static bool determineDebuggerType(const QString &executable,
DebuggerManager::DebuggerType *dt,
static DebuggerManager::DebuggerType determineDebuggerType(const QString &executable,
QString *errorMessage)
{
if (executable.endsWith(_(".js"))) {
*dt = DebuggerManager::ScriptDebugger;
return true;
}
if (executable.endsWith(_(".js")))
return DebuggerManager::ScriptDebugger;
#ifndef Q_OS_WIN
*dt = DebuggerManager::GdbDebugger;
Q_UNUSED(errorMessage)
return true;
return DebuggerManager::GdbDebugger;
#else
// If a file has PDB files, it has been compiled by VS.
QStringList pdbFiles;
if (!getPDBFiles(executable, &pdbFiles, errorMessage))
return false;
if (pdbFiles.empty()) {
*dt = DebuggerManager::GdbDebugger;
return true;
}
return DebuggerManager::NoDebugger;
if (pdbFiles.empty())
return DebuggerManager::GdbDebugger;
// We need the CDB debugger in order to be able to debug VS
// executables
if (!winEngine) {
*errorMessage = DebuggerManager::tr("Debugging VS executables is not supported.");
return false;
return DebuggerManager::NoDebugger;
}
*dt = DebuggerManager::WinDebugger;
return true;
return DebuggerManager::WinDebugger;
#endif
}
// Figure out the debugger type of a PID
static bool determineDebuggerType(int /* pid */,
DebuggerManager::DebuggerType *dt,
static DebuggerManager::DebuggerType determineDebuggerType(int /* pid */,
QString * /*errorMessage*/)
{
#ifdef Q_OS_WIN
// Preferably Windows debugger
*dt = winEngine ? DebuggerManager::WinDebugger : DebuggerManager::GdbDebugger;
return winEngine ? DebuggerManager::WinDebugger : DebuggerManager::GdbDebugger;
#else
*dt = DebuggerManager::GdbDebugger;
return DebuggerManager::GdbDebugger;
#endif
return true;
}
void DebuggerManager::startNewDebugger(DebuggerRunControl *runControl)
......@@ -939,10 +939,14 @@ void DebuggerManager::startNewDebugger(DebuggerRunControl *runControl)
QStringList arches;
arches.append(_("i386:x86-64:intel"));
dlg.setRemoteArchitectures(arches);
dlg.setRemoteChannel(configValue(_("LastRemoteChannel")).toString());
dlg.setRemoteArchitecture(configValue(_("LastRemoteArchtecture")).toString());
dlg.setServerStartScript(configValue(_("LastServerStartScript")).toString());
dlg.setUseServerStartScript(configValue(_("LastUseServerStartScript")).toBool());
dlg.setRemoteChannel(
configValue(_("LastRemoteChannel")).toString());
dlg.setRemoteArchitecture(
configValue(_("LastRemoteArchitecture")).toString());
dlg.setServerStartScript(
configValue(_("LastServerStartScript")).toString());
dlg.setUseServerStartScript(
configValue(_("LastUseServerStartScript")).toBool());
if (dlg.exec() != QDialog::Accepted) {
runControl->debuggingFinished();
return;
......@@ -958,16 +962,48 @@ void DebuggerManager::startNewDebugger(DebuggerRunControl *runControl)
m_serverStartScript.clear();
break;
}
case AttachTcf: {
AttachTcfDialog dlg(mainWindow());
QStringList arches;
arches.append(_("i386:x86-64:intel"));
dlg.setRemoteArchitectures(arches);
dlg.setRemoteChannel(
configValue(_("LastTcfRemoteChannel")).toString());
dlg.setRemoteArchitecture(
configValue(_("LastTcfRemoteArchitecture")).toString());
dlg.setServerStartScript(
configValue(_("LastTcfServerStartScript")).toString());
dlg.setUseServerStartScript(
configValue(_("LastTcfUseServerStartScript")).toBool());
if (dlg.exec() != QDialog::Accepted) {
runControl->debuggingFinished();
return;
}
setConfigValue(_("LastTcfRemoteChannel"), dlg.remoteChannel());
setConfigValue(_("LastTcfRemoteArchitecture"), dlg.remoteArchitecture());
setConfigValue(_("LastTcfServerStartScript"), dlg.serverStartScript());
setConfigValue(_("LastTcfUseServerStartScript"), dlg.useServerStartScript());
m_remoteChannel = dlg.remoteChannel();
m_remoteArchitecture = dlg.remoteArchitecture();
m_serverStartScript = dlg.serverStartScript();
if (!dlg.useServerStartScript())
m_serverStartScript.clear();
break;
}
}
emit debugModeRequested();
DebuggerType type;
DebuggerType type = NoDebugger;
QString errorMessage;
const bool hasDebugger = startMode() == AttachExternal
? determineDebuggerType(m_attachedPID, &type, &errorMessage)
: determineDebuggerType(m_executable, &type, &errorMessage);
if (!hasDebugger) {
if (startMode() == AttachExternal)
type = determineDebuggerType(m_attachedPID, &errorMessage);
else if (startMode() == AttachTcf)
type = TcfDebugger;
else
type = determineDebuggerType(m_executable, &errorMessage);
if (type == NoDebugger) {
QMessageBox::warning(mainWindow(), tr("Warning"),
tr("Cannot debug '%1': %2").arg(m_executable, errorMessage));
debuggingFinished();
......
......@@ -109,11 +109,12 @@ enum DebuggerStatus
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
StartRemote // Start and attach to a remote process
StartInternal, // Start current start project's binary
StartExternal, // Start binary found in file system
AttachExternal, // Attach to running process
AttachTcf, // Attach to a running Target Communication Framework agent
AttachCore, // Attach to a core file
StartRemote // Start and attach to a remote process
};
class IDebuggerEngine;
......@@ -142,13 +143,14 @@ public:
private:
// This is the part of the interface that's exclusively seen by the
// debugger engines
friend class GdbEngine;
friend class CdbDebugEngine;
friend class CdbDebugEventCallback;
friend class ScriptEngine;
friend struct CdbDebugEnginePrivate;
friend class CdbDumperHelper;
friend class CdbExceptionLoggerEventCallback;
friend class GdbEngine;
friend class ScriptEngine;
friend class TcfEngine;
friend struct CdbDebugEnginePrivate;
// called from the engines after successful startup
virtual void notifyInferiorStopRequested() = 0;
......@@ -202,7 +204,9 @@ public:
QMainWindow *mainWindow() const { return m_mainWindow; }
QLabel *statusLabel() const { return m_statusLabel; }
enum DebuggerType { NoDebugger, GdbDebugger, ScriptDebugger, WinDebugger };
enum DebuggerType {
NoDebugger, GdbDebugger, ScriptDebugger, WinDebugger, TcfDebugger
};
public slots:
void startNewDebugger(DebuggerRunControl *runControl);
......
......@@ -1109,6 +1109,14 @@ void DebuggerPlugin::startRemoteApplication()
runControl->start();
}
void DebuggerPlugin::attachRemoteTcf()
{
QSharedPointer<RunConfiguration> rc = activeRunConfiguration();
if (RunControl *runControl = m_debuggerRunner
->run(rc, ProjectExplorer::Constants::DEBUGMODE, AttachTcf))
runControl->start();
}
void DebuggerPlugin::updateActions(int status)
{
const bool started = status == DebuggerInferiorRunning
......
......@@ -103,6 +103,7 @@ private slots:
void startRemoteApplication();
void attachExternalApplication();
void attachCore();
void attachRemoteTcf();
private:
void readSettings();
......
......@@ -39,8 +39,6 @@
#include <QtCore/QSet>
#include <QtCore/QVariant>
#include <QtNetwork/QLocalSocket>
QT_BEGIN_NAMESPACE
class QAction;
class QAbstractItemModel;
......
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Qt Software Information (qt-info@nokia.com)
**
** Commercial Usage
**
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** 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.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at qt-sales@nokia.com.
**
**************************************************************************/
#include "tcfengine.h"
#include "debuggerdialogs.h"
#include "breakhandler.h"
#include "debuggerconstants.h"
#include "debuggermanager.h"
#include "disassemblerhandler.h"
#include "moduleshandler.h"
#include "registerhandler.h"
#include "stackhandler.h"
#include "watchhandler.h"
#include "watchutils.h"
#include "moduleshandler.h"
#include <utils/qtcassert.h>
#include <QtCore/QDateTime>
#include <QtCore/QDebug>
#include <QtCore/QDir>
#include <QtCore/QFileInfo>
#include <QtCore/QTimer>
#include <QtGui/QAction>
#include <QtGui/QApplication>
#include <QtGui/QToolTip>
using namespace Debugger;
using namespace Debugger::Internal;
using namespace Debugger::Constants;
//#define DEBUG_TCF 1
#if DEBUG_TCF
# define SDEBUG(s) qDebug() << s
#else
# define SDEBUG(s)
#endif
# define XSDEBUG(s) qDebug() << s
///////////////////////////////////////////////////////////////////////
//
// TcfEngine
//
///////////////////////////////////////////////////////////////////////
TcfEngine::TcfEngine(DebuggerManager *parent)
{
q = parent;
qq = parent->engineInterface();
}
TcfEngine::~TcfEngine()
{
}
void TcfEngine::executeDebuggerCommand(const QString &command)
{
Q_UNUSED(command);
XSDEBUG("FIXME: TcfEngine::executeDebuggerCommand()");
}
void TcfEngine::shutdown()