debugger: The DebuggerEngine refactoring.

This replaces the (de facto) singleton engines and data handlers by classes
that are instantiated per run. The DebuggerRunControl will now create an
object of (a class derived from) DebuggerEngine that contains all the relevant
"dynamic" data.

DebuggerManager is no more. The "singleton" bits are merged into DebuggerPlugin,
whereas the data bits went to DebuggerEngine.

There is no formal notion of a "current" DebuggerEngine. However, as there's
only one DebuggerEngine at a time that has its data models connected to the
view, there's still some "de facto" notion of a "current" engine. Calling
SomeModel::setData(int role, QVariant data) with custom role is used as the
primary dispatch mechanism from the views to the "current" data models
(and the engine, as all data models know their engine).
This commit is contained in:
hjk
2010-06-16 11:08:54 +02:00
parent 4cc244469a
commit 6a6cba5518
93 changed files with 5258 additions and 4846 deletions
+2 -2
View File
@@ -942,7 +942,7 @@ class Dumper:
pass
except:
# Locals with failing memory access.
with SubItem(d):
with SubItem(self):
self.put('iname="%s",' % item.iname)
self.put('name="%s",' % item.name)
self.put('addr="<not accessible>",')
@@ -963,7 +963,7 @@ class Dumper:
p += 1
n += 1
with SubItem(d):
with SubItem(self):
self.put('iname="%s",' % item.iname)
self.putName(item.name)
self.putItemCount(select(n <= 100, n, "> 100"))
+250 -103
View File
@@ -30,8 +30,11 @@
#include "breakhandler.h"
#include "debuggeractions.h"
#include "debuggermanager.h"
#include "debuggerengine.h"
#include "debuggerplugin.h"
#include "debuggerstringutils.h"
#include "threadshandler.h"
#include "stackhandler.h"
#include "stackframe.h"
#include <texteditor/basetextmark.h>
@@ -42,9 +45,6 @@
#include <QtCore/QTextStream>
#include <QtCore/QFileInfo>
using namespace Debugger;
using namespace Debugger::Internal;
//////////////////////////////////////////////////////////////////
//
@@ -65,6 +65,8 @@ static inline bool fileNameMatch(const QString &f1, const QString &f2)
namespace Debugger {
namespace Internal {
static DebuggerPlugin *plugin() { return DebuggerPlugin::instance(); }
// The red blob on the left side in the cpp editor.
class BreakpointMarker : public TextEditor::BaseTextMark
{
@@ -137,7 +139,7 @@ public:
}
// Ignore updates to the "real" line number while the debugger is
// running, as this can be triggered by moving the breakpoint to
// the next line that generated code.
// the next line that generated code.
// FIXME: Do we need yet another data member?
if (m_data->bpNumber.trimmed().isEmpty()) {
m_data->lineNumber = QByteArray::number(lineNumber);
@@ -151,10 +153,6 @@ private:
bool m_enabled;
};
} // namespace Internal
} // namespace Debugger
//////////////////////////////////////////////////////////////////
//
@@ -175,6 +173,27 @@ BreakpointData::BreakpointData()
useFullPath = false;
}
BreakpointData::BreakpointData(const BreakpointData &other)
{
//qDebug() << "COPYING BREAKPOINT " << other.toString();
pending = true;
marker = 0;
m_handler = other.m_handler;
m_markerFileName = other.m_markerFileName;
m_markerLineNumber = other.m_markerLineNumber;
enabled = other.enabled;
type = other.type;
fileName = other.fileName;
condition = other.condition;
ignoreCount = other.ignoreCount;
lineNumber = other.lineNumber;
address = other.address;
threadSpec = other.threadSpec;
funcName = other.funcName;
useFullPath = other.useFullPath;
}
BreakpointData::~BreakpointData()
{
removeMarker();
@@ -223,7 +242,7 @@ QString BreakpointData::toToolTip() const
<< "</td><td>" << bpNumber << "</td></tr>"
<< "<tr><td>" << BreakHandler::tr("Breakpoint Type:")
<< "</td><td>"
<< (type == BreakpointType ? BreakHandler::tr("Breakpoint")
<< (type == BreakpointType ? BreakHandler::tr("Breakpoint")
: type == WatchpointType ? BreakHandler::tr("Watchpoint")
: BreakHandler::tr("Unknown breakpoint type"))
<< "</td></tr>"
@@ -261,7 +280,7 @@ QString BreakpointData::toString() const
<< BreakHandler::tr("Marker Line:") << ' ' << m_markerLineNumber << '\n'
<< BreakHandler::tr("Breakpoint Number:") << ' ' << bpNumber << '\n'
<< BreakHandler::tr("Breakpoint Type:") << ' '
<< (type == BreakpointType ? BreakHandler::tr("Breakpoint")
<< (type == BreakpointType ? BreakHandler::tr("Breakpoint")
: type == WatchpointType ? BreakHandler::tr("Watchpoint")
: BreakHandler::tr("Unknown breakpoint type")) << '\n'
<< BreakHandler::tr("File Name:") << ' '
@@ -296,6 +315,43 @@ bool BreakpointData::isLocatedAt(const QString &fileName_, int lineNumber_) cons
&& fileNameMatch(fileName_, m_markerFileName);
}
bool BreakpointData::isSimilarTo(const BreakpointData *needle) const
{
//qDebug() << "COMPARING " << toString() << " WITH " << needle->toString();
// Clear hit.
if (bpNumber == needle->bpNumber
&& !bpNumber.isEmpty()
&& bpNumber.toInt() != 0)
return true;
// Clear miss.
if (type != needle->type)
return false;
// We have numbers, but they are different.
if (!bpNumber.isEmpty() && !needle->bpNumber.isEmpty()
&& !bpNumber.startsWith(needle->bpNumber)
&& !needle->bpNumber.startsWith(bpNumber))
return false;
// At least at a position we were looking for.
// FIXME: breaks multiple breakpoints at the same location
if (!fileName.isEmpty()
&& fileNameMatch(fileName, needle->fileName)
&& lineNumber == needle->lineNumber)
return true;
// At least at a position we were looking for.
// FIXME: breaks multiple breakpoints at the same location
if (!fileName.isEmpty()
&& fileNameMatch(fileName, needle->bpFileName)
&& lineNumber == needle->bpLineNumber)
return true;
return false;
}
bool BreakpointData::conditionsMatch() const
{
// Some versions of gdb "beautify" the passed condition.
@@ -313,15 +369,15 @@ bool BreakpointData::conditionsMatch() const
//
//////////////////////////////////////////////////////////////////
BreakHandler::BreakHandler(DebuggerManager *manager, QObject *parent) :
QAbstractTableModel(parent),
m_breakpointIcon(_(":/debugger/images/breakpoint_16.png")),
BreakHandler::BreakHandler(DebuggerEngine *engine)
: m_breakpointIcon(_(":/debugger/images/breakpoint_16.png")),
m_disabledBreakpointIcon(_(":/debugger/images/breakpoint_disabled_16.png")),
m_pendingBreakPointIcon(_(":/debugger/images/breakpoint_pending_16.png")),
m_watchpointIcon(_(":/debugger/images/watchpoint.png")),
m_manager(manager)
{
}
m_engine(engine), // Possibly 0 for the dummy engine "handling" session data.
m_lastFound(0),
m_lastFoundQueried(false)
{}
BreakHandler::~BreakHandler()
{
@@ -369,29 +425,12 @@ void BreakHandler::clear()
m_inserted.clear();
}
BreakpointData *BreakHandler::findSimilarBreakpoint(const BreakpointData &needle) const
BreakpointData *BreakHandler::findSimilarBreakpoint(const BreakpointData *needle) const
{
// Search a breakpoint we might refer to.
for (int index = 0; index != size(); ++index) {
BreakpointData *data = m_bp[index];
// Clear hit.
if (data->bpNumber == needle.bpNumber
&& !data->bpNumber.isEmpty()
&& data->bpNumber.toInt() != 0)
return data;
// Clear miss.
if (data->type != needle.type)
continue;
// We have numbers, but they are different.
if (!data->bpNumber.isEmpty() && !needle.bpNumber.isEmpty()
&& !data->bpNumber.startsWith(needle.bpNumber)
&& !needle.bpNumber.startsWith(data->bpNumber))
continue;
// At least at a position we were looking for.
// FIXME: breaks multiple breakpoints at the same location
if (!data->fileName.isEmpty()
&& fileNameMatch(data->fileName, needle.bpFileName)
&& data->lineNumber == needle.bpLineNumber)
if (data->isSimilarTo(needle))
return data;
}
return 0;
@@ -426,6 +465,8 @@ bool BreakHandler::watchPointAt(quint64 address) const
void BreakHandler::saveBreakpoints()
{
//qDebug() << "SAVING BREAKPOINTS...";
QTC_ASSERT(plugin(), return);
QList<QVariant> list;
for (int index = 0; index != size(); ++index) {
const BreakpointData *data = at(index);
@@ -455,12 +496,15 @@ void BreakHandler::saveBreakpoints()
map.insert(_("usefullpath"), _("1"));
list.append(map);
}
m_manager->setSessionValue("Breakpoints", list);
plugin()->setSessionValue("Breakpoints", list);
//qDebug() << "SAVED BREAKPOINTS" << this << list.size();
}
void BreakHandler::loadBreakpoints()
{
QVariant value = m_manager->sessionValue("Breakpoints");
QTC_ASSERT(plugin(), return);
//qDebug() << "LOADING BREAKPOINTS...";
QVariant value = plugin()->sessionValue("Breakpoints");
QList<QVariant> list = value.toList();
clear();
foreach (const QVariant &var, list) {
@@ -500,6 +544,7 @@ void BreakHandler::loadBreakpoints()
data->setMarkerLineNumber(data->lineNumber.toInt());
append(data);
}
//qDebug() << "LOADED BREAKPOINTS" << this << list.size();
}
void BreakHandler::resetBreakpoints()
@@ -554,20 +599,56 @@ QVariant BreakHandler::data(const QModelIndex &mi, int role) const
{
static const QString empty = QString(QLatin1Char('-'));
QTC_ASSERT(mi.isValid(), return QVariant());
switch (role) {
case RequestFindSimilarBreakpointRole: {
// Complain if data/setData are not used alternately.
QTC_ASSERT(m_lastFoundQueried, return false);
QVariant value = QVariant::fromValue(m_lastFound);
m_lastFoundQueried = false;
m_lastFound = 0; // Reset for "safety".
return value;
}
case CurrentThreadIdRole:
QTC_ASSERT(m_engine, return QVariant());
return m_engine->threadsHandler()->currentThreadId();
case EngineActionsEnabledRole:
QTC_ASSERT(m_engine, return QVariant());
return m_engine->debuggerActionsEnabled();
case EngineCapabilitiesRole:
QTC_ASSERT(m_engine, return QVariant());
return m_engine->debuggerCapabilities();
default:
break;
}
QTC_ASSERT(mi.isValid(), return QVariant());
if (mi.row() >= size())
return QVariant();
const BreakpointData *data = at(mi.row());
if (role == BreakpointUseFullPathRole)
return data->useFullPath;
if (role == BreakpointFileNameRole)
return data->fileName;
if (role == BreakpointEnabledRole)
return data->enabled;
if (role == BreakpointFunctionNameRole)
return data->funcName;
switch (mi.column()) {
case 0:
if (role == Qt::DisplayRole) {
const QString str = data->bpNumber;
return str.isEmpty() ? empty : str;
}
if (role == Qt::UserRole)
return data->enabled;
if (role == Qt::DecorationRole) {
if (data->type == BreakpointData::WatchpointType)
return m_watchpointIcon;
@@ -581,8 +662,6 @@ QVariant BreakHandler::data(const QModelIndex &mi, int role) const
const QString str = data->pending ? data->funcName : data->bpFuncName;
return str.isEmpty() ? empty : str;
}
if (role == Qt::UserRole + 1)
return data->funcName;
break;
case 2:
if (role == Qt::DisplayRole) {
@@ -596,10 +675,6 @@ QVariant BreakHandler::data(const QModelIndex &mi, int role) const
str = "/.../" + str;
return str;
}
if (role == Qt::UserRole)
return data->useFullPath;
if (role == Qt::UserRole + 1)
return data->fileName;
break;
case 3:
if (role == Qt::DisplayRole) {
@@ -645,7 +720,7 @@ QVariant BreakHandler::data(const QModelIndex &mi, int role) const
if (data->type == BreakpointData::WatchpointType)
return data->address;
return data->bpAddress;
}
}
break;
}
if (role == Qt::ToolTipRole)
@@ -654,92 +729,151 @@ QVariant BreakHandler::data(const QModelIndex &mi, int role) const
return QVariant();
}
Qt::ItemFlags BreakHandler::flags(const QModelIndex &mi) const
Qt::ItemFlags BreakHandler::flags(const QModelIndex &index) const
{
switch (mi.column()) {
switch (index.column()) {
//case 0:
// return Qt::ItemIsUserCheckable | Qt::ItemIsEnabled;
default:
return QAbstractTableModel::flags(mi);
return QAbstractTableModel::flags(index);
}
}
bool BreakHandler::setData(const QModelIndex &mi, const QVariant &value, int role)
bool BreakHandler::setData(const QModelIndex &index, const QVariant &value, int role)
{
BreakpointData *data = at(mi.row());
if (role == Qt::UserRole + 1) {
if (data->enabled != value.toBool()) {
toggleBreakpointEnabled(data);
layoutChanged();
switch (role) {
case RequestFindSimilarBreakpointRole: {
// Complain if data/setData are not used alternately.
QTC_ASSERT(!m_lastFoundQueried, return false);
BreakpointData *needle = value.value<BreakpointData *>();
QTC_ASSERT(needle, return false);
m_lastFound = findSimilarBreakpoint(needle);
m_lastFoundQueried = true;
return true;
}
return true;
case RequestActivateBreakpointRole: {
const BreakpointData *data = at(value.toInt());
QTC_ASSERT(data, return false);
m_engine->gotoLocation(data->markerFileName(),
data->markerLineNumber(), false);
return true;
}
case RequestRemoveBreakpointByIndexRole: {
BreakpointData *data = at(value.toInt());
QTC_ASSERT(data, return false);
removeBreakpoint(data);
return true;
}
case RequestRemoveBreakpointRole: {
BreakpointData *data = value.value<BreakpointData *>();
QTC_ASSERT(data, return false);
removeBreakpoint(data);
return true;
}
case RequestAppendBreakpointRole: {
BreakpointData *data = value.value<BreakpointData *>();
QTC_ASSERT(data, return false);
appendBreakpoint(data);
if (m_engine)
m_engine->attemptBreakpointSynchronization();
return true;
}
case RequestUpdateBreakpointRole: {
BreakpointData *data = value.value<BreakpointData *>();
QTC_ASSERT(data, return false);
if (m_engine)
m_engine->attemptBreakpointSynchronization();
return true;
}
case RequestSynchronizeBreakpointsRole:
QTC_ASSERT(m_engine, return false);
m_engine->attemptBreakpointSynchronization();
return true;
case RequestBreakByFunctionRole:
QTC_ASSERT(m_engine, return false);
m_engine->breakByFunction(value.toString());
return true;
case RequestBreakByFunctionMainRole:
QTC_ASSERT(m_engine, return false);
m_engine->breakByFunctionMain();
return true;
}
if (role == Qt::UserRole + 2) {
if (data->useFullPath != value.toBool()) {
data->useFullPath = value.toBool();
layoutChanged();
}
return true;
}
BreakpointData *data = at(index.row());
//if (role != Qt::EditRole)
// return false;
switch (role) {
case BreakpointEnabledRole:
if (data->enabled != value.toBool()) {
toggleBreakpointEnabled(data);
layoutChanged();
}
return true;
switch (mi.column()) {
case 1: {
case BreakpointUseFullPathRole:
if (data->useFullPath != value.toBool()) {
data->useFullPath = value.toBool();
layoutChanged();
}
return true;
/*
QString val = value.toString();
if (data->funcName != val) {
data->funcName = val;
layoutChanged();
}
return true;
}
case 2: {
QString val = value.toString();
if (data->fileName != val) {
data->fileName = val;
layoutChanged();
}
return true;
}
case 3: {
QByteArray val = value.toString().toLatin1();
if (data->lineNumber != val) {
data->lineNumber = val;
layoutChanged();
}
return true;
}
case 4: {
QByteArray val = value.toString().toLatin1();
if (val != data->condition) {
data->condition = val;
layoutChanged();
*/
case BreakpointConditionRole: {
QByteArray val = value.toString().toLatin1();
if (val != data->condition) {
data->condition = val;
layoutChanged();
}
}
return true;
}
case 5: {
QByteArray val = value.toString().toLatin1();
if (val != data->ignoreCount) {
data->ignoreCount = val;
layoutChanged();
case BreakpointIgnoreCountRole: {
QByteArray val = value.toString().toLatin1();
if (val != data->ignoreCount) {
data->ignoreCount = val;
layoutChanged();
}
}
return true;
}
case 6: {
QByteArray val = value.toString().toLatin1();
if (val != data->threadSpec) {
data->threadSpec = val;
layoutChanged();
case BreakpointThreadSpecRole: {
QByteArray val = value.toString().toLatin1();
if (val != data->threadSpec) {
data->threadSpec = val;
layoutChanged();
}
}
return true;
}
default: {
return false;
}
}
return false;
}
void BreakHandler::append(BreakpointData *data)
@@ -749,7 +883,7 @@ void BreakHandler::append(BreakpointData *data)
m_inserted.append(data);
}
QList<BreakpointData *> BreakHandler::insertedBreakpoints() const
Breakpoints BreakHandler::insertedBreakpoints() const
{
return m_inserted;
}
@@ -759,23 +893,23 @@ void BreakHandler::takeInsertedBreakPoint(BreakpointData *d)
m_inserted.removeAll(d);
}
QList<BreakpointData *> BreakHandler::takeRemovedBreakpoints()
Breakpoints BreakHandler::takeRemovedBreakpoints()
{
QList<BreakpointData *> result = m_removed;
Breakpoints result = m_removed;
m_removed.clear();
return result;
}
QList<BreakpointData *> BreakHandler::takeEnabledBreakpoints()
Breakpoints BreakHandler::takeEnabledBreakpoints()
{
QList<BreakpointData *> result = m_enabled;
Breakpoints result = m_enabled;
m_enabled.clear();
return result;
}
QList<BreakpointData *> BreakHandler::takeDisabledBreakpoints()
Breakpoints BreakHandler::takeDisabledBreakpoints()
{
QList<BreakpointData *> result = m_disabled;
Breakpoints result = m_disabled;
m_disabled.clear();
return result;
}
@@ -838,11 +972,14 @@ void BreakHandler::removeAllBreakpoints()
void BreakHandler::setAllPending()
{
QTC_ASSERT(false, /*ABC*/ return);
/*
loadBreakpoints();
for (int index = size(); --index >= 0;)
at(index)->pending = true;
saveBreakpoints();
updateMarkers();
*/
}
void BreakHandler::saveSessionData()
@@ -876,4 +1013,14 @@ void BreakHandler::breakByFunction(const QString &functionName)
updateMarkers();
}
void BreakHandler::initializeFromTemplate(BreakHandler *other)
{
//qDebug() << "COPYING BREAKPOINTS INTO NEW SESSION";
m_bp = other->m_bp;
updateMarkers();
}
} // namespace Internal
} // namespace Debugger
#include "breakhandler.moc"
+22 -14
View File
@@ -39,6 +39,8 @@
namespace Debugger {
namespace Internal {
class DebuggerEngine;
//////////////////////////////////////////////////////////////////
//
// BreakHandler
@@ -50,7 +52,7 @@ class BreakHandler : public QAbstractTableModel
Q_OBJECT
public:
explicit BreakHandler(DebuggerManager *manager, QObject *parent = 0);
explicit BreakHandler(DebuggerEngine *engine);
~BreakHandler();
void removeAllBreakpoints();
@@ -67,23 +69,25 @@ public:
void removeAt(int index); // This also deletes the marker.
void clear(); // This also deletes all the marker.
int indexOf(BreakpointData *data) { return m_bp.indexOf(data); }
// Find a breakpoint matching approximately the data in needle.bp*,
BreakpointData *findSimilarBreakpoint(const BreakpointData &needle) const;
// Find a breakpoint matching approximately the data in needle.
BreakpointData *findSimilarBreakpoint(const BreakpointData *needle) const;
BreakpointData *findBreakpointByNumber(int bpNumber) const;
int findWatchPointIndexByAddress(const QByteArray &a) const;
bool watchPointAt(quint64 address) const;
void updateMarkers();
QList<BreakpointData *> insertedBreakpoints() const;
Breakpoints insertedBreakpoints() const;
void takeInsertedBreakPoint(BreakpointData *);
QList<BreakpointData *> takeRemovedBreakpoints(); // Owned.
QList<BreakpointData *> takeEnabledBreakpoints(); // Not owned.
QList<BreakpointData *> takeDisabledBreakpoints(); // Not owned.
Breakpoints takeRemovedBreakpoints(); // Owned.
Breakpoints takeEnabledBreakpoints(); // Not owned.
Breakpoints takeDisabledBreakpoints(); // Not owned.
QIcon breakpointIcon() const { return m_breakpointIcon; }
QIcon disabledBreakpointIcon() const { return m_disabledBreakpointIcon; }
QIcon pendingBreakPointIcon() const { return m_pendingBreakPointIcon; }
void initializeFromTemplate(BreakHandler *other);
public slots:
void appendBreakpoint(BreakpointData *data);
void toggleBreakpointEnabled(BreakpointData *data);
@@ -98,7 +102,7 @@ private:
int columnCount(const QModelIndex &parent) const;
int rowCount(const QModelIndex &parent) const;
QVariant data(const QModelIndex &index, int role) const;
bool setData(const QModelIndex &index, const QVariant &, int role);
bool setData(const QModelIndex &index, const QVariant &value, int role);
QVariant headerData(int section, Qt::Orientation orientation, int role) const;
Qt::ItemFlags flags(const QModelIndex &index) const;
@@ -113,12 +117,16 @@ private:
const QIcon m_pendingBreakPointIcon;
const QIcon m_watchpointIcon;
DebuggerManager *m_manager; // Not owned.
QList<BreakpointData *> m_bp;
QList<BreakpointData *> m_inserted; // Lately inserted breakpoints.
QList<BreakpointData *> m_removed; // Lately removed breakpoints.
QList<BreakpointData *> m_enabled; // Lately enabled breakpoints.
QList<BreakpointData *> m_disabled; // Lately disabled breakpoints.
DebuggerEngine *m_engine; // Not owned.
Breakpoints m_bp;
Breakpoints m_inserted; // Lately inserted breakpoints.
Breakpoints m_removed; // Lately removed breakpoints.
Breakpoints m_enabled; // Lately enabled breakpoints.
Breakpoints m_disabled; // Lately disabled breakpoints.
// Hack for BreakWindow::findSimilarBreakpoint
mutable BreakpointData *m_lastFound;
mutable bool m_lastFoundQueried;
};
} // namespace Internal
+10 -1
View File
@@ -30,6 +30,8 @@
#ifndef DEBUGGER_BREAKPOINT_H
#define DEBUGGER_BREAKPOINT_H
#include <QtCore/QMetaType>
#include <QtCore/QList>
#include <QtCore/QString>
namespace Debugger {
@@ -58,13 +60,17 @@ public:
BreakHandler *handler() { return m_handler; }
bool isLocatedAt(const QString &fileName, int lineNumber) const;
bool isSimilarTo(const BreakpointData *needle) const;
bool conditionsMatch() const;
protected:
// This copies only the static data.
BreakpointData(const BreakpointData &);
private:
// Intentionally unimplemented.
// Making it copyable is tricky because of the markers.
void operator=(const BreakpointData &);
BreakpointData(const BreakpointData &);
// Our owner
BreakHandler *m_handler; // Not owned.
@@ -116,8 +122,11 @@ private:
BreakpointMarker *marker;
};
typedef QList<BreakpointData *> Breakpoints;
} // namespace Internal
} // namespace Debugger
Q_DECLARE_METATYPE(Debugger::Internal::BreakpointData *);
#endif // DEBUGGER_BREAKPOINT_H
+91 -59
View File
@@ -29,11 +29,8 @@
#include "breakwindow.h"
#include "breakhandler.h"
#include "threadshandler.h"
#include "debuggeractions.h"
#include "debuggermanager.h"
#include "stackhandler.h"
#include "debuggerconstants.h"
#include "ui_breakcondition.h"
#include "ui_breakbyfunction.h"
@@ -41,9 +38,6 @@
#include <utils/savedaction.h>
#include <QtCore/QDebug>
#include <QtCore/QDir>
#include <QtCore/QFileInfo>
#include <QtCore/QFileInfoList>
#include <QtGui/QAction>
#include <QtGui/QHeaderView>
@@ -54,8 +48,9 @@
#include <QtGui/QToolButton>
#include <QtGui/QTreeView>
using Debugger::Internal::BreakWindow;
namespace Debugger {
namespace Internal {
///////////////////////////////////////////////////////////////////////
//
@@ -83,9 +78,11 @@ public:
//
///////////////////////////////////////////////////////////////////////
BreakWindow::BreakWindow(Debugger::DebuggerManager *manager)
: m_manager(manager), m_alwaysResizeColumnsToContents(false)
BreakWindow::BreakWindow(QWidget *parent)
: QTreeView(parent)
{
m_alwaysResizeColumnsToContents = false;
QAction *act = theDebuggerAction(UseAlternatingRowColors);
setFrameStyle(QFrame::NoFrame);
setAttribute(Qt::WA_MacShowFocusRect, false);
@@ -104,6 +101,10 @@ BreakWindow::BreakWindow(Debugger::DebuggerManager *manager)
this, SLOT(showAddressColumn(bool)));
}
BreakWindow::~BreakWindow()
{
}
void BreakWindow::showAddressColumn(bool on)
{
setColumnHidden(7, !on);
@@ -112,9 +113,9 @@ void BreakWindow::showAddressColumn(bool on)
static QModelIndexList normalizeIndexes(const QModelIndexList &list)
{
QModelIndexList res;
foreach (const QModelIndex &idx, list)
if (idx.column() == 0)
res.append(idx);
foreach (const QModelIndex &index, list)
if (index.column() == 0)
res.append(index);
return res;
}
@@ -147,7 +148,6 @@ void BreakWindow::mouseDoubleClickEvent(QMouseEvent *ev)
void BreakWindow::contextMenuEvent(QContextMenuEvent *ev)
{
QMenu menu;
const QAbstractItemModel *itemModel = model();
QItemSelectionModel *sm = selectionModel();
QTC_ASSERT(sm, return);
QModelIndexList si = sm->selectedIndexes();
@@ -156,8 +156,9 @@ void BreakWindow::contextMenuEvent(QContextMenuEvent *ev)
si.append(indexUnderMouse.sibling(indexUnderMouse.row(), 0));
si = normalizeIndexes(si);
const int rowCount = itemModel->rowCount();
const unsigned engineCapabilities = m_manager->debuggerCapabilities();
const int rowCount = model()->rowCount();
const unsigned engineCapabilities =
model()->data(QModelIndex(), EngineCapabilitiesRole).toUInt();
QAction *deleteAction = new QAction(tr("Delete Breakpoint"), &menu);
deleteAction->setEnabled(si.size() > 0);
@@ -170,10 +171,10 @@ void BreakWindow::contextMenuEvent(QContextMenuEvent *ev)
QList<int> breakPointsOfFile;
if (indexUnderMouse.isValid()) {
const QModelIndex index = indexUnderMouse.sibling(indexUnderMouse.row(), 2);
const QString file = itemModel->data(index).toString();
const QString file = model()->data(index).toString();
if (!file.isEmpty()) {
for (int i = 0; i < rowCount; i++)
if (itemModel->data(itemModel->index(i, 2)).toString() == file)
if (model()->data(model()->index(i, 2)).toString() == file)
breakPointsOfFile.push_back(i);
if (breakPointsOfFile.size() > 1) {
deleteByFileAction =
@@ -200,7 +201,7 @@ void BreakWindow::contextMenuEvent(QContextMenuEvent *ev)
new QAction(tr("Edit Breakpoint..."), &menu);
editBreakpointAction->setEnabled(si.size() > 0);
int threadId = m_manager->threadsHandler()->currentThreadId();
int threadId = model()->data(QModelIndex(), CurrentThreadIdRole).toInt();
QString associateTitle = threadId == -1
? tr("Associate Breakpoint With All Threads")
: tr("Associate Breakpoint With Thread %1").arg(threadId);
@@ -210,11 +211,12 @@ void BreakWindow::contextMenuEvent(QContextMenuEvent *ev)
QAction *synchronizeAction =
new QAction(tr("Synchronize Breakpoints"), &menu);
synchronizeAction->setEnabled(
Debugger::DebuggerManager::instance()->debuggerActionsEnabled());
model()->data(QModelIndex(), EngineActionsEnabledRole).toBool());
QModelIndex idx0 = (si.size() ? si.front() : QModelIndex());
QModelIndex idx2 = idx0.sibling(idx0.row(), 2);
bool enabled = si.isEmpty() || itemModel->data(idx0, Qt::UserRole).toBool();
bool enabled = si.isEmpty()
|| idx0.data(BreakpointEnabledRole).toBool();
const QString str5 = si.size() > 1
? enabled
@@ -226,7 +228,8 @@ void BreakWindow::contextMenuEvent(QContextMenuEvent *ev)
QAction *toggleEnabledAction = new QAction(str5, &menu);
toggleEnabledAction->setEnabled(si.size() > 0);
const bool fullpath = si.isEmpty() || itemModel->data(idx2, Qt::UserRole).toBool();
const bool fullpath = si.isEmpty()
|| idx2.data(BreakpointEnabledRole).toBool();
const QString str6 = fullpath ? tr("Use Short Path") : tr("Use Full Path");
QAction *pathAction = new QAction(str6, &menu);
pathAction->setEnabled(si.size() > 0);
@@ -285,7 +288,7 @@ void BreakWindow::contextMenuEvent(QContextMenuEvent *ev)
else if (act == associateBreakpointAction)
associateBreakpoint(si, threadId);
else if (act == synchronizeAction)
emit breakpointSynchronizationRequested();
setModelData(RequestSynchronizeBreakpointsRole);
else if (act == toggleEnabledAction)
setBreakpointsEnabled(si, !enabled);
else if (act == pathAction)
@@ -293,37 +296,35 @@ void BreakWindow::contextMenuEvent(QContextMenuEvent *ev)
else if (act == breakAtFunctionAction) {
BreakByFunctionDialog dlg(this);
if (dlg.exec())
emit breakByFunctionRequested(dlg.functionName());
setModelData(RequestBreakByFunctionRole, dlg.functionName());
} else if (act == breakAtMainAction)
emit breakByFunctionMainRequested();
setModelData(RequestBreakByFunctionMainRole);
else if (act == breakAtThrowAction)
emit breakByFunctionRequested("__cxa_throw");
setModelData(RequestBreakByFunctionRole, "__cxa_throw");
else if (act == breakAtCatchAction)
emit breakByFunctionRequested("__cxa_begin_catch");
setModelData(RequestBreakByFunctionRole, "__cxa_begin_catch");
}
void BreakWindow::setBreakpointsEnabled(const QModelIndexList &list, bool enabled)
{
foreach (const QModelIndex &idx, list)
model()->setData(idx, enabled, Qt::UserRole + 1);
emit breakpointSynchronizationRequested();
foreach (const QModelIndex &index, list)
setModelData(BreakpointEnabledRole, enabled, index);
setModelData(RequestSynchronizeBreakpointsRole);
}
void BreakWindow::setBreakpointsFullPath(const QModelIndexList &list, bool fullpath)
{
foreach (const QModelIndex &idx, list) {
QModelIndex idx2 = idx.sibling(idx.row(), 2);
model()->setData(idx2, fullpath, Qt::UserRole + 2);
}
emit breakpointSynchronizationRequested();
foreach (const QModelIndex &index, list)
setModelData(BreakpointUseFullPathRole, fullpath, index);
setModelData(RequestSynchronizeBreakpointsRole);
}
void BreakWindow::deleteBreakpoints(const QModelIndexList &indexes)
{
QTC_ASSERT(!indexes.isEmpty(), return);
QList<int> list;
foreach (const QModelIndex &idx, indexes)
list.append(idx.row());
foreach (const QModelIndex &index, indexes)
list.append(index.row());
deleteBreakpoints(list);
}
@@ -334,12 +335,12 @@ void BreakWindow::deleteBreakpoints(QList<int> list)
const int firstRow = list.front();
qSort(list.begin(), list.end());
for (int i = list.size(); --i >= 0; )
emit breakpointDeleted(list.at(i));
setModelData(RequestRemoveBreakpointByIndexRole, list.at(i));
const int row = qMin(firstRow, model()->rowCount() - 1);
if (row >= 0)
setCurrentIndex(model()->index(row, 0));
emit breakpointSynchronizationRequested();
setModelData(RequestSynchronizeBreakpointsRole);
}
void BreakWindow::editBreakpoint(const QModelIndexList &list)
@@ -350,9 +351,8 @@ void BreakWindow::editBreakpoint(const QModelIndexList &list)
QTC_ASSERT(!list.isEmpty(), return);
QModelIndex idx = list.front();
int row = idx.row();
const int row = idx.row();
dlg.setWindowTitle(tr("Conditions on Breakpoint %1").arg(row));
int role = Qt::UserRole + 1;
ui.lineEditFunction->hide();
ui.labelFunction->hide();
ui.lineEditFileName->hide();
@@ -360,18 +360,12 @@ void BreakWindow::editBreakpoint(const QModelIndexList &list)
ui.lineEditLineNumber->hide();
ui.labelLineNumber->hide();
QAbstractItemModel *m = model();
//ui.lineEditFunction->setText(
// m->data(idx.sibling(row, 1), role).toString());
//ui.lineEditFileName->setText(
// m->data(idx.sibling(row, 2), role).toString());
//ui.lineEditLineNumber->setText(
// m->data(idx.sibling(row, 3), role).toString());
ui.lineEditCondition->setText(
m->data(idx.sibling(row, 4), role).toString());
m->data(idx, BreakpointConditionRole).toString());
ui.lineEditIgnoreCount->setText(
m->data(idx.sibling(row, 5), role).toString());
m->data(idx, BreakpointIgnoreCountRole).toString());
ui.lineEditThreadSpec->setText(
m->data(idx.sibling(row, 6), role).toString());
m->data(idx, BreakpointThreadSpecRole).toString());
if (dlg.exec() == QDialog::Rejected)
return;
@@ -380,11 +374,11 @@ void BreakWindow::editBreakpoint(const QModelIndexList &list)
//m->setData(idx.sibling(idx.row(), 1), ui.lineEditFunction->text());
//m->setData(idx.sibling(idx.row(), 2), ui.lineEditFileName->text());
//m->setData(idx.sibling(idx.row(), 3), ui.lineEditLineNumber->text());
m->setData(idx.sibling(idx.row(), 4), ui.lineEditCondition->text());
m->setData(idx.sibling(idx.row(), 5), ui.lineEditIgnoreCount->text());
m->setData(idx.sibling(idx.row(), 6), ui.lineEditThreadSpec->text());
m->setData(idx, ui.lineEditCondition->text(), BreakpointConditionRole);
m->setData(idx, ui.lineEditIgnoreCount->text(), BreakpointIgnoreCountRole);
m->setData(idx, ui.lineEditThreadSpec->text(), BreakpointThreadSpecRole);
}
emit breakpointSynchronizationRequested();
setModelData(RequestSynchronizeBreakpointsRole);
}
void BreakWindow::associateBreakpoint(const QModelIndexList &list, int threadId)
@@ -392,9 +386,9 @@ void BreakWindow::associateBreakpoint(const QModelIndexList &list, int threadId)
QString str;
if (threadId != -1)
str = QString::number(threadId);
foreach (const QModelIndex &idx, list)
model()->setData(idx.sibling(idx.row(), 6), str);
emit breakpointSynchronizationRequested();
foreach (const QModelIndex &index, list)
setModelData(BreakpointThreadSpecRole, str, index);
setModelData(RequestSynchronizeBreakpointsRole);
}
void BreakWindow::resizeColumnsToContents()
@@ -412,8 +406,46 @@ void BreakWindow::setAlwaysResizeColumnsToContents(bool on)
header()->setResizeMode(i, mode);
}
void BreakWindow::rowActivated(const QModelIndex &idx)
void BreakWindow::rowActivated(const QModelIndex &index)
{
emit breakpointActivated(idx.row());
setModelData(RequestActivateBreakpointRole, index.row());
}
BreakpointData *BreakWindow::findSimilarBreakpoint(const BreakpointData *needle0)
{
BreakpointData *needle = const_cast<BreakpointData *>(needle0);
QVariant v = QVariant::fromValue<BreakpointData *>(needle);
setModelData(RequestFindSimilarBreakpointRole, v);
QTC_ASSERT(model(), return false);
v = model()->data(QModelIndex(), RequestFindSimilarBreakpointRole);
return v.value<BreakpointData *>();
}
void BreakWindow::appendBreakpoint(BreakpointData *data)
{
QVariant v = QVariant::fromValue<BreakpointData *>(data);
setModelData(RequestAppendBreakpointRole, v);
}
void BreakWindow::removeBreakpoint(BreakpointData *data)
{
QVariant v = QVariant::fromValue<BreakpointData *>(data);
setModelData(RequestRemoveBreakpointRole, v);
}
void BreakWindow::updateBreakpoint(BreakpointData *data)
{
QVariant v = QVariant::fromValue<BreakpointData *>(data);
setModelData(RequestUpdateBreakpointRole, v);
}
void BreakWindow::setModelData
(int role, const QVariant &value, const QModelIndex &index)
{
QTC_ASSERT(model(), return);
model()->setData(index, value, role);
}
} // namespace Internal
} // namespace Debugger
+14 -16
View File
@@ -1,5 +1,4 @@
/**************************************************************************
QT_END_NAMESPACE
**
** This file is part of Qt Creator
**
@@ -31,12 +30,11 @@ QT_END_NAMESPACE
#ifndef DEBUGGER_BREAKWINDOW_H
#define DEBUGGER_BREAKWINDOW_H
#include "breakpoint.h"
#include <QtGui/QTreeView>
namespace Debugger {
class DebuggerManager;
namespace Internal {
class BreakWindow : public QTreeView
@@ -44,31 +42,30 @@ class BreakWindow : public QTreeView
Q_OBJECT
public:
explicit BreakWindow(DebuggerManager *manager);
explicit BreakWindow(QWidget *parent = 0);
~BreakWindow();
BreakpointData *findSimilarBreakpoint(const BreakpointData *needle);
void updateBreakpoint(BreakpointData *data);
void appendBreakpoint(BreakpointData *data);
void removeBreakpoint(BreakpointData *data);
QVariant modelData(int role, int index);
public slots:
void resizeColumnsToContents();
void setAlwaysResizeColumnsToContents(bool on);
signals:
void breakpointDeleted(int index);
void breakpointActivated(int index);
void breakpointSynchronizationRequested();
void breakByFunctionRequested(const QString &functionName);
void breakByFunctionMainRequested();
private slots:
void rowActivated(const QModelIndex &index);
void setAlternatingRowColorsHelper(bool on) { setAlternatingRowColors(on); }
void showAddressColumn(bool on);
protected:
private:
void resizeEvent(QResizeEvent *ev);
void contextMenuEvent(QContextMenuEvent *ev);
void keyPressEvent(QKeyEvent *ev);
void mouseDoubleClickEvent(QMouseEvent *ev);
private:
void deleteBreakpoints(const QModelIndexList &list);
void deleteBreakpoints(QList<int> rows);
void editBreakpoint(const QModelIndexList &list);
@@ -76,11 +73,12 @@ private:
void setBreakpointsEnabled(const QModelIndexList &list, bool enabled);
void setBreakpointsFullPath(const QModelIndexList &list, bool fullpath);
DebuggerManager *m_manager;
void setModelData(int role, const QVariant &value = QVariant(),
const QModelIndex &index = QModelIndex());
bool m_alwaysResizeColumnsToContents;
};
} // namespace Internal
} // namespace Debugger
+2
View File
@@ -47,6 +47,8 @@ namespace CdbCore {
* When/How many times it triggers can be influenced by
* condition/ignorecount and 'oneshot'-flag. */
// FIXME: Merge with/derive from Debugger::Internal::Breakpoint
struct BreakPoint
{
enum Type { Code, // Stop in code.
+6
View File
@@ -1,6 +1,10 @@
# Detect presence of "Debugging Tools For Windows"
# in case VS compilers are used.
# FIXME
CDB_PATH=""
false {
win32 {
contains(QMAKE_CXX, cl) {
@@ -50,3 +54,5 @@ LIBS+=-lpsapi
} # exists($$CDB_PATH)
} # (QMAKE_CXX, cl)
} # win32
} # false
+76 -86
View File
@@ -45,7 +45,6 @@
#include "debuggermainwindow.h"
#include "debuggeractions.h"
#include "debuggermanager.h"
#include "breakhandler.h"
#include "stackhandler.h"
#include "watchhandler.h"
@@ -83,6 +82,7 @@ static const char *localSymbolRootC = "local";
namespace Debugger {
namespace Internal {
CdbOptionsPage *theOptionsPage = 0;
typedef QList<WatchData> WatchList;
// ----- Message helpers
@@ -119,9 +119,8 @@ static QString msgFunctionFailed(const char *func, const QString &why)
// --- CdbDebugEnginePrivate
CdbDebugEnginePrivate::CdbDebugEnginePrivate(const QSharedPointer<CdbOptions> &options,
CdbDebugEngine *engine) :
m_options(options),
CdbDebugEnginePrivate::CdbDebugEnginePrivate(CdbDebugEngine *engine) :
m_options(theOptionsPage->options()),
m_hDebuggeeProcess(0),
m_hDebuggeeThread(0),
m_breakEventMode(BreakEventHandle),
@@ -159,11 +158,10 @@ bool CdbDebugEnginePrivate::init(QString *errorMessage)
return true;
}
IDebuggerEngine *CdbDebugEngine::create(Debugger::DebuggerManager *manager,
const QSharedPointer<CdbOptions> &options,
QString *errorMessage)
DebuggerEngine *CdbDebugEngine::create(const DebuggerStartParameters &sp,
QString *errorMessage)
{
CdbDebugEngine *rc = new CdbDebugEngine(manager, options);
CdbDebugEngine *rc = new CdbDebugEngine(sp);
if (rc->m_d->init(errorMessage)) {
rc->syncDebuggerPaths();
return rc;
@@ -184,11 +182,6 @@ CdbDebugEnginePrivate::~CdbDebugEnginePrivate()
cleanStackTrace();
}
DebuggerManager *CdbDebugEnginePrivate::manager() const
{
return m_engine->manager();
}
void CdbDebugEnginePrivate::clearForRun()
{
if (debugCDB)
@@ -212,9 +205,9 @@ void CdbDebugEnginePrivate::cleanStackTrace()
m_editorToolTipCache.clear();
}
CdbDebugEngine::CdbDebugEngine(DebuggerManager *manager, const QSharedPointer<CdbOptions> &options) :
IDebuggerEngine(manager),
m_d(new CdbDebugEnginePrivate(options, this))
CdbDebugEngine::CdbDebugEngine(const DebuggerStartParameters &startParameters) :
DebuggerEngine(startParamters),
m_d(new CdbDebugEnginePrivate(this))
{
m_d->m_consoleStubProc.setMode(Utils::ConsoleProcess::Suspend);
connect(&m_d->m_consoleStubProc, SIGNAL(processMessage(QString,bool)),
@@ -234,7 +227,7 @@ void CdbDebugEngine::setState(DebuggerState state, const char *func, int line)
{
if (debugCDB)
qDebug() << "setState(" << state << ") at " << func << ':' << line;
IDebuggerEngine::setState(state);
DebuggerEngine::setState(state);
}
void CdbDebugEngine::shutdown()
@@ -392,6 +385,7 @@ void CdbDebugEngine::startDebugger()
if (m_d->m_hDebuggeeProcess) {
warning(QLatin1String("Internal error: Attempt to start debugger while another process is being debugged."));
setState(AdapterStartFailed, Q_FUNC_INFO, __LINE__);
setState(DebuggerNotReady, Q_FUNC_INFO, __LINE__);
emit startFailed();
return;
}
@@ -400,6 +394,7 @@ void CdbDebugEngine::startDebugger()
case AttachToRemote:
warning(QLatin1String("Internal error: Mode not supported."));
setState(AdapterStartFailed, Q_FUNC_INFO, __LINE__);
setState(DebuggerNotReady, Q_FUNC_INFO, __LINE__);
emit startFailed();
break;
default:
@@ -415,24 +410,24 @@ void CdbDebugEngine::startDebugger()
showMessage(errorMessage, LogWarning);
m_d->setVerboseSymbolLoading(m_d->m_options->verboseSymbolLoading);
// Figure out dumper. @TODO: same in gdb...
const QString dumperLibName = QDir::toNativeSeparators(manager()->qtDumperLibraryName());
const QString dumperLibName = QDir::toNativeSeparators(qtDumperLibraryName());
bool dumperEnabled = m_d->m_mode != AttachCore
&& m_d->m_mode != AttachCrashedExternal
&& manager()->qtDumperLibraryEnabled();
&& qtDumperLibraryEnabled();
if (dumperEnabled) {
const QFileInfo fi(dumperLibName);
if (!fi.isFile()) {
const QStringList &locations = manager()->qtDumperLibraryLocations();
const QStringList &locations = qtDumperLibraryLocations();
const QString loc = locations.join(QLatin1String(", "));
const QString msg = tr("The dumper library was not found at %1.").arg(loc);
manager()->showQtDumperLibraryWarning(msg);
showQtDumperLibraryWarning(msg);
dumperEnabled = false;
}
}
m_d->m_dumper->reset(dumperLibName, dumperEnabled);
setState(InferiorStarting, Q_FUNC_INFO, __LINE__);
manager()->showStatusMessage("Starting Debugger", messageTimeOut);
showStatusMessage("Starting Debugger", messageTimeOut);
bool rc = false;
bool needWatchTimer = false;
@@ -474,11 +469,11 @@ void CdbDebugEngine::startDebugger()
if (rc) {
if (needWatchTimer)
m_d->startWatchTimer();
emit startSuccessful();
startSuccessful();
} else {
warning(errorMessage);
setState(InferiorStartFailed, Q_FUNC_INFO, __LINE__);
emit startFailed();
startFailed();
}
}
@@ -543,7 +538,7 @@ void CdbDebugEngine::processTerminated(unsigned long exitCode)
m_d->clearForRun();
setState(InferiorShutDown, Q_FUNC_INFO, __LINE__);
// Avoid calls from event handler.
QTimer::singleShot(0, manager(), SLOT(exitDebugger()));
QTimer::singleShot(0, this, SLOT(quitDebugger()));
}
bool CdbDebugEnginePrivate::endInferior(EndInferiorAction action, QString *errorMessage)
@@ -680,15 +675,14 @@ void CdbDebugEngine::updateWatchData(const WatchData &incomplete)
if (debugCDBWatchHandling)
qDebug() << Q_FUNC_INFO << "\n " << incomplete.toString();
WatchHandler *watchHandler = manager()->watchHandler();
if (incomplete.iname.startsWith("watch.")) {
WatchData watchData = incomplete;
evaluateWatcher(&watchData);
watchHandler->insertData(watchData);
watchHandler()->insertData(watchData);
return;
}
const int frameIndex = manager()->stackHandler()->currentIndex();
const int frameIndex = stackHandler()->currentIndex();
bool success = false;
QString errorMessage;
@@ -696,14 +690,14 @@ void CdbDebugEngine::updateWatchData(const WatchData &incomplete)
CdbSymbolGroupContext *sg = m_d->m_currentStackTrace->cdbSymbolGroupContextAt(frameIndex, &errorMessage);
if (!sg)
break;
if (!sg->completeData(incomplete, watchHandler, &errorMessage))
if (!sg->completeData(incomplete, watchHandler(), &errorMessage))
break;
success = true;
} while (false);
if (!success)
warning(msgFunctionFailed(Q_FUNC_INFO, errorMessage));
if (debugCDBWatchHandling > 1)
qDebug() << *manager()->watchHandler()->model(LocalsWatch);
qDebug() << *watchHandler()->model(LocalsWatch);
}
// Continue inferior with a debugger command, such as "p", "pt"
@@ -771,7 +765,7 @@ bool CdbDebugEngine::step(unsigned long executionStatus)
const int triggeringEventThread = m_d->m_eventThreadId;
const bool sameThread = triggeringEventThread == -1
|| m_d->m_currentThreadId == triggeringEventThread
|| manager()->threadsHandler()->threads().size() == 1;
|| threadsHandler()->threads().size() == 1;
m_d->clearForRun(); // clears thread ids
m_d->updateCodeLevel(); // Step by instruction or source line
setState(InferiorRunningRequested, Q_FUNC_INFO, __LINE__);
@@ -819,12 +813,12 @@ bool CdbDebugEngine::step(unsigned long executionStatus)
void CdbDebugEngine::executeStep()
{
step(manager()->isReverseDebugging() ? DEBUG_STATUS_REVERSE_STEP_INTO : DEBUG_STATUS_STEP_INTO);
step(isReverseDebugging() ? DEBUG_STATUS_REVERSE_STEP_INTO : DEBUG_STATUS_STEP_INTO);
}
void CdbDebugEngine::executeNext()
{
step(manager()->isReverseDebugging() ? DEBUG_STATUS_REVERSE_STEP_OVER : DEBUG_STATUS_STEP_OVER);
step(isReverseDebugging() ? DEBUG_STATUS_REVERSE_STEP_OVER : DEBUG_STATUS_STEP_OVER);
}
void CdbDebugEngine::executeStepI()
@@ -839,7 +833,7 @@ void CdbDebugEngine::executeNextI()
void CdbDebugEngine::executeStepOut()
{
if (!manager()->isReverseDebugging())
if (!isReverseDebugging())
step(CdbExtendedExecutionStatusStepOut);
}
@@ -887,8 +881,8 @@ bool CdbDebugEnginePrivate::continueInferior(QString *errorMessage)
clearForRun();
updateCodeLevel();
killWatchTimer();
manager()->resetLocation();
manager()->showStatusMessage(CdbDebugEngine::tr("Running requested..."), messageTimeOut);
m_engine->resetLocation();
m_engine->showStatusMessage(CdbDebugEngine::tr("Running requested..."), messageTimeOut);
if (!continueInferiorProcess(errorMessage))
break;
@@ -988,7 +982,7 @@ void CdbDebugEngine::assignValueInDebugger(const QString &expr, const QString &v
{
if (debugCDB)
qDebug() << Q_FUNC_INFO << expr << value;
const int frameIndex = manager()->stackHandler()->currentIndex();
const int frameIndex = stackHandler()->currentIndex();
QString errorMessage;
bool success = false;
do {
@@ -999,11 +993,10 @@ void CdbDebugEngine::assignValueInDebugger(const QString &expr, const QString &v
if (!sg->assignValue(expr, value, &newValue, &errorMessage))
break;
// Update view
WatchHandler *watchHandler = manager()->watchHandler();
if (WatchData *fwd = watchHandler->findItem(expr.toLatin1())) {
if (WatchData *fwd = watchHandler()->findItem(expr.toLatin1())) {
fwd->setValue(newValue);
watchHandler->insertData(*fwd);
watchHandler->updateWatchers();
watchHandler()->insertData(*fwd);
watchHandler()->updateWatchers();
}
success = true;
} while (false);
@@ -1032,24 +1025,22 @@ void CdbDebugEngine::activateFrame(int frameIndex)
QString errorMessage;
bool success = false;
StackHandler *stackHandler = manager()->stackHandler();
do {
WatchHandler *watchHandler = manager()->watchHandler();
const int oldIndex = stackHandler->currentIndex();
if (frameIndex >= stackHandler->stackSize()) {
errorMessage = msgStackIndexOutOfRange(frameIndex, stackHandler->stackSize());
const int oldIndex = stackHandler()->currentIndex();
if (frameIndex >= stackHandler()->stackSize()) {
errorMessage = msgStackIndexOutOfRange(frameIndex, stackHandler()->stackSize());
break;
}
if (oldIndex != frameIndex)
stackHandler->setCurrentIndex(frameIndex);
stackHandler()->setCurrentIndex(frameIndex);
const StackFrame &frame = stackHandler->currentFrame();
const StackFrame &frame = stackHandler()->currentFrame();
const bool showAssembler = !frame.isUsable();
if (showAssembler) { // Assembly code: Clean out model and force instruction mode.
watchHandler->beginCycle();
watchHandler->endCycle();
watchHandler()->beginCycle();
watchHandler()->endCycle();
QAction *assemblerAction = theDebuggerAction(OperateByInstruction);
if (!assemblerAction->isChecked())
assemblerAction->trigger();
@@ -1057,20 +1048,22 @@ void CdbDebugEngine::activateFrame(int frameIndex)
break;
}
manager()->gotoLocation(frame, true);
gotoLocation(frame, true);
if (oldIndex != frameIndex || m_d->m_firstActivatedFrame) {
watchHandler->beginCycle();
watchHandler()->beginCycle();
if (CdbSymbolGroupContext *sgc = m_d->getSymbolGroupContext(frameIndex, &errorMessage))
success = sgc->populateModelInitially(watchHandler, &errorMessage);
watchHandler->endCycle();
success = sgc->populateModelInitially(watchHandler(), &errorMessage);
watchHandler()->endCycle();
} else {
success = true;
}
} while (false);
if (!success) {
const QString msg = QString::fromLatin1("Internal error: activateFrame() failed for frame #%1 of %2, thread %3: %4").
arg(frameIndex).arg(stackHandler->stackSize()).arg(m_d->m_currentThreadId).arg(errorMessage);
arg(frameIndex).arg(stackHandler()->stackSize()).
arg(m_d->m_currentThreadId).arg(errorMessage);
warning(msg);
}
m_d->m_firstActivatedFrame = false;
@@ -1081,14 +1074,13 @@ void CdbDebugEngine::selectThread(int index)
if (debugCDB)
qDebug() << Q_FUNC_INFO << index;
//reset location arrow
manager()->resetLocation();
// Reset location arrow.
resetLocation();
ThreadsHandler *threadsHandler = manager()->threadsHandler();
threadsHandler->setCurrentThread(index);
const int newThreadId = threadsHandler->threads().at(index).id;
threadsHandler()->setCurrentThread(index);
const int newThreadId = threadsHandler()->threads().at(index).id;
if (newThreadId != m_d->m_currentThreadId) {
m_d->m_currentThreadId = threadsHandler->threads().at(index).id;
m_d->m_currentThreadId = threadsHandler()->threads().at(index).id;
m_d->updateStackTrace();
}
}
@@ -1133,7 +1125,7 @@ bool CdbDebugEnginePrivate::attemptBreakpointSynchronization(QString *errorMessa
QStringList warnings;
const bool ok = synchronizeBreakPoints(interfaces().debugControl,
interfaces().debugSymbols,
manager()->breakHandler(),
breakHandler(),
errorMessage, &warnings);
if (const int warningsCount = warnings.size())
for (int w = 0; w < warningsCount; w++)
@@ -1313,7 +1305,7 @@ void CdbDebugEnginePrivate::notifyException(long code, bool fatal, const QString
static int threadIndexById(const ThreadsHandler *threadsHandler, int id)
{
const QList<ThreadData> threads = threadsHandler->threads();
const Threads threads = threadsHandler->threads();
const int count = threads.count();
for (int i = 0; i < count; i++)
if (threads.at(i).id == id)
@@ -1343,7 +1335,7 @@ void CdbDebugEnginePrivate::handleDebugEvent()
// Get thread to stop and its index. If avoidable, do not use
// the artifical thread that is created when interrupting,
// use the oldest thread 0 instead.
ThreadsHandler *threadsHandler = manager()->threadsHandler();
ThreadsHandler *threadsHandler = m_engine->threadsHandler();
m_currentThreadId = m_interrupted ? 0 : m_eventThreadId;
int currentThreadIndex = -1;
m_currentThreadId = -1;
@@ -1418,13 +1410,13 @@ ULONG CdbDebugEnginePrivate::updateThreadList()
if (debugCDB)
qDebug() << Q_FUNC_INFO << m_hDebuggeeProcess;
QList<ThreadData> threads;
Threads threads;
ULONG currentThreadId;
QString errorMessage;
// When interrupting, an artifical thread with a breakpoint is created.
if (!CdbStackTraceContext::getThreads(interfaces(), &threads, &currentThreadId, &errorMessage))
m_engine->warning(errorMessage);
manager()->threadsHandler()->setThreads(threads);
m_engine->threadsHandler()->setThreads(threads);
return currentThreadId;
}
@@ -1527,19 +1519,19 @@ void CdbDebugEnginePrivate::updateStackTrace()
qDebug() << "updateStackTrace() current: " << m_currentThreadId << " dumper=" << dumperThread;
m_dumper->setDumperCallThread(dumperThread);
// Display frames
manager()->stackHandler()->setFrames(stackFrames);
m_engine->stackHandler()->setFrames(stackFrames);
m_firstActivatedFrame = true;
if (current >= 0) {
manager()->stackHandler()->setCurrentIndex(current);
m_engine->stackHandler()->setCurrentIndex(current);
m_engine->activateFrame(current);
} else {
// Clean out variables
manager()->watchHandler()->beginCycle();
manager()->watchHandler()->endCycle();
m_engine->watchHandler()->beginCycle();
m_engine->watchHandler()->endCycle();
}
manager()->watchHandler()->updateWatchers();
m_engine->watchHandler()->updateWatchers();
// Show message after a lengthy dumper initialization
manager()->showStatusMessage(stopMessage, 15000);
m_engine->showMessage(stopMessage, StatusBar, 15000);
}
void CdbDebugEnginePrivate::updateModules()
@@ -1618,30 +1610,28 @@ unsigned CdbDebugEngine::debuggerCapabilities() const
|BreakOnThrowAndCatchCapability; // Sort-of: Can break on throw().
}
// Accessed by DebuggerManager
IDebuggerEngine *createCdbEngine(DebuggerManager *parent,
bool cmdLineEnabled,
QList<Core::IOptionsPage*> *opts)
// Accessed by RunControlFactory
DebuggerEngine *createCdbEngine(const DebuggerStartParameters &sp)
{
// Create options page
QSharedPointer<CdbOptions> options(new CdbOptions);
options->fromSettings(Core::ICore::instance()->settings());
CdbOptionsPage *optionsPage = new CdbOptionsPage(options);
opts->push_back(optionsPage);
if (!cmdLineEnabled || !options->enabled)
return 0;
// Create engine
QString errorMessage;
IDebuggerEngine *engine = CdbDebugEngine::create(parent, options, &errorMessage);
DebuggerEngine *engine = CdbDebugEngine::create(sp, &errorMessage);
if (engine) {
QObject::connect(optionsPage, SIGNAL(debuggerPathsChanged()), engine, SLOT(syncDebuggerPaths()));
QObject::connect(theOptionsPage, SIGNAL(debuggerPathsChanged()), engine, SLOT(syncDebuggerPaths()));
} else {
optionsPage->setFailureMessage(errorMessage);
theOptionsPage->setFailureMessage(errorMessage);
qWarning("%s\n" ,qPrintable(errorMessage));
}
return engine;
}
void addCdbOptionPages(QList<Core::IOptionsPage *> *opts)
{
// FIXME: HACK (global variable)
theOptionsPage = new CdbOptionsPage;
opts->push_back(theOptionsPage);
}
} // namespace Internal
} // namespace Debugger
+4 -9
View File
@@ -30,14 +30,11 @@
#ifndef DEBUGGER_CDBENGINE_H
#define DEBUGGER_CDBENGINE_H
#include "idebuggerengine.h"
#include "debuggermanager.h"
#include "debuggerengine.h"
#include <QtCore/QSharedPointer>
namespace Debugger {
class DebuggerManager;
namespace Internal {
class DisassemblerViewAgent;
@@ -46,19 +43,17 @@ class CdbDebugOutput;
class CdbDebugEnginePrivate;
struct CdbOptions;
class CdbDebugEngine : public IDebuggerEngine
class CdbDebugEngine : public DebuggerEngine
{
Q_DISABLE_COPY(CdbDebugEngine)
Q_OBJECT
explicit CdbDebugEngine(DebuggerManager *parent,
const QSharedPointer<CdbOptions> &options);
explicit CdbDebugEngine(const DebuggerStartParameters &sp);
public:
~CdbDebugEngine();
// Factory function that returns 0 if the debug engine library cannot be found.
static IDebuggerEngine *create(DebuggerManager *parent,
const QSharedPointer<CdbOptions> &options,
static DebuggerEngine *create(const DebuggerStartParameters &sp,
QString *errorMessage);
virtual void shutdown();
+3 -6
View File
@@ -31,18 +31,17 @@
#define DEBUGGER_CDBENGINEPRIVATE_H
#include "coreengine.h"
#include "debuggerconstants.h"
#include "cdboptions.h"
#include "cdbdumperhelper.h"
#include "stackhandler.h"
#include "debuggermanager.h"
#include <utils/consoleprocess.h>
#include <QtCore/QSharedPointer>
#include <QtCore/QMap>
namespace Debugger {
class DebuggerManager;
namespace Internal {
class WatchHandler;
@@ -68,8 +67,7 @@ public:
StoppedOther
};
explicit CdbDebugEnginePrivate(const QSharedPointer<CdbOptions> &options,
CdbDebugEngine* engine);
explicit CdbDebugEnginePrivate(CdbDebugEngine* engine);
~CdbDebugEnginePrivate();
bool init(QString *errorMessage);
@@ -128,7 +126,6 @@ public:
QSharedPointer<CdbDumperHelper> m_dumper;
CdbDebugEngine *m_engine;
inline DebuggerManager *manager() const;
CdbStackTraceContext *m_currentStackTrace;
EditorToolTipCache m_editorToolTipCache;
@@ -31,7 +31,6 @@
#include "cdbdebugengine.h"
#include "cdbexceptionutils.h"
#include "cdbdebugengine_p.h"
#include "debuggermanager.h"
#include <QtCore/QDebug>
#include <QtCore/QTextStream>
@@ -42,7 +41,7 @@ namespace Internal {
// ---------- CdbDebugEventCallback
CdbDebugEventCallback::CdbDebugEventCallback(CdbDebugEngine* dbg) :
CdbDebugEventCallback::CdbDebugEventCallback(CdbDebugEngine *dbg) :
m_pEngine(dbg)
{
}
+4 -3
View File
@@ -100,7 +100,7 @@ namespace Internal {
// the QtCored4.pdb file to be present as we need "qstrdup"
// as dummy symbol. This is ok ATM since dumpers only
// make sense for Qt apps.
static bool debuggeeLoadLibrary(CdbDebugEngine *manager,
static bool debuggeeLoadLibrary(CdbDebugEngine *cdbEngine,
CdbCore::CoreEngine *engine,
unsigned long threadId,
const QString &moduleName,
@@ -109,7 +109,8 @@ static bool debuggeeLoadLibrary(CdbDebugEngine *manager,
if (loadDebug > 1)
qDebug() << Q_FUNC_INFO << moduleName;
// Try to ignore the breakpoints, skip stray startup-complete trap exceptions
QSharedPointer<CdbExceptionLoggerEventCallback> exLogger(new CdbExceptionLoggerEventCallback(LogWarning, true, manager));
QSharedPointer<CdbExceptionLoggerEventCallback>
exLogger(new CdbExceptionLoggerEventCallback(LogWarning, true, cdbEngine));
CdbCore::EventCallbackRedirector eventRedir(engine, exLogger);
Q_UNUSED(eventRedir)
// Make a call to LoadLibraryA. First, reserve memory in debugger
@@ -251,7 +252,7 @@ bool CdbDumperInitThread::ensureDumperInitialized(CdbDumperHelper &h, QString *e
h.m_state = CdbDumperHelper::Disabled; // No message here
*errorMessage = QCoreApplication::translate("Debugger::Internal::CdbDumperHelper", "The custom dumper library could not be initialized: %1").arg(*errorMessage);
h.m_engine->showStatusMessage(*errorMessage, messageTimeOut);
h.m_engine->manager()->showQtDumperLibraryWarning(*errorMessage);
h.m_engine->showQtDumperLibraryWarning(*errorMessage);
}
if (loadDebug)
qDebug() << Q_FUNC_INFO << '\n' << thread.m_ok;
+1 -2
View File
@@ -42,9 +42,8 @@ namespace CdbCore {
}
namespace Debugger {
class DebuggerManager;
namespace Internal {
class CdbDumperInitThread;
class CdbDebugEngine;
+3 -2
View File
@@ -138,9 +138,10 @@ QString CdbOptionsPageWidget::searchKeywords() const
}
// ---------- CdbOptionsPage
CdbOptionsPage::CdbOptionsPage(const QSharedPointer<CdbOptions> &options) :
m_options(options)
CdbOptionsPage::CdbOptionsPage() :
m_options(new CdbOptions)
{
m_options->fromSettings(Core::ICore::instance()->settings());
}
CdbOptionsPage::~CdbOptionsPage()
+2 -1
View File
@@ -68,7 +68,7 @@ class CdbOptionsPage : public Core::IOptionsPage
Q_DISABLE_COPY(CdbOptionsPage)
Q_OBJECT
public:
explicit CdbOptionsPage(const QSharedPointer<CdbOptions> &options);
explicit CdbOptionsPage();
virtual ~CdbOptionsPage();
// IOptionsPage
@@ -87,6 +87,7 @@ public:
// Load failure messages can be displayed here
void setFailureMessage(const QString &msg) { m_failureMessage = msg; }
QSharedPointer<CdbOptions> options() const { return m_options; }
signals:
void debuggerPathsChanged();
@@ -28,10 +28,12 @@
**************************************************************************/
#include "cdbstacktracecontext.h"
#include "cdbsymbolgroupcontext.h"
#include "cdbdumperhelper.h"
#include "cdbdebugengine_p.h"
#include "debuggeractions.h"
#include "debuggerplugin.h"
#include "watchutils.h"
#include "threadshandler.h"
@@ -61,18 +63,18 @@ CdbStackTraceContext *CdbStackTraceContext::create(const QSharedPointer<CdbDumpe
return ctx;
}
CdbCore::SymbolGroupContext
*CdbStackTraceContext::createSymbolGroup(const CdbCore::ComInterfaces & /* cif */,
int index,
const QString &prefix,
CIDebugSymbolGroup *comSymbolGroup,
QString *errorMessage)
CdbCore::SymbolGroupContext *
CdbStackTraceContext::createSymbolGroup(const CdbCore::ComInterfaces & /* cif */,
int index,
const QString &prefix,
CIDebugSymbolGroup *comSymbolGroup,
QString *errorMessage)
{
// Exclude uninitialized variables if desired
QStringList uninitializedVariables;
const CdbCore::StackFrame &frame = stackFrameAt(index);
if (theDebuggerAction(UseCodeModel)->isChecked())
getUninitializedVariables(DebuggerManager::instance()->cppCodeModelSnapshot(), frame.function, frame.fileName, frame.line, &uninitializedVariables);
getUninitializedVariables(DebuggerPlugin::instance()->cppCodeModelSnapshot(), frame.function, frame.fileName, frame.line, &uninitializedVariables);
if (debug)
qDebug() << frame << uninitializedVariables;
CdbSymbolGroupContext *sc = CdbSymbolGroupContext::create(prefix,
@@ -113,7 +115,7 @@ QList<StackFrame> CdbStackTraceContext::stackFrames() const
}
bool CdbStackTraceContext::getThreads(const CdbCore::ComInterfaces &cif,
QList<ThreadData> *threads,
Threads *threads,
ULONG *currentThreadId,
QString *errorMessage)
{
@@ -32,6 +32,7 @@
#include "stackhandler.h"
#include "stacktracecontext.h"
#include "threadshandler.h"
#include "cdbcom.h"
@@ -74,7 +75,7 @@ public:
// get threads in stopped state
static bool getThreads(const CdbCore::ComInterfaces &cif,
QList<ThreadData> *threads,
Threads *threads,
ULONG *currentThreadId,
QString *errorMessage);
+4 -4
View File
@@ -21,14 +21,13 @@ HEADERS += breakhandler.h \
debuggeractions.h \
debuggerconstants.h \
debuggerdialogs.h \
debuggermanager.h \
debuggerengine.h \
debugger_global.h \
debuggeroutputwindow.h \
debuggerplugin.h \
debuggerrunner.h \
debuggertooltip.h \
debuggerstringutils.h \
idebuggerengine.h \
moduleshandler.h \
moduleswindow.h \
outputcollector.h \
@@ -40,6 +39,7 @@ HEADERS += breakhandler.h \
stackwindow.h \
snapshothandler.h \
snapshotwindow.h \
sourcefileshandler.h \
sourcefileswindow.h \
threadswindow.h \
watchhandler.h \
@@ -55,12 +55,11 @@ SOURCES += breakhandler.cpp \
debuggeragents.cpp \
debuggeractions.cpp \
debuggerdialogs.cpp \
debuggermanager.cpp \
debuggerengine.cpp \
debuggeroutputwindow.cpp \
debuggerplugin.cpp \
debuggerrunner.cpp \
debuggertooltip.cpp \
idebuggerengine.cpp \
moduleshandler.cpp \
moduleswindow.cpp \
outputcollector.cpp \
@@ -71,6 +70,7 @@ SOURCES += breakhandler.cpp \
snapshotwindow.cpp \
stackhandler.cpp \
stackwindow.cpp \
sourcefileshandler.cpp \
sourcefileswindow.cpp \
threadswindow.cpp \
watchdata.cpp \
+9 -15
View File
@@ -64,7 +64,7 @@ namespace Internal {
//////////////////////////////////////////////////////////////////////////
DebuggerSettings::DebuggerSettings(QObject *parent)
: QObject(parent), m_gdbBinaryToolChainMap(new GdbBinaryToolChainMap)
: QObject(parent)
{}
DebuggerSettings::~DebuggerSettings()
@@ -87,7 +87,7 @@ void DebuggerSettings::readSettings(QSettings *settings)
item->readSettings(settings);
// Convert gdb binaries from flat settings list (see writeSettings)
// into map ("binary1=gdb,1,2", "binary2=symbian_gdb,3,4").
m_gdbBinaryToolChainMap->clear();
m_gdbBinaryToolChainMap.clear();
const QChar separator = QLatin1Char(',');
const QString keyRoot = QLatin1String(gdbBinariesSettingsGroupC) + QLatin1Char('/') +
QLatin1String(debugModeGdbBinaryKeyC);
@@ -102,15 +102,15 @@ void DebuggerSettings::readSettings(QSettings *settings)
const QString binary = tokens.front();
tokens.pop_front();
foreach(const QString &t, tokens)
m_gdbBinaryToolChainMap->insert(binary, t.toInt());
m_gdbBinaryToolChainMap.insert(binary, t.toInt());
}
// Linux defaults
#ifdef Q_OS_UNIX
if (m_gdbBinaryToolChainMap->isEmpty()) {
if (m_gdbBinaryToolChainMap.isEmpty()) {
const QString gdb = QLatin1String("gdb");
m_gdbBinaryToolChainMap->insert(gdb, ProjectExplorer::ToolChain::GCC);
m_gdbBinaryToolChainMap->insert(gdb, ProjectExplorer::ToolChain::OTHER);
m_gdbBinaryToolChainMap->insert(gdb, ProjectExplorer::ToolChain::UNKNOWN);
m_gdbBinaryToolChainMap.insert(gdb, ProjectExplorer::ToolChain::GCC);
m_gdbBinaryToolChainMap.insert(gdb, ProjectExplorer::ToolChain::OTHER);
m_gdbBinaryToolChainMap.insert(gdb, ProjectExplorer::ToolChain::UNKNOWN);
}
#endif
}
@@ -124,8 +124,8 @@ void DebuggerSettings::writeSettings(QSettings *settings) const
QString lastBinary;
QStringList settingsList;
const QChar separator = QLatin1Char(',');
const GdbBinaryToolChainMap::const_iterator cend = m_gdbBinaryToolChainMap->constEnd();
for (GdbBinaryToolChainMap::const_iterator it = m_gdbBinaryToolChainMap->constBegin(); it != cend; ++it) {
const GdbBinaryToolChainMap::const_iterator cend = m_gdbBinaryToolChainMap.constEnd();
for (GdbBinaryToolChainMap::const_iterator it = m_gdbBinaryToolChainMap.constBegin(); it != cend; ++it) {
if (it.key() != lastBinary) {
lastBinary = it.key(); // Start new entry with first toolchain
settingsList.push_back(lastBinary);
@@ -255,12 +255,6 @@ DebuggerSettings *DebuggerSettings::instance()
item->setTextPattern(tr("Watch Expression \"%1\" in Separate Window"));
instance->insertItem(WatchExpressionInWindow, item);
item = new SavedAction(instance);
instance->insertItem(AssignValue, item);
item = new SavedAction(instance);
instance->insertItem(AssignType, item);
item = new SavedAction(instance);
instance->insertItem(WatchPoint, item);
+6 -32
View File
@@ -32,7 +32,6 @@
#include <QtCore/QHash>
#include <QtCore/QMap>
#include <QtCore/QSharedPointer>
QT_BEGIN_NAMESPACE
class QAction;
@@ -41,7 +40,7 @@ class QSettings;
QT_END_NAMESPACE
namespace Utils {
class SavedAction;
class SavedAction;
}
namespace Debugger {
@@ -52,12 +51,14 @@ class DebuggerSettings : public QObject
Q_OBJECT
public:
typedef QMultiMap<QString, int> GdbBinaryToolChainMap;
typedef QSharedPointer<GdbBinaryToolChainMap> GdbBinaryToolChainMapPtr;
explicit DebuggerSettings(QObject *parent = 0);
~DebuggerSettings();
GdbBinaryToolChainMapPtr gdbBinaryToolChainMap() const { return m_gdbBinaryToolChainMap; }
GdbBinaryToolChainMap gdbBinaryToolChainMap() const
{ return m_gdbBinaryToolChainMap; }
void setGdbBinaryToolChainMap(const GdbBinaryToolChainMap &map)
{ m_gdbBinaryToolChainMap = map; }
void insertItem(int code, Utils::SavedAction *item);
Utils::SavedAction *item(int code) const;
@@ -72,8 +73,7 @@ public slots:
private:
QHash<int, Utils::SavedAction *> m_items;
const GdbBinaryToolChainMapPtr m_gdbBinaryToolChainMap;
GdbBinaryToolChainMap m_gdbBinaryToolChainMap;
};
@@ -127,8 +127,6 @@ enum DebuggerActionCode
WatchExpressionInWindow,
RemoveWatchExpression,
WatchPoint,
AssignValue,
AssignType,
ShowStdNamespace,
ShowQtNamespace,
@@ -160,30 +158,6 @@ Utils::SavedAction *theDebuggerAction(int code);
bool theDebuggerBoolSetting(int code);
QString theDebuggerStringSetting(int code);
struct DebuggerManagerActions
{
QAction *continueAction;
QAction *stopAction;
QAction *resetAction; // FIXME: Should not be needed in a stable release
QAction *stepAction;
QAction *stepOutAction;
QAction *runToLineAction1; // in the Debug menu
QAction *runToLineAction2; // in the text editor context menu
QAction *runToFunctionAction;
QAction *jumpToLineAction1; // in the Debug menu
QAction *jumpToLineAction2; // in the text editor context menu
QAction *returnFromFunctionAction;
QAction *nextAction;
QAction *snapshotAction;
QAction *watchAction1; // in the Debug menu
QAction *watchAction2; // in the text editor context menu
QAction *breakAction;
QAction *sepAction;
QAction *reverseDirectionAction;
QAction *frameUpAction;
QAction *frameDownAction;
};
} // namespace Internal
} // namespace Debugger
+18 -20
View File
@@ -28,10 +28,11 @@
**************************************************************************/
#include "debuggeragents.h"
#include "debuggermanager.h"
#include "stackframe.h"
#include "debuggerengine.h"
#include "debuggerplugin.h"
#include "debuggerstringutils.h"
#include "idebuggerengine.h"
#include "stackframe.h"
#include <coreplugin/coreconstants.h>
#include <coreplugin/editormanager/editormanager.h>
@@ -71,15 +72,17 @@ namespace Internal {
it handles communication between the engine and the bineditor.
*/
MemoryViewAgent::MemoryViewAgent(DebuggerManager *manager, quint64 addr)
: QObject(manager), m_engine(manager->currentEngine()), m_manager(manager)
MemoryViewAgent::MemoryViewAgent(DebuggerEngine *engine, quint64 addr)
: QObject(engine), m_engine(engine)
{
QTC_ASSERT(engine, /**/);
createBinEditor(addr);
}
MemoryViewAgent::MemoryViewAgent(DebuggerManager *manager, const QString &addr)
: QObject(manager), m_engine(manager->currentEngine()), m_manager(manager)
MemoryViewAgent::MemoryViewAgent(DebuggerEngine *engine, const QString &addr)
: QObject(engine), m_engine(engine)
{
QTC_ASSERT(engine, /**/);
bool ok = true;
createBinEditor(addr.toULongLong(&ok, 0));
//qDebug() << " ADDRESS: " << addr << addr.toUInt(&ok, 0);
@@ -111,7 +114,7 @@ void MemoryViewAgent::createBinEditor(quint64 addr)
QMetaObject::invokeMethod(editor->widget(), "setLazyData",
Q_ARG(quint64, addr), Q_ARG(int, 1024 * 1024), Q_ARG(int, BinBlockSize));
} else {
m_manager->showMessageBox(QMessageBox::Warning,
DebuggerPlugin::instance()->showMessageBox(QMessageBox::Warning,
tr("No memory viewer available"),
tr("The memory contents cannot be shown as no viewer plugin "
"for binary data has been loaded."));
@@ -122,8 +125,7 @@ void MemoryViewAgent::createBinEditor(quint64 addr)
void MemoryViewAgent::fetchLazyData(Core::IEditor *editor, quint64 block, bool sync)
{
Q_UNUSED(sync); // FIXME: needed support for incremental searching
if (m_engine)
m_engine->fetchMemory(this, editor, BinBlockSize * block, BinBlockSize);
m_engine->fetchMemory(this, editor, BinBlockSize * block, BinBlockSize);
}
void MemoryViewAgent::addLazyData(QObject *editorToken, quint64 addr,
@@ -150,7 +152,7 @@ class LocationMark2 : public TextEditor::ITextMark
public:
LocationMark2() {}
QIcon icon() const { return DebuggerManager::instance()->locationMarkIcon(); }
QIcon icon() const { return DebuggerPlugin::instance()->locationMarkIcon(); }
void updateLineNumber(int /*lineNumber*/) {}
void updateBlock(const QTextBlock & /*block*/) {}
void removedFromEditor() {}
@@ -164,7 +166,7 @@ struct DisassemblerViewAgentPrivate
QPointer<TextEditor::ITextEditor> editor;
StackFrame frame;
bool tryMixed;
QPointer<DebuggerManager> manager;
QPointer<DebuggerEngine> engine;
LocationMark2 *locationMark;
QHash<QString, QString> cache;
};
@@ -201,12 +203,12 @@ private:
it handles communication between the engine and the editor.
*/
DisassemblerViewAgent::DisassemblerViewAgent(DebuggerManager *manager)
DisassemblerViewAgent::DisassemblerViewAgent(DebuggerEngine *engine)
: QObject(0), d(new DisassemblerViewAgentPrivate)
{
d->editor = 0;
d->locationMark = new LocationMark2();
d->manager = manager;
d->engine = engine;
}
DisassemblerViewAgent::~DisassemblerViewAgent()
@@ -261,16 +263,12 @@ void DisassemblerViewAgent::setFrame(const StackFrame &frame, bool tryMixed)
if (it != d->cache.end()) {
QString msg = _("Use cache disassembler for '%1' in '%2'")
.arg(frame.function).arg(frame.file);
QTC_ASSERT(d->manager->runControl(), /**/);
if (d->manager->runControl())
d->manager->runControl()->showMessage(msg);
d->engine->showMessage(msg);
setContents(*it);
return;
}
}
IDebuggerEngine *engine = d->manager->currentEngine();
QTC_ASSERT(engine, return);
engine->fetchDisassembler(this);
d->engine->fetchDisassembler(this);
}
void DisassemblerViewAgent::setContents(const QString &contents)
+11 -11
View File
@@ -34,15 +34,14 @@
#include <QtCore/QPointer>
namespace Core {
class IEditor;
class IEditor;
}
namespace Debugger {
class DebuggerManager;
namespace Debugger {
namespace Internal {
struct StackFrame;
class IDebuggerEngine;
struct DisassemblerViewAgentPrivate;
class DebuggerEngine;
class StackFrame;
class MemoryViewAgent : public QObject
{
@@ -50,8 +49,8 @@ class MemoryViewAgent : public QObject
public:
// Called from Gui
explicit MemoryViewAgent(DebuggerManager *manager, quint64 startaddr);
explicit MemoryViewAgent(DebuggerManager *manager, const QString &startaddr);
explicit MemoryViewAgent(DebuggerEngine *engine, quint64 startaddr);
explicit MemoryViewAgent(DebuggerEngine *engine, const QString &startaddr);
~MemoryViewAgent();
enum { BinBlockSize = 1024 };
@@ -65,19 +64,20 @@ public slots:
private:
Q_SLOT void createBinEditor(quint64 startAddr);
QPointer<IDebuggerEngine> m_engine;
QList<QPointer<Core::IEditor> > m_editors;
QPointer<DebuggerManager> m_manager;
QPointer<DebuggerEngine> m_engine;
};
class DisassemblerViewAgentPrivate;
class DisassemblerViewAgent : public QObject
{
Q_OBJECT
public:
// Called from Gui
explicit DisassemblerViewAgent(DebuggerManager *manager);
explicit DisassemblerViewAgent(DebuggerEngine *engine);
~DisassemblerViewAgent();
void setFrame(const StackFrame &frame, bool tryMixed = true);
+114 -18
View File
@@ -138,36 +138,132 @@ enum DebuggerCapabilities
enum LogChannel
{
LogInput, // Used for user input
LogMiscInput, // Used for misc stuff in the input pane
LogOutput,
LogWarning,
LogError,
LogStatus, // Used for status changed messages
LogTime, // Used for time stamp messages
LogDebug,
LogMisc,
AppOutput,
AppError,
StatusBar // LogStatus and also put to the status bar
};
LogInput, // Used for user input
LogMiscInput, // Used for misc stuff in the input pane
LogOutput,
LogWarning,
LogError,
LogStatus, // Used for status changed messages
LogTime, // Used for time stamp messages
LogDebug,
LogMisc,
AppOutput,
AppError,
AppStuff,
StatusBar // LogStatus and also put to the status bar
};
enum ModelRoles
{
DisplaySourceRole = 32, // Qt::UserRole
enum ModelRoles
{
DisplaySourceRole = 32, // Qt::UserRole,
EngineCapabilityRole,
EngineStateRole,
EngineCapabilitiesRole,
EngineActionsEnabledRole,
// Running
RequestExecContinueRole,
RequestExecInterruptRole,
RequestExecResetRole,
RequestExecStepRole,
RequestExecStepOutRole,
RequestExecNextRole,
RequestExecRunToLineRole,
RequestExecRunToFunctionRole,
RequestExecReturnFromFunctionRole,
RequestExecJumpToLineRole,
RequestExecWatchRole,
RequestExecSnapshotRole,
RequestExecFrameDownRole,
RequestExecFrameUpRole,
RequestExecDetachRole,
RequestExecExitRole,
RequestLoadSessionDataRole,
RequestSaveSessionDataRole,
// Breakpoints
BreakpointEnabledRole,
BreakpointUseFullPathRole,
BreakpointFunctionNameRole,
BreakpointFileNameRole,
BreakpointConditionRole,
BreakpointIgnoreCountRole,
BreakpointThreadSpecRole,
RequestActivateBreakpointRole,
RequestRemoveBreakpointRole,
RequestRemoveBreakpointByIndexRole,
RequestSynchronizeBreakpointsRole,
RequestBreakByFunctionRole,
RequestBreakByFunctionMainRole,
RequestFindSimilarBreakpointRole,
RequestAppendBreakpointRole,
RequestUpdateBreakpointRole,
// Locals and Watchers
LocalsINameRole,
LocalsExpressionRole,
LocalsExpandedRole, // The preferred expanded state to the view
LocalsTypeFormatListRole,
LocalsTypeFormatRole, // Used to communicate alternative formats to the view
LocalsIndividualFormatRole,
LocalsAddressRole, // Memory address of variable as quint64
LocalsRawValueRole, // Unformatted value as string
LocalsPointerValueRole, // Pointer value (address) as quint64
LocalsIsWatchpointAtAddressRole,
LocalsIsWatchpointAtPointerValueRole,
RequestToggleWatchRole,
RequestClearCppCodeModelSnapshotRole,
RequestAssignValueRole,
RequestAssignTypeRole,
// Stack
StackFrameAddressRole,
RequestActivateFrameRole,
RequestReloadFullStackRole,
RequestShowMemoryRole,
RequestShowDisassemblerRole,
// Threads
CurrentThreadIdRole,
RequestSelectThreadRole,
// Modules
RequestReloadModulesRole,
RequestModuleSymbolsRole,
RequestAllSymbolsRole,
RequestOpenFileRole,
// Registers
RegisterNumberBaseRole, // Currently used number base
RegisterAddressRole, // Start value for opening memory view
RegisterChangedRole, // Used for painting changed values
RequestSetRegisterRole,
RequestReloadRegistersRole,
// Snapshots
RequestMakeSnapshotRole,
RequestActivateSnapshotRole,
RequestRemoveSnapshotRole,
// Sources
RequestReloadSourceFilesRole,
};
enum DebuggerEngineType
{
NoEngineType = 0,
GdbEngineType = 0x01,
ScriptEngineType = 0x02,
CdbEngineType = 0x04,
PdbEngineType = 0x08,
TcfEngineType = 0x10,
QmlEngineType = 0x20,
AllEngineTypes = GdbEngineType
| ScriptEngineType
| CdbEngineType
| PdbEngineType
| TcfEngineType
| QmlEngineType
};
} // namespace Debugger
+943
View File
@@ -0,0 +1,943 @@
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (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 http://qt.nokia.com/contact.
**
**************************************************************************/
#include "debuggerengine.h"
#include "debuggeractions.h"
#include "debuggeragents.h"
#include "debuggerrunner.h"
#include "debuggeroutputwindow.h"
#include "debuggerplugin.h"
#include "debuggerstringutils.h"
#include "breakhandler.h"
#include "moduleshandler.h"
#include "registerhandler.h"
#include "snapshothandler.h"
#include "sourcefileshandler.h"
#include "stackhandler.h"
#include "threadshandler.h"
#include "watchhandler.h"
#include <projectexplorer/debugginghelper.h>
#include <projectexplorer/environment.h>
#include <projectexplorer/project.h>
#include <projectexplorer/projectexplorerconstants.h>
#include <projectexplorer/target.h>
#include <projectexplorer/buildconfiguration.h>
#include <projectexplorer/applicationrunconfiguration.h> // For LocalApplication*
#include <qt4projectmanager/qt4projectmanagerconstants.h>
#include <utils/savedaction.h>
#include <utils/qtcassert.h>
#include <coreplugin/icore.h>
#include <QtCore/QDebug>
#include <QtCore/QDir>
#include <QtCore/QFileInfo>
#include <QtCore/QTimer>
#include <QtGui/QAbstractItemView>
#include <QtGui/QStandardItemModel>
#include <QtGui/QAction>
#include <QtGui/QMessageBox>
#include <QtGui/QPushButton>
#include <QtGui/QTextDocument>
#include <QtGui/QTreeWidget>
using namespace ProjectExplorer;
using namespace Debugger;
using namespace Debugger::Internal;
///////////////////////////////////////////////////////////////////////
//
// DebuggerStartParameters
//
///////////////////////////////////////////////////////////////////////
DebuggerStartParameters::DebuggerStartParameters()
: attachPID(-1),
useTerminal(false),
breakAtMain(false),
toolChainType(ToolChain::UNKNOWN),
startMode(NoStartMode)
{}
void DebuggerStartParameters::clear()
{
*this = DebuggerStartParameters();
}
namespace Debugger {
QDebug operator<<(QDebug d, DebuggerState state)
{
return d << DebuggerEngine::stateName(state) << '(' << int(state) << ')';
}
QDebug operator<<(QDebug str, const DebuggerStartParameters &sp)
{
QDebug nospace = str.nospace();
const QString sep = QString(QLatin1Char(','));
nospace << "executable=" << sp.executable
<< " coreFile=" << sp.coreFile
<< " processArgs=" << sp.processArgs.join(sep)
<< " environment=<" << sp.environment.size() << " variables>"
<< " workingDir=" << sp.workingDirectory
<< " attachPID=" << sp.attachPID
<< " useTerminal=" << sp.useTerminal
<< " remoteChannel=" << sp.remoteChannel
<< " remoteArchitecture=" << sp.remoteArchitecture
<< " symbolFileName=" << sp.symbolFileName
<< " serverStartScript=" << sp.serverStartScript
<< " toolchain=" << sp.toolChainType << '\n';
return str;
}
namespace Internal {
const char *DebuggerEngine::stateName(int s)
{
# define SN(x) case x: return #x;
switch (s) {
SN(DebuggerNotReady)
SN(EngineStarting)
SN(AdapterStarting)
SN(AdapterStarted)
SN(AdapterStartFailed)
SN(InferiorStarting)
SN(InferiorStartFailed)
SN(InferiorRunningRequested)
SN(InferiorRunningRequested_Kill)
SN(InferiorRunning)
SN(InferiorUnrunnable)
SN(InferiorStopping)
SN(InferiorStopping_Kill)
SN(InferiorStopped)
SN(InferiorStopFailed)
SN(InferiorShuttingDown)
SN(InferiorShutDown)
SN(InferiorShutdownFailed)
SN(EngineShuttingDown)
}
return "<unknown>";
# undef SN
}
//////////////////////////////////////////////////////////////////////
//
// CommandHandler
//
//////////////////////////////////////////////////////////////////////
class CommandHandler : public QStandardItemModel
{
public:
CommandHandler(DebuggerEngine *engine) : m_engine(engine) {}
bool setData(const QModelIndex &index, const QVariant &value, int role);
QAbstractItemModel *model() { return this; }
private:
DebuggerEngine *m_engine;
};
bool CommandHandler::setData
(const QModelIndex &index, const QVariant &value, int role)
{
//qDebug() << "COMMAND: " << role << value;
Q_UNUSED(index);
Q_UNUSED(value);
switch (role) {
case RequestLoadSessionDataRole:
m_engine->loadSessionData();
return true;
case RequestSaveSessionDataRole:
m_engine->saveSessionData();
return true;
case RequestReloadSourceFilesRole:
m_engine->reloadSourceFiles();
return true;
case RequestReloadModulesRole:
m_engine->reloadModules();
return true;
case RequestExecContinueRole:
m_engine->continueInferior();
return true;
case RequestExecInterruptRole:
m_engine->interruptInferior();
return true;
case RequestExecResetRole:
//m_engine->exec();
return true;
case RequestExecStepRole:
m_engine->executeStepX();
return true;
case RequestExecStepOutRole:
m_engine->executeStepOutX();
return true;
case RequestExecNextRole:
m_engine->executeStepNextX();
return true;
case RequestExecRunToLineRole:
//m_engine->executeRunToLine();
QTC_ASSERT(false, /* FIXME ABC */);
return true;
case RequestExecRunToFunctionRole:
//m_engine->executeRunToFunction();
QTC_ASSERT(false, /* FIXME ABC */);
return true;
case RequestExecReturnFromFunctionRole:
m_engine->executeReturnX();
return true;
case RequestExecJumpToLineRole:
//m_engine->executeJumpToLine();
QTC_ASSERT(false, /* FIXME ABC */);
return true;
case RequestExecWatchRole:
//m_engine->exec();
QTC_ASSERT(false, /* FIXME ABC */);
return true;
case RequestExecExitRole:
m_engine->exitDebugger();
return true;
case RequestExecSnapshotRole:
m_engine->makeSnapshot();
return true;
case RequestExecFrameDownRole:
m_engine->frameDown();
return true;
case RequestExecFrameUpRole:
m_engine->frameUp();
return true;
}
return false;
}
//////////////////////////////////////////////////////////////////////
//
// DebuggerEnginePrivate
//
//////////////////////////////////////////////////////////////////////
class DebuggerEnginePrivate
{
public:
DebuggerEnginePrivate(DebuggerEngine *engine, const DebuggerStartParameters &sp)
: m_engine(engine),
m_runControl(0),
m_startParameters(sp),
m_state(DebuggerNotReady),
m_breakHandler(engine),
m_commandHandler(engine),
m_modulesHandler(engine),
m_registerHandler(engine),
m_snapshotHandler(engine),
m_sourceFilesHandler(engine),
m_stackHandler(engine),
m_threadsHandler(engine),
m_watchHandler(engine),
m_disassemblerViewAgent(engine)
{}
public:
DebuggerEngine *m_engine; // Not owned.
DebuggerRunControl *m_runControl; // Not owned.
DebuggerStartParameters m_startParameters;
DebuggerState m_state;
qint64 m_inferiorPid;
BreakHandler m_breakHandler;
CommandHandler m_commandHandler;
ModulesHandler m_modulesHandler;
RegisterHandler m_registerHandler;
SnapshotHandler m_snapshotHandler;
SourceFilesHandler m_sourceFilesHandler;
StackHandler m_stackHandler;
ThreadsHandler m_threadsHandler;
WatchHandler m_watchHandler;
DisassemblerViewAgent m_disassemblerViewAgent;
};
//////////////////////////////////////////////////////////////////////
//
// DebuggerEngine
//
//////////////////////////////////////////////////////////////////////
DebuggerEngine::DebuggerEngine(const DebuggerStartParameters &startParameters)
: d(new DebuggerEnginePrivate(this, startParameters))
{
//loadSessionData();
}
DebuggerEngine::~DebuggerEngine()
{
//saveSessionData();
}
/*
void DebuggerEngine::showStatusMessage(const QString &msg, int timeout)
{
plugin()->showStatusMessage(msg, timeout);
}
*/
void DebuggerEngine::showModuleSymbols
(const QString &moduleName, const Symbols &symbols)
{
QTreeWidget *w = new QTreeWidget;
w->setColumnCount(3);
w->setRootIsDecorated(false);
w->setAlternatingRowColors(true);
w->setSortingEnabled(true);
w->setHeaderLabels(QStringList() << tr("Symbol") << tr("Address") << tr("Code"));
w->setWindowTitle(tr("Symbols in \"%1\"").arg(moduleName));
foreach (const Symbol &s, symbols) {
QTreeWidgetItem *it = new QTreeWidgetItem;
it->setData(0, Qt::DisplayRole, s.name);
it->setData(1, Qt::DisplayRole, s.address);
it->setData(2, Qt::DisplayRole, s.state);
w->addTopLevelItem(it);
}
plugin()->createNewDock(w);
}
void DebuggerEngine::frameUp()
{
int currentIndex = stackHandler()->currentIndex();
activateFrame(qMin(currentIndex + 1, stackHandler()->stackSize() - 1));
}
void DebuggerEngine::frameDown()
{
int currentIndex = stackHandler()->currentIndex();
activateFrame(qMax(currentIndex - 1, 0));
}
ModulesHandler *DebuggerEngine::modulesHandler() const
{
return &d->m_modulesHandler;
}
BreakHandler *DebuggerEngine::breakHandler() const
{
return &d->m_breakHandler;
}
RegisterHandler *DebuggerEngine::registerHandler() const
{
return &d->m_registerHandler;
}
StackHandler *DebuggerEngine::stackHandler() const
{
return &d->m_stackHandler;
}
ThreadsHandler *DebuggerEngine::threadsHandler() const
{
return &d->m_threadsHandler;
}
WatchHandler *DebuggerEngine::watchHandler() const
{
return &d->m_watchHandler;
}
SnapshotHandler *DebuggerEngine::snapshotHandler() const
{
return &d->m_snapshotHandler;
}
SourceFilesHandler *DebuggerEngine::sourceFilesHandler() const
{
return &d->m_sourceFilesHandler;
}
QAbstractItemModel *DebuggerEngine::modulesModel() const
{
return d->m_modulesHandler.model();
}
QAbstractItemModel *DebuggerEngine::breakModel() const
{
return d->m_breakHandler.model();
}
QAbstractItemModel *DebuggerEngine::registerModel() const
{
return d->m_registerHandler.model();
}
QAbstractItemModel *DebuggerEngine::stackModel() const
{
return d->m_stackHandler.model();
}
QAbstractItemModel *DebuggerEngine::threadsModel() const
{
return d->m_threadsHandler.model();
}
QAbstractItemModel *DebuggerEngine::localsModel() const
{
return d->m_watchHandler.model(LocalsWatch);
}
QAbstractItemModel *DebuggerEngine::watchersModel() const
{
return d->m_watchHandler.model(WatchersWatch);
}
QAbstractItemModel *DebuggerEngine::returnModel() const
{
return d->m_watchHandler.model(ReturnWatch);
}
QAbstractItemModel *DebuggerEngine::snapshotModel() const
{
return d->m_snapshotHandler.model();
}
QAbstractItemModel *DebuggerEngine::sourceFilesModel() const
{
return d->m_sourceFilesHandler.model();
}
QAbstractItemModel *DebuggerEngine::commandModel() const
{
return d->m_commandHandler.model();
}
void DebuggerEngine::fetchMemory(MemoryViewAgent *, QObject *,
quint64 addr, quint64 length)
{
Q_UNUSED(addr);
Q_UNUSED(length);
}
void DebuggerEngine::setRegisterValue(int regnr, const QString &value)
{
Q_UNUSED(regnr);
Q_UNUSED(value);
}
void DebuggerEngine::showMessage(const QString &msg, int channel, int timeout) const
{
//qDebug() << channel << msg;
d->m_runControl->showMessage(msg, channel);
plugin()->showMessage(msg, channel, timeout);
}
void DebuggerEngine::startDebugger(DebuggerRunControl *runControl)
{
QTC_ASSERT(runControl, startFailed(); return);
QTC_ASSERT(!d->m_runControl, startFailed(); return);
DebuggerEngine *sessionTemplate = plugin()->sessionTemplate();
QTC_ASSERT(sessionTemplate, startFailed(); return);
QTC_ASSERT(sessionTemplate != this, startFailed(); return);
breakHandler()->initializeFromTemplate(sessionTemplate->breakHandler());
d->m_runControl = runControl;
QTC_ASSERT(state() == DebuggerNotReady, setState(DebuggerNotReady));
d->m_inferiorPid = d->m_startParameters.attachPID > 0
? d->m_startParameters.attachPID : 0;
if (d->m_startParameters.environment.empty())
d->m_startParameters.environment = Environment().toStringList();
if (d->m_startParameters.breakAtMain)
breakByFunctionMain();
const unsigned engineCapabilities = debuggerCapabilities();
theDebuggerAction(OperateByInstruction)
->setEnabled(engineCapabilities & DisassemblerCapability);
//loadSessionData();
startDebugger();
}
void DebuggerEngine::breakByFunctionMain()
{
#ifdef Q_OS_WIN
// FIXME: wrong on non-Qt based binaries
emit breakByFunction("qMain");
#else
emit breakByFunction("main");
#endif
}
void DebuggerEngine::breakByFunction(const QString &functionName)
{
d->m_breakHandler.breakByFunction(functionName);
attemptBreakpointSynchronization();
}
void DebuggerEngine::loadSessionData()
{
d->m_breakHandler.loadSessionData();
d->m_watchHandler.loadSessionData();
}
void DebuggerEngine::saveSessionData()
{
d->m_breakHandler.saveSessionData();
d->m_watchHandler.saveSessionData();
}
void DebuggerEngine::resetLocation()
{
d->m_disassemblerViewAgent.resetLocation();
d->m_stackHandler.setCurrentIndex(-1);
plugin()->resetLocation();
}
void DebuggerEngine::gotoLocation(const QString &fileName, int lineNumber, bool setMarker)
{
StackFrame frame;
frame.file = fileName;
frame.line = lineNumber;
gotoLocation(frame, setMarker);
}
void DebuggerEngine::gotoLocation(const StackFrame &frame, bool setMarker)
{
if (theDebuggerBoolSetting(OperateByInstruction) || !frame.isUsable()) {
if (setMarker)
plugin()->resetLocation();
d->m_disassemblerViewAgent.setFrame(frame);
} else {
plugin()->gotoLocation(frame.file, frame.line, setMarker);
}
}
void DebuggerEngine::executeStepX()
{
resetLocation();
if (theDebuggerBoolSetting(OperateByInstruction))
executeStepI();
else
executeStep();
}
void DebuggerEngine::executeStepOutX()
{
resetLocation();
executeStepOut();
}
void DebuggerEngine::executeStepNextX()
{
resetLocation();
if (theDebuggerBoolSetting(OperateByInstruction))
executeNextI();
else
executeNext();
}
void DebuggerEngine::executeReturnX()
{
resetLocation();
executeReturn();
}
void DebuggerEngine::executeWatchPointX()
{
if (QAction *action = qobject_cast<QAction *>(sender()))
watchPoint(action->data().toPoint());
}
/*
void DebuggerEngine::executeDebuggerCommand()
{
if (QAction *action = qobject_cast<QAction *>(sender()))
executeDebuggerCommand(action->data().toString());
}
void DebuggerManager::executeRunToLine()
{
ITextEditor *textEditor = d->m_plugin->currentTextEditor();
QTC_ASSERT(textEditor, return);
QString fileName = textEditor->file()->fileName();
int lineNumber = textEditor->currentLine();
if (d->m_engine && !fileName.isEmpty()) {
STATE_DEBUG(fileName << lineNumber);
resetLocation();
d->m_engine->executeRunToLine(fileName, lineNumber);
}
}
void DebuggerManager::executeRunToFunction()
{
ITextEditor *textEditor = d->m_plugin->currentTextEditor();
QTC_ASSERT(textEditor, return);
QString fileName = textEditor->file()->fileName();
QPlainTextEdit *ed = qobject_cast<QPlainTextEdit*>(textEditor->widget());
if (!ed)
return;
QTextCursor cursor = ed->textCursor();
QString functionName = cursor.selectedText();
if (functionName.isEmpty()) {
const QTextBlock block = cursor.block();
const QString line = block.text();
foreach (const QString &str, line.trimmed().split('(')) {
QString a;
for (int i = str.size(); --i >= 0; ) {
if (!str.at(i).isLetterOrNumber())
break;
a = str.at(i) + a;
}
if (!a.isEmpty()) {
functionName = a;
break;
}
}
}
STATE_DEBUG(functionName);
if (d->m_engine && !functionName.isEmpty()) {
resetLocation();
d->m_engine->executeRunToFunction(functionName);
}
}
void DebuggerManager::executeJumpToLine()
{
ITextEditor *textEditor = d->m_plugin->currentTextEditor();
QTC_ASSERT(textEditor, return);
QString fileName = textEditor->file()->fileName();
int lineNumber = textEditor->currentLine();
if (d->m_engine && !fileName.isEmpty()) {
STATE_DEBUG(fileName << lineNumber);
d->m_engine->executeJumpToLine(fileName, lineNumber);
}
}
*/
void DebuggerEngine::operateByInstructionTriggered()
{
StackFrame frame = d->m_stackHandler.currentFrame();
gotoLocation(frame, true);
}
void DebuggerEngine::cleanup()
{
/*
FIXME ABS: Still needed?
modulesHandler()->removeAll();
breakHandler()->setAllPending();
stackHandler()->removeAll();
threadsHandler()->removeAll();
watchHandler()->cleanup();
*/
}
const DebuggerStartParameters &DebuggerEngine::startParameters() const
{
return d->m_startParameters;
}
DebuggerStartParameters &DebuggerEngine::startParameters()
{
return d->m_startParameters;
}
//////////////////////////////////////////////////////////////////////
//
// Dumpers. "Custom dumpers" are a library compiled against the current
// Qt containing functions to evaluate values of Qt classes
// (such as QString, taking pointers to their addresses).
// The library must be loaded into the debuggee.
//
//////////////////////////////////////////////////////////////////////
bool DebuggerEngine::qtDumperLibraryEnabled() const
{
return theDebuggerBoolSetting(UseDebuggingHelpers);
}
QStringList DebuggerEngine::qtDumperLibraryLocations() const
{
if (theDebuggerAction(UseCustomDebuggingHelperLocation)->value().toBool()) {
const QString customLocation =
theDebuggerAction(CustomDebuggingHelperLocation)->value().toString();
const QString location =
tr("%1 (explicitly set in the Debugger Options)").arg(customLocation);
return QStringList(location);
}
return d->m_startParameters.dumperLibraryLocations;
}
void DebuggerEngine::showQtDumperLibraryWarning(const QString &details)
{
//QMessageBox dialog(d->m_mainWindow); // FIXME
QMessageBox dialog;
QPushButton *qtPref = dialog.addButton(tr("Open Qt preferences"),
QMessageBox::ActionRole);
QPushButton *helperOff = dialog.addButton(tr("Turn off helper usage"),
QMessageBox::ActionRole);
QPushButton *justContinue = dialog.addButton(tr("Continue anyway"),
QMessageBox::AcceptRole);
dialog.setDefaultButton(justContinue);
dialog.setWindowTitle(tr("Debugging helper missing"));
dialog.setText(tr("The debugger could not load the debugging helper library."));
dialog.setInformativeText(tr(
"The debugging helper is used to nicely format the values of some Qt "
"and Standard Library data types. "
"It must be compiled for each used Qt version separately. "
"This can be done in the Qt preferences page by selecting a Qt installation "
"and clicking on 'Rebuild' in the 'Debugging Helper' row."));
if (!details.isEmpty())
dialog.setDetailedText(details);
dialog.exec();
if (dialog.clickedButton() == qtPref) {
Core::ICore::instance()->showOptionsDialog(
_(Qt4ProjectManager::Constants::QT_SETTINGS_CATEGORY),
_(Qt4ProjectManager::Constants::QTVERSION_SETTINGS_PAGE_ID));
} else if (dialog.clickedButton() == helperOff) {
theDebuggerAction(UseDebuggingHelpers)
->setValue(qVariantFromValue(false), false);
}
}
QString DebuggerEngine::qtDumperLibraryName() const
{
if (theDebuggerAction(UseCustomDebuggingHelperLocation)->value().toBool())
return theDebuggerAction(CustomDebuggingHelperLocation)->value().toString();
return startParameters().dumperLibrary;
}
DebuggerState DebuggerEngine::state() const
{
return d->m_state;
}
static bool isAllowedTransition(int from, int to)
{
switch (from) {
case -1:
return to == DebuggerNotReady;
case DebuggerNotReady:
return to == EngineStarting || to == DebuggerNotReady;
case EngineStarting:
return to == AdapterStarting || to == DebuggerNotReady;
case AdapterStarting:
return to == AdapterStarted || to == AdapterStartFailed;
case AdapterStarted:
return to == InferiorStarting || to == EngineShuttingDown;
case AdapterStartFailed:
return to == DebuggerNotReady;
case InferiorStarting:
return to == InferiorRunningRequested || to == InferiorStopped
|| to == InferiorStartFailed || to == InferiorUnrunnable;
case InferiorStartFailed:
return to == EngineShuttingDown;
case InferiorRunningRequested:
return to == InferiorRunning || to == InferiorStopped
|| to == InferiorRunningRequested_Kill;
case InferiorRunningRequested_Kill:
return to == InferiorRunning || to == InferiorStopped;
case InferiorRunning:
return to == InferiorStopping;
case InferiorStopping:
return to == InferiorStopped || to == InferiorStopFailed
|| to == InferiorStopping_Kill;
case InferiorStopping_Kill:
return to == InferiorStopped || to == InferiorStopFailed;
case InferiorStopped:
return to == InferiorRunningRequested || to == InferiorShuttingDown;
case InferiorStopFailed:
return to == EngineShuttingDown;
case InferiorUnrunnable:
return to == EngineShuttingDown;
case InferiorShuttingDown:
return to == InferiorShutDown || to == InferiorShutdownFailed;
case InferiorShutDown:
return to == EngineShuttingDown;
case InferiorShutdownFailed:
return to == EngineShuttingDown;
case EngineShuttingDown:
return to == DebuggerNotReady;
}
qDebug() << "UNKNOWN STATE:" << from;
return false;
}
void DebuggerEngine::setState(DebuggerState state, bool forced)
{
//qDebug() << "STATUS CHANGE: FROM " << stateName(d->m_state)
// << " TO " << stateName(state);
QString msg = _("State changed from %1(%2) to %3(%4).")
.arg(stateName(d->m_state)).arg(d->m_state).arg(stateName(state)).arg(state);
//if (!((d->m_state == -1 && state == 0) || (d->m_state == 0 && state == 0)))
// qDebug() << msg;
if (!forced && !isAllowedTransition(d->m_state, state))
qDebug() << "UNEXPECTED STATE TRANSITION: " << msg;
showMessage(msg, LogDebug);
//resetLocation();
if (state == d->m_state)
return;
d->m_state = state;
plugin()->updateState(this);
if (d->m_state == DebuggerNotReady) {
saveSessionData();
d->m_runControl->debuggingFinished();
}
}
bool DebuggerEngine::debuggerActionsEnabled() const
{
return debuggerActionsEnabled(d->m_state);
}
bool DebuggerEngine::debuggerActionsEnabled(DebuggerState state)
{
switch (state) {
case InferiorStarting:
case InferiorRunningRequested:
case InferiorRunning:
case InferiorUnrunnable:
case InferiorStopping:
case InferiorStopped:
return true;
case DebuggerNotReady:
case EngineStarting:
case AdapterStarting:
case AdapterStarted:
case AdapterStartFailed:
case InferiorStartFailed:
case InferiorRunningRequested_Kill:
case InferiorStopping_Kill:
case InferiorStopFailed:
case InferiorShuttingDown:
case InferiorShutDown:
case InferiorShutdownFailed:
case EngineShuttingDown:
break;
}
return false;
}
void DebuggerEngine::startFailed()
{
// The concrete engines themselves are responsible for changing state.
QTC_ASSERT(state() == DebuggerNotReady, setState(DebuggerNotReady));
d->m_runControl->startFailed();
}
void DebuggerEngine::startSuccessful()
{
d->m_runControl->startSuccessful();
}
void DebuggerEngine::notifyInferiorPid(qint64 pid)
{
//STATE_DEBUG(d->m_inferiorPid << pid);
if (d->m_inferiorPid == pid)
return;
d->m_inferiorPid = pid;
QTimer::singleShot(0, this, SLOT(raiseApplication()));
}
qint64 DebuggerEngine::inferiorPid() const
{
return d->m_inferiorPid;
}
DebuggerPlugin *DebuggerEngine::plugin() const
{
return DebuggerPlugin::instance();
}
void DebuggerEngine::raiseApplication()
{
d->m_runControl->bringApplicationToForeground(d->m_inferiorPid);
}
void DebuggerEngine::openFile(const QString &fileName, int lineNumber)
{
plugin()->gotoLocation(fileName, lineNumber, false);
}
bool DebuggerEngine::isReverseDebugging() const
{
return plugin()->isReverseDebugging();
}
} // namespace Internal
} // namespace Debugger
+273
View File
@@ -0,0 +1,273 @@
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (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 http://qt.nokia.com/contact.
**
**************************************************************************/
#ifndef DEBUGGER_DEBUGGERENGINE_H
#define DEBUGGER_DEBUGGERENGINE_H
#include "debugger_global.h"
#include "debuggerconstants.h"
#include "moduleshandler.h" // For 'Symbols'
#include <coreplugin/ssh/sshconnection.h>
#include <QtCore/QObject>
#include <QtCore/QSharedPointer>
#include <QtCore/QStringList>
QT_BEGIN_NAMESPACE
class QDebug;
class QPoint;
QT_END_NAMESPACE
namespace TextEditor {
class ITextEditor;
}
namespace Core {
class IOptionsPage;
}
namespace Debugger {
class DebuggerRunControl;
class DebuggerPlugin;
class DEBUGGER_EXPORT DebuggerStartParameters
{
public:
DebuggerStartParameters();
void clear();
QString executable;
QString displayName;
QString coreFile;
QStringList processArgs;
QStringList environment;
QString workingDirectory;
qint64 attachPID;
bool useTerminal;
bool breakAtMain;
QString crashParameter; // for AttachCrashedExternal
// for remote debugging
QString remoteChannel;
QString remoteArchitecture;
QString symbolFileName;
QString serverStartScript;
QString sysRoot;
QString debuggerCommand;
int toolChainType;
QByteArray remoteDumperLib;
QString qtInstallPath;
QString dumperLibrary;
QStringList dumperLibraryLocations;
Core::SshServerInfo sshserver;
DebuggerStartMode startMode;
};
DEBUGGER_EXPORT QDebug operator<<(QDebug str, const DebuggerStartParameters &);
DEBUGGER_EXPORT QDebug operator<<(QDebug str, DebuggerState state);
namespace Internal {
class DisassemblerViewAgent;
class MemoryViewAgent;
class Symbol;
class WatchData;
class BreakHandler;
class ModulesHandler;
class RegisterHandler;
class StackHandler;
class StackFrame;
class SnapshotHandler;
class SourceFilesHandler;
class ThreadsHandler;
class WatchHandler;
class DebuggerEnginePrivate;
class DebuggerEngine : public QObject
{
Q_OBJECT
public:
DebuggerEngine(const DebuggerStartParameters &sp);
virtual ~DebuggerEngine();
virtual void shutdown() {}
virtual void setToolTipExpression(const QPoint &mousePos,
TextEditor::ITextEditor *editor, int cursorPos)
{ Q_UNUSED(mousePos); Q_UNUSED(editor); Q_UNUSED(cursorPos); }
void initializeFromTemplate(DebuggerEngine *other);
void startDebugger(DebuggerRunControl *runControl);
virtual void startDebugger() {}
virtual void exitDebugger() {}
virtual void abortDebugger() { exitDebugger(); }
virtual void detachDebugger() {}
virtual void updateWatchData(const WatchData &data)
{ Q_UNUSED(data); }
virtual void executeStep() {}
virtual void executeStepOut() {}
virtual void executeNext() {}
virtual void executeStepI() {}
virtual void executeNextI() {}
virtual void executeReturn() {}
virtual void continueInferior() {}
virtual void interruptInferior() {}
virtual void executeRunToLine(const QString &fileName, int lineNumber)
{ Q_UNUSED(fileName); Q_UNUSED(lineNumber); }
virtual void executeRunToFunction(const QString &functionName)
{ Q_UNUSED(functionName); }
virtual void executeJumpToLine(const QString &fileName, int lineNumber)
{ Q_UNUSED(fileName); Q_UNUSED(lineNumber); }
virtual void assignValueInDebugger(const QString &expr, const QString &value)
{ Q_UNUSED(expr); Q_UNUSED(value); }
virtual void executeDebuggerCommand(const QString &command)
{ Q_UNUSED(command); }
virtual void activateFrame(int index) { Q_UNUSED(index); }
virtual void frameUp();
virtual void frameDown();
virtual void selectThread(int index) { Q_UNUSED(index); }
virtual void makeSnapshot() {}
virtual void activateSnapshot(int index) { Q_UNUSED(index); }
virtual void attemptBreakpointSynchronization() {}
virtual void reloadModules() {}
virtual void loadSymbols(const QString &moduleName)
{ Q_UNUSED(moduleName); }
virtual void loadAllSymbols() {}
virtual void requestModuleSymbols(const QString &moduleName)
{ Q_UNUSED(moduleName); }
virtual void reloadRegisters() {}
virtual void reloadSourceFiles() {}
virtual void reloadFullStack() {}
virtual void watchPoint(const QPoint &) {}
virtual void fetchMemory(MemoryViewAgent *, QObject *,
quint64 addr, quint64 length);
virtual void fetchDisassembler(DisassemblerViewAgent *) {}
virtual void setRegisterValue(int regnr, const QString &value);
virtual void addOptionPages(QList<Core::IOptionsPage*> *) const {}
virtual unsigned debuggerCapabilities() const { return 0; }
virtual bool isSynchroneous() const { return false; }
virtual QString qtNamespace() const { return QString(); }
public slots:
// Convenience
void showMessage(const QString &msg, int channel = LogDebug, int timeout = -1) const;
void showStatusMessage(const QString &msg, int timeout = -1) const
{ showMessage(msg, StatusBar, timeout); }
public:
DebuggerPlugin *plugin() const;
const DebuggerStartParameters &startParameters() const;
DebuggerStartParameters &startParameters();
ModulesHandler *modulesHandler() const;
BreakHandler *breakHandler() const;
RegisterHandler *registerHandler() const;
StackHandler *stackHandler() const;
ThreadsHandler *threadsHandler() const;
WatchHandler *watchHandler() const;
SnapshotHandler *snapshotHandler() const;
SourceFilesHandler *sourceFilesHandler() const;
QAbstractItemModel *commandModel() const;
QAbstractItemModel *modulesModel() const;
QAbstractItemModel *breakModel() const;
QAbstractItemModel *registerModel() const;
QAbstractItemModel *stackModel() const;
QAbstractItemModel *threadsModel() const;
QAbstractItemModel *localsModel() const;
QAbstractItemModel *watchersModel() const;
QAbstractItemModel *returnModel() const;
QAbstractItemModel *snapshotModel() const;
QAbstractItemModel *sourceFilesModel() const;
void cleanup();
bool debuggerActionsEnabled() const;
static bool debuggerActionsEnabled(DebuggerState state);
void showModuleSymbols(const QString &moduleName, const Symbols &symbols);
void breakByFunction(const QString &functionName);
void breakByFunctionMain();
void loadSessionData();
void saveSessionData();
void executeStepX();
void executeStepOutX();
void executeStepNextX();
void executeReturnX();
void executeWatchPointX();
void operateByInstructionTriggered();
DebuggerState state() const;
// Dumper stuff (common to cdb and gdb).
bool qtDumperLibraryEnabled() const;
QString qtDumperLibraryName() const;
QStringList qtDumperLibraryLocations() const;
void showQtDumperLibraryWarning(const QString &details = QString());
static const char *stateName(int s);
void notifyInferiorPid(qint64 pid);
qint64 inferiorPid() const;
bool isReverseDebugging() const;
public slots:
void resetLocation();
void openFile(const QString &fileName, int lineNumber = -1);
void gotoLocation(const QString &fileName, int lineNumber, bool setMarker);
void gotoLocation(const StackFrame &frame, bool setMarker);
void startSuccessful();
void startFailed();
void raiseApplication();
void quitDebugger() { exitDebugger(); }
protected:
void setState(DebuggerState state, bool forced = false);
DebuggerEnginePrivate *d;
};
} // namespace Internal
} // namespace Debugger
#endif // DEBUGGER_DEBUGGERENGINE_H
+4 -3
View File
@@ -39,11 +39,12 @@ class DebuggerUISwitcher;
namespace Internal {
class DebugToolWindow {
class DebugToolWindow
{
public:
DebugToolWindow() : m_visible(false) {}
QDockWidget* m_dockWidget;
DebugToolWindow() : m_dockWidget(0), m_languageId(-1), m_visible(false) {}
QDockWidget *m_dockWidget;
int m_languageId;
bool m_visible;
};
File diff suppressed because it is too large Load Diff
-321
View File
@@ -1,321 +0,0 @@
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (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 http://qt.nokia.com/contact.
**
**************************************************************************/
#ifndef DEBUGGER_DEBUGGERMANAGER_H
#define DEBUGGER_DEBUGGERMANAGER_H
#include "debugger_global.h"
#include "debuggerconstants.h"
#include "debuggerrunner.h"
#include <QtCore/QObject>
#include <QtCore/QSharedPointer>
#include <QtCore/QStringList>
#include <QtCore/QVariant>
QT_BEGIN_NAMESPACE
class QAbstractItemModel;
class QAbstractItemView;
class QAction;
class QDebug;
class QDockWidget;
class QLabel;
class QMessageBox;
class QPoint;
class QIcon;
QT_END_NAMESPACE
namespace Core {
class IOptionsPage;
}
namespace TextEditor {
class ITextEditor;
class FontSettings;
}
namespace CPlusPlus {
class Snapshot;
}
namespace Debugger {
namespace Internal {
class DebuggerOutputWindow;
class DebuggerPlugin;
class BreakpointData;
class SourceFilesWindow;
struct StackFrame;
class Symbol;
class WatchData;
class WatchHandler;
class IDebuggerEngine;
class GdbEngine;
class ScriptEngine;
class PdbEngine;
class CdbDebugEngine;
class CdbDebugEnginePrivate;
struct DebuggerManagerActions;
class CdbDebugEventCallback;
class CdbDumperHelper;
class CdbDumperInitThread;
class CdbExceptionLoggerEventCallback;
class GdbEngine;
class TcfEngine;
class QmlEngine;
class CdbDebugEngine;
class CdbDebugEnginePrivate;
class TrkGdbAdapter;
class BreakpointMarker;
} // namespace Internal
// Flags for initialization
enum DebuggerEngineTypeFlags
{
GdbEngineType = 0x01,
ScriptEngineType = 0x02,
CdbEngineType = 0x04,
PdbEngineType = 0x08,
TcfEngineType = 0x10,
QmlEngineType = 0x20,
AllEngineTypes = GdbEngineType
| ScriptEngineType
| CdbEngineType
| PdbEngineType
| TcfEngineType
| QmlEngineType
};
QDebug operator<<(QDebug d, DebuggerState state);
//
// DebuggerManager
//
struct DebuggerManagerPrivate;
class DEBUGGER_EXPORT DebuggerManager : public QObject
{
Q_OBJECT
public:
explicit DebuggerManager(Internal::DebuggerPlugin *plugin);
~DebuggerManager();
friend class Internal::IDebuggerEngine;
friend class Internal::DebuggerPlugin;
friend class Internal::CdbDebugEventCallback;
friend class Internal::CdbDumperHelper;
friend class Internal::CdbDumperInitThread;
friend class Internal::CdbExceptionLoggerEventCallback;
friend class Internal::GdbEngine;
friend class Internal::ScriptEngine;
friend class Internal::PdbEngine;
friend class Internal::TcfEngine;
friend class Internal::QmlEngine;
friend class Internal::CdbDebugEngine;
friend class Internal::CdbDebugEnginePrivate;
friend class Internal::TrkGdbAdapter;
friend class Internal::BreakpointMarker;
DebuggerState state() const;
QList<Core::IOptionsPage*> initializeEngines(unsigned enabledTypeFlags);
QLabel *statusLabel() const;
Internal::IDebuggerEngine *currentEngine() const;
DebuggerRunControl *runControl() const;
QMessageBox *showMessageBox(int icon, const QString &title, const QString &text,
int buttons = 0);
bool debuggerActionsEnabled() const;
unsigned debuggerCapabilities() const;
bool checkDebugConfiguration(int toolChain,
QString *errorMessage,
QString *settingsCategory = 0,
QString *settingsPage = 0) const;
const CPlusPlus::Snapshot &cppCodeModelSnapshot() const;
QIcon locationMarkIcon() const;
static DebuggerManager *instance();
void startNewDebugger(DebuggerRunControl *runControl);
public slots:
void exitDebugger();
void abortDebugger();
void setSimpleDockWidgetArrangement(const QString &activeLanguage);
void setBusyCursor(bool on);
void gotoLocation(const Debugger::Internal::StackFrame &frame, bool setLocationMarker);
void fileOpen(const QString &file);
void resetLocation();
void interruptDebuggingRequest();
void executeJumpToLine();
void executeRunToLine();
void executeRunToFunction();
void breakByFunction(const QString &functionName);
void breakByFunctionMain();
void activateFrame(int index);
void selectThread(int index);
void executeStep();
void executeStepOut();
void executeStepNext();
void executeContinue();
void executeReturn();
void detachDebugger();
void frameUp();
void frameDown();
void addToWatchWindow();
void updateWatchData(const Debugger::Internal::WatchData &data);
void sessionLoaded();
void aboutToUnloadSession();
void aboutToSaveSession();
QVariant sessionValue(const QString &name);
void setSessionValue(const QString &name, const QVariant &value);
void assignValueInDebugger();
void assignValueInDebugger(const QString &expr, const QString &value);
void executeDebuggerCommand();
void executeDebuggerCommand(const QString &command);
void watchPoint();
void setRegisterValue(int nr, const QString &value);
void showStatusMessage(const QString &msg, int timeout = -1); // -1 forever
void clearCppCodeModelSnapshot();
static const char *stateName(int s);
public slots: // FIXME
void ensureLogVisible();
void updateWatchersWindow();
void updateWatchersHeader(int section, int oldSize, int newSize);
void activateBreakpoint(int index);
//private slots: // FIXME
void reloadSourceFiles();
void sourceFilesDockToggled(bool on);
void reloadModules();
void modulesDockToggled(bool on);
void loadSymbols(const QString &moduleName);
void loadAllSymbols();
void reloadRegisters();
void registerDockToggled(bool on);
void clearStatusMessage();
void attemptBreakpointSynchronization();
void reloadFullStack();
void operateByInstructionTriggered();
void startFailed();
// Called from global action.
void makeSnapshot();
friend class DebuggerRunControl;
public:
Internal::BreakHandler *breakHandler() const;
Internal::StackHandler *stackHandler() const;
Internal::ThreadsHandler *threadsHandler() const;
Internal::WatchHandler *watchHandler() const;
Internal::DebuggerOutputWindow *debuggerOutputWindow() const;
private:
Internal::SourceFilesWindow *sourceFileWindow() const;
QAbstractItemView *modulesWindow() const;
QAbstractItemView *registerWindow() const;
QAbstractItemView *snapshotWindow() const;
QWidget *threadsWindow() const;
Internal::DebuggerManagerActions debuggerManagerActions() const;
void notifyInferiorStopped();
void notifyInferiorRunning();
void notifyInferiorExited();
void cleanupViews();
void setState(DebuggerState state, bool forced = false);
//
// internal implementation
//
bool qtDumperLibraryEnabled() const;
QString qtDumperLibraryName() const;
QStringList qtDumperLibraryLocations() const;
void showQtDumperLibraryWarning(const QString &details = QString());
bool isReverseDebugging() const;
QAbstractItemModel *threadsModel();
Q_SLOT void loadSessionData();
Q_SLOT void saveSessionData();
Q_SLOT void dumpLog();
Q_SLOT void fontSettingsChanged(const TextEditor::FontSettings &settings);
signals:
void debuggingFinished();
void stateChanged(int newstatus);
void statusMessageRequested(const QString &msg, int timeout); // -1 for 'forever'
void applicationOutputAvailable(const QString &output, bool onStdErr);
void messageAvailable(const QString &output, bool isError);
private:
void init();
// void runTest(const QString &fileName);
void showMessage(const QString &msg, int channel);
Q_SLOT void createNewDock(QWidget *widget);
void aboutToShutdown();
//void toggleBreakpoint(const QString &fileName, int lineNumber);
void setToolTipExpression(const QPoint &mousePos,
TextEditor::ITextEditor *editor, int cursorPos);
void openTextEditor(const QString &titlePattern,
const QString &contents);
DebuggerManagerPrivate *d;
};
} // namespace Debugger
#endif // DEBUGGER_DEBUGGERMANAGER_H
@@ -28,8 +28,9 @@
**************************************************************************/
#include "debuggeroutputwindow.h"
#include "debuggeractions.h"
#include "debuggermanager.h"
#include "debuggerconstants.h"
#include <QtCore/QDebug>
#include <QtCore/QFile>
File diff suppressed because it is too large Load Diff
+76 -93
View File
@@ -30,138 +30,121 @@
#ifndef DEBUGGERPLUGIN_H
#define DEBUGGERPLUGIN_H
#include "debugger_global.h"
#include <extensionsystem/iplugin.h>
#include <QtCore/QObject>
QT_BEGIN_NAMESPACE
class QAction;
class QComboBox;
class QMenu;
class QPoint;
class QToolButton;
class QAbstractItemView;
class QIcon;
class QMessageBox;
QT_END_NAMESPACE
namespace Core {
class IEditor;
class IMode;
namespace CPlusPlus {
class Snapshot;
}
namespace TextEditor {
class ITextEditor;
class ITextMark;
class BaseTextMark;
namespace ProjectExplorer {
class RunControl;
}
namespace Debugger {
class DebuggerManager;
class DebuggerUISwitcher;
class DebuggerRunControlFactory;
class DebuggerPluginPrivate;
class DebuggerRunControl;
class DebuggerStartParameters;
namespace Internal {
class DebuggerEngine;
class DebuggerListener;
}
class BreakpointData;
class DebugMode;
class DebuggerPlugin : public ExtensionSystem::IPlugin
class DEBUGGER_EXPORT DebuggerPlugin : public ExtensionSystem::IPlugin
{
Q_OBJECT
public:
struct AttachRemoteParameters {
AttachRemoteParameters();
quint64 attachPid;
QString attachCore;
// Event handle for attaching to crashed Windows processes.
quint64 winCrashEvent;
};
DebuggerPlugin();
~DebuggerPlugin();
private:
bool initialize(const QStringList &arguments, QString *error_message);
void aboutToShutdown();
void extensionsInitialized();
void remoteCommand(const QStringList &options, const QStringList &arguments);
static DebuggerPlugin *instance();
QVariant configValue(const QString &name) const;
TextEditor::ITextEditor *currentTextEditor();
QVariant sessionValue(const QString &name);
void setSessionValue(const QString &name, const QVariant &value);
void setConfigValue(const QString &name, const QVariant &value);
private slots:
void activatePreviousMode();
void activateDebugMode();
void editorOpened(Core::IEditor *editor);
void editorAboutToClose(Core::IEditor *editor);
void handleStateChanged(int state);
void requestMark(TextEditor::ITextEditor *editor, int lineNumber);
void showToolTip(TextEditor::ITextEditor *editor, const QPoint &pnt, int pos);
void requestContextMenu(TextEditor::ITextEditor *editor,
int lineNumber, QMenu *menu);
void resetLocation();
void gotoLocation(const QString &fileName, int lineNumber, bool setMarker);
void activatePreviousMode();
void activateDebugMode();
void openTextEditor(const QString &titlePattern, const QString &contents);
void toggleBreakpoint();
void toggleBreakpoint(const QString &fileName, int lineNumber);
void breakpointSetRemoveMarginActionTriggered();
void breakpointEnableDisableMarginActionTriggered();
void onModeChanged(Core::IMode *mode);
void showSettingsDialog();
void startExternalApplication();
void startRemoteApplication();
void attachExternalApplication();
void attachCore();
void attachCmdLine();
void attachRemoteTcf();
void enableReverseDebuggingTriggered(const QVariant &value);
void languageChanged(const QString &debuggerLanguage);
private:
void readSettings();
void writeSettings() const;
void attachExternalApplication(qint64 pid,
const QString &binary,
const QString &crashParameter);
void attachCore(const QString &core, const QString &exeFileName);
friend class Debugger::DebuggerManager;
friend class GdbOptionPage;
friend class DebuggingHelperOptionPage;
// FIXME: Just a hack now so that it can access the views.
friend class Debugger::Internal::DebugMode;
static ProjectExplorer::RunControl *createDebugger
(const DebuggerStartParameters &sp);
static void startDebugger(ProjectExplorer::RunControl *runControl);
DebuggerUISwitcher *m_uiSwitcher;
DebuggerManager *m_manager;
DebugMode *m_debugMode;
DebuggerRunControlFactory *m_debuggerRunControlFactory;
QMessageBox *showMessageBox(int icon, const QString &title,
const QString &text, int buttons = 0);
QString m_previousMode;
TextEditor::BaseTextMark *m_locationMark;
int m_gdbRunningContext;
AttachRemoteParameters m_attachRemoteParameters;
unsigned m_cmdLineEnabledEngines;
const CPlusPlus::Snapshot &cppCodeModelSnapshot() const;
QAction *m_startExternalAction;
QAction *m_startRemoteAction;
QAction *m_attachExternalAction;
QAction *m_attachCoreAction;
QAction *m_attachTcfAction;
QAction *m_detachAction;
QComboBox *m_langBox;
QToolButton *m_reverseToolButton;
QIcon locationMarkIcon() const;
int state() const; // Last reported state of last active engine.
bool isReverseDebugging() const;
void createNewDock(QWidget *widget);
void runControlStarted(DebuggerRunControl *runControl);
void runControlFinished(DebuggerRunControl *runControl);
// This contains per-session data like breakpoints and watched
// expression. It serves as a template for new engine instantiations.
Internal::DebuggerEngine *sessionTemplate();
public slots:
void exitDebugger(); // FIXME: remove
void setBusyCursor(bool on);
void interruptDebuggingRequest();
void detachDebugger();
void addToWatchWindow();
void executeDebuggerCommand();
void executeDebuggerCommand(const QString &command);
void watchPoint();
void clearCppCodeModelSnapshot();
void ensureLogVisible();
void updateWatchersWindow(bool showWatchers, bool showReturn);
// void runTest(const QString &fileName);
void showMessage(const QString &msg, int channel, int timeout = -1);
signals:
void stateChanged(int);
private:
friend class Internal::DebuggerEngine;
friend class Internal::DebuggerListener
;
bool initialize(const QStringList &arguments, QString *errorMessage);
void aboutToShutdown();
void extensionsInitialized();
void remoteCommand(const QStringList &options, const QStringList &arguments);
void updateState(Internal::DebuggerEngine *engine);
void showStatusMessage(const QString &msg, int timeout = -1); // -1 forever
QWidget *mainWindow() const;
private:
friend class DebuggerPluginPrivate;
DebuggerPluginPrivate *d;
};
} // namespace Internal
} // namespace Debugger
#endif // DEBUGGERPLUGIN_H
+322 -287
View File
@@ -28,19 +28,12 @@
**************************************************************************/
#include "debuggerrunner.h"
#include "debuggermanager.h"
#include "debuggeroutputwindow.h"
#include "idebuggerengine.h"
#include "breakhandler.h"
#include "moduleshandler.h"
#include "registerhandler.h"
#include "snapshothandler.h"
#include "stackhandler.h"
#include "stackframe.h"
#include "threadshandler.h"
#include "watchhandler.h"
#include "debuggeractions.h"
#include "debuggerconstants.h"
#include "debuggerengine.h"
#include "debuggerplugin.h"
#include "debuggerstringutils.h"
#include <projectexplorer/debugginghelper.h>
#include <projectexplorer/environment.h>
@@ -65,6 +58,38 @@
using namespace ProjectExplorer;
using namespace Debugger::Internal;
namespace Debugger {
namespace Internal {
DebuggerEngine *createGdbEngine(const DebuggerStartParameters &);
DebuggerEngine *createScriptEngine(const DebuggerStartParameters &);
DebuggerEngine *createPdbEngine(const DebuggerStartParameters &);
DebuggerEngine *createTcfEngine(const DebuggerStartParameters &);
DebuggerEngine *createQmlEngine(const DebuggerStartParameters &);
#ifdef CDB_ENABLED
DebuggerEngine *createCdbEngine(const DebuggerStartParameters &);
#else
DebuggerEngine *createCdbEngine(const DebuggerStartParameters &) { return 0; }
#endif
// FIXME: Outdated?
// The createCdbEngine function takes a list of options pages it can add to.
// This allows for having a "enabled" toggle on the page independently
// of the engine. That's good for not enabling the related ActiveX control
// unnecessarily.
bool checkGdbConfiguration(int toolChain, QString *errorMsg, QString *settingsPage);
bool checkCdbConfiguration(int toolChain, QString *errorMsg, QString *settingsPage);
}
static QString toolChainName(int toolChainType)
{
return ToolChain::toolChainName(ToolChain::ToolChainType(toolChainType));
}
////////////////////////////////////////////////////////////////////////
//
@@ -72,11 +97,18 @@ using namespace Debugger::Internal;
//
////////////////////////////////////////////////////////////////////////
namespace Debugger {
static QString msgEngineNotAvailable(const char *engine)
{
return DebuggerPlugin::tr("The application requires the debugger engine '%1', "
"which is disabled.").arg(QLatin1String(engine));
}
static DebuggerPlugin *plugin() { return DebuggerPlugin::instance(); }
// A factory to create DebuggerRunControls
DebuggerRunControlFactory::DebuggerRunControlFactory(DebuggerManager *manager)
: m_manager(manager)
DebuggerRunControlFactory::DebuggerRunControlFactory(QObject *parent,
DebuggerEngineType enabledEngines)
: IRunControlFactory(parent), m_enabledEngines(enabledEngines)
{}
bool DebuggerRunControlFactory::canRun(RunConfiguration *runConfiguration, const QString &mode) const
@@ -131,12 +163,22 @@ RunControl *DebuggerRunControlFactory::create
{
QTC_ASSERT(mode == ProjectExplorer::Constants::DEBUGMODE, return 0);
DebuggerStartParameters sp = localStartParameters(runConfiguration);
return new DebuggerRunControl(m_manager, sp);
return create(sp);
}
RunControl *DebuggerRunControlFactory::create(const DebuggerStartParameters &sp)
{
return new DebuggerRunControl(m_manager, sp);
DebuggerRunControl *runControl = new DebuggerRunControl;
runControl->setEnabledEngines(m_enabledEngines);
runControl->createEngine(sp);
if (!runControl->engine()) {
qDebug() << "FAILED TO CREATE ENGINE";
delete runControl;
return 0;
}
connect(runControl, SIGNAL(started()), runControl, SLOT(handleStarted()));
connect(runControl, SIGNAL(finished()), runControl, SLOT(handleFinished()));
return runControl;
}
QWidget *DebuggerRunControlFactory::createConfigurationWidget(RunConfiguration *runConfiguration)
@@ -147,342 +189,335 @@ QWidget *DebuggerRunControlFactory::createConfigurationWidget(RunConfiguration *
}
////////////////////////////////////////////////////////////////////////
//
// DebuggerRunControl::Private
//
////////////////////////////////////////////////////////////////////////
class DebuggerRunControl::Private
{
public:
Private(DebuggerRunControl *parent, DebuggerManager *manager,
const DebuggerStartParameters &startParameters);
~Private();
public:
DebuggerRunControl *q;
DebuggerStartParameters m_startParameters;
DebuggerManager *m_manager;
Internal::IDebuggerEngine *m_engine;
bool m_running;
qint64 m_inferiorPid;
ModulesHandler *m_modulesHandler;
RegisterHandler *m_registerHandler;
SnapshotHandler *m_snapshotHandler;
/*
// FIXME: Move from DebuggerManager
BreakHandler *m_breakHandler;
StackHandler *m_stackHandler;
ThreadsHandler *m_threadsHandler;
WatchHandler *m_watchHandler;
*/
};
DebuggerRunControl::Private::Private(DebuggerRunControl *parent,
DebuggerManager *manager,
const DebuggerStartParameters &startParameters)
: q(parent),
m_startParameters(startParameters),
m_manager(manager),
m_engine(0)
{
m_running = false;
m_inferiorPid = m_startParameters.attachPID > 0 ? m_startParameters.attachPID : 0;
m_modulesHandler = new ModulesHandler(q);
m_registerHandler = new RegisterHandler();
m_snapshotHandler = new SnapshotHandler(q);
}
DebuggerRunControl::Private::~Private()
{
#define doDelete(ptr) delete ptr; ptr = 0
doDelete(m_modulesHandler);
doDelete(m_registerHandler);
doDelete(m_snapshotHandler);
#undef doDelete
}
////////////////////////////////////////////////////////////////////////
//
// DebuggerRunControl
//
////////////////////////////////////////////////////////////////////////
DebuggerRunControl::DebuggerRunControl(DebuggerManager *manager,
const DebuggerStartParameters &startParameters)
: RunControl(0, ProjectExplorer::Constants::DEBUGMODE),
d(new Private(this, manager, startParameters))
DebuggerRunControl::DebuggerRunControl(QObject *parent)
: RunControl(0, ProjectExplorer::Constants::DEBUGMODE)
{
connect(d->m_manager, SIGNAL(debuggingFinished()),
this, SLOT(debuggingFinished()),
Qt::QueuedConnection);
connect(d->m_manager, SIGNAL(messageAvailable(QString, bool)),
this, SLOT(slotMessageAvailable(QString, bool)));
connect(this, SIGNAL(stopRequested()),
d->m_manager, SLOT(exitDebugger()));
Q_UNUSED(parent);
m_running = false;
m_engine = 0;
m_enabledEngines = AllEngineTypes;
}
if (d->m_startParameters.environment.empty())
d->m_startParameters.environment = ProjectExplorer::Environment().toStringList();
d->m_startParameters.useTerminal = false;
static DebuggerEngineType engineForToolChain(int toolChainType)
{
switch (toolChainType) {
case ProjectExplorer::ToolChain::LINUX_ICC:
case ProjectExplorer::ToolChain::MinGW:
case ProjectExplorer::ToolChain::GCC:
case ProjectExplorer::ToolChain::WINSCW: // S60
case ProjectExplorer::ToolChain::GCCE:
case ProjectExplorer::ToolChain::RVCT_ARMV5:
case ProjectExplorer::ToolChain::RVCT_ARMV6:
case ProjectExplorer::ToolChain::RVCT_ARMV5_GNUPOC:
case ProjectExplorer::ToolChain::GCCE_GNUPOC:
return GdbEngineType;
case ProjectExplorer::ToolChain::MSVC:
case ProjectExplorer::ToolChain::WINCE:
return CdbEngineType;
case ProjectExplorer::ToolChain::OTHER:
case ProjectExplorer::ToolChain::UNKNOWN:
case ProjectExplorer::ToolChain::INVALID:
default:
break;
}
return NoEngineType;
}
// Figure out the debugger type of an executable. Analyze executable
// unless the toolchain provides a hint.
DebuggerEngineType DebuggerRunControl::engineForExecutable(const QString &executable)
{
if (executable.endsWith(_("qmlviewer"))) {
if (m_enabledEngines & QmlEngineType)
return QmlEngineType;
m_errorMessage = msgEngineNotAvailable("Qml Engine");
}
if (executable.endsWith(_(".js"))) {
if (m_enabledEngines & ScriptEngineType)
return ScriptEngineType;
m_errorMessage = msgEngineNotAvailable("Script Engine");
}
if (executable.endsWith(_(".py"))) {
if (m_enabledEngines & PdbEngineType)
return PdbEngineType;
m_errorMessage = msgEngineNotAvailable("Pdb Engine");
}
#ifdef Q_OS_WIN
// A remote executable?
if (!executable.endsWith(_(".exe")))
return GdbEngineType
// If a file has PDB files, it has been compiled by VS.
QStringList pdbFiles;
if (!getPDBFiles(executable, &pdbFiles, errorMessage)) {
qWarning("Cannot determine type of executable %s: %s",
qPrintable(executable), qPrintable(m_errorMessage));
return 0;
}
if (pdbFiles.empty())
return GdbEngineType;
// We need the CDB debugger in order to be able to debug VS
// executables
if (checkDebugConfiguration(ToolChain::MSVC, errorMessage, 0, &m_settingsIdHint))
return CdbEngineType;
#else
if (m_enabledEngines & GdbEngineType)
return GdbEngineType;
m_errorMessage = msgEngineNotAvailable("Gdb Engine");
#endif
return NoEngineType;
}
// Debugger type for mode.
DebuggerEngineType DebuggerRunControl::engineForMode(DebuggerStartMode startMode)
{
if (startMode == AttachTcf)
return TcfEngineType;
#ifdef Q_OS_WIN
// Preferably Windows debugger for attaching locally.
if (startMode != AttachToRemote && cdbEngine)
return CdbEngineType;
if (gdbEngine)
return GdbEngineType;
m_errorMessage = msgEngineNotAvailable("Gdb Engine");
return NoEngineType;
#else
Q_UNUSED(startMode)
// m_errorMessage = msgEngineNotAvailable("Gdb Engine");
return GdbEngineType;
#endif
}
void DebuggerRunControl::setEnabledEngines(DebuggerEngineType enabledEngines)
{
m_enabledEngines = enabledEngines;
}
void DebuggerRunControl::createEngine(const DebuggerStartParameters &sp)
{
// Figure out engine according to toolchain, executable, attach or default.
DebuggerEngineType engineType = NoEngineType;
QString errorMessage;
QString settingsIdHint;
if (sp.executable.endsWith(_("qmlviewer")))
engineType = QmlEngineType;
else if (sp.executable.endsWith(_(".js")))
engineType = ScriptEngineType;
else if (sp.executable.endsWith(_(".py")))
engineType = PdbEngineType;
else
engineType = engineForToolChain(sp.toolChainType);
if (engineType == NoEngineType
&& sp.startMode != AttachToRemote
&& !sp.executable.isEmpty())
engineType = engineForExecutable(sp.executable);
if (!engineType)
engineType = engineForMode(sp.startMode);
//qDebug() << "USING ENGINE : " << engineType;
switch (engineType) {
case GdbEngineType:
m_engine = createGdbEngine(sp);
break;
case ScriptEngineType:
m_engine = createScriptEngine(sp);
break;
case CdbEngineType:
m_engine = createCdbEngine(sp);
break;
case PdbEngineType:
m_engine = createPdbEngine(sp);
break;
case TcfEngineType:
m_engine = createTcfEngine(sp);
break;
case QmlEngineType:
m_engine = createQmlEngine(sp);
break;
default: {
// Could not find anything suitable.
emit debuggingFinished();
// Create Message box with possibility to go to settings
const QString msg = tr("Cannot debug '%1' (tool chain: '%2'): %3")
.arg(sp.executable, toolChainName(sp.toolChainType), m_errorMessage);
Core::ICore::instance()->showWarningWithOptions(tr("Warning"),
msg, QString(), QLatin1String(Constants::DEBUGGER_SETTINGS_CATEGORY),
m_settingsIdHint);
break;
}
}
}
DebuggerRunControl::~DebuggerRunControl()
{
delete d;
delete m_engine;
}
QString DebuggerRunControl::displayName() const
{
return d->m_startParameters.displayName;
QTC_ASSERT(m_engine, return QString());
return m_engine->startParameters().displayName;
}
void DebuggerRunControl::setCustomEnvironment(ProjectExplorer::Environment env)
{
d->m_startParameters.environment = env.toStringList();
m_engine->startParameters().environment = env.toStringList();
}
void DebuggerRunControl::init()
{
}
bool DebuggerRunControl::checkDebugConfiguration(int toolChain,
QString *errorMessage,
QString *settingsCategory /* = 0 */,
QString *settingsPage /* = 0 */)
{
errorMessage->clear();
if (settingsCategory)
settingsCategory->clear();
if (settingsPage)
settingsPage->clear();
bool success = true;
switch(toolChain) {
case ProjectExplorer::ToolChain::GCC:
case ProjectExplorer::ToolChain::LINUX_ICC:
case ProjectExplorer::ToolChain::MinGW:
case ProjectExplorer::ToolChain::WINCE: // S60
case ProjectExplorer::ToolChain::WINSCW:
case ProjectExplorer::ToolChain::GCCE:
case ProjectExplorer::ToolChain::RVCT_ARMV5:
case ProjectExplorer::ToolChain::RVCT_ARMV6:
success = checkGdbConfiguration(toolChain, errorMessage, settingsPage);
if (!success)
*errorMessage = msgEngineNotAvailable("Gdb");
break;
case ProjectExplorer::ToolChain::MSVC:
success = checkCdbConfiguration(toolChain, errorMessage, settingsPage);
if (!success) {
*errorMessage = msgEngineNotAvailable("Cdb");
if (settingsPage)
*settingsPage = QLatin1String("Cdb");
}
break;
}
if (!success && settingsCategory && settingsPage && !settingsPage->isEmpty())
*settingsCategory = QLatin1String(Constants::DEBUGGER_SETTINGS_CATEGORY);
return success;
}
void DebuggerRunControl::start()
{
d->m_running = true;
QTC_ASSERT(m_engine, return);
const DebuggerStartParameters &sp = m_engine->startParameters();
QString errorMessage;
QString settingsCategory;
QString settingsPage;
if (d->m_manager->checkDebugConfiguration(d->m_startParameters.toolChainType,
QString settingsIdHint;
if (!checkDebugConfiguration(sp.toolChainType,
&errorMessage, &settingsCategory, &settingsPage)) {
d->m_manager->startNewDebugger(this);
emit started();
} else {
appendMessage(this, errorMessage, true);
emit appendMessage(this, errorMessage, true);
emit finished();
Core::ICore::instance()->showWarningWithOptions(tr("Debugger"),
errorMessage, QString(), settingsCategory, settingsPage);
return;
}
plugin()->activateDebugMode();
showMessage(tr("Starting debugger for tool chain '%1'...")
.arg(toolChainName(sp.toolChainType)), LogStatus);
showMessage(DebuggerSettings::instance()->dump(), LogDebug);
plugin()->setBusyCursor(false);
engine()->startDebugger(this);
}
void DebuggerRunControl::showMessage(const QString &msg, int channel,
int timeout)
void DebuggerRunControl::startSuccessful()
{
m_running = true;
emit started();
}
void DebuggerRunControl::startFailed()
{
m_running = false;
emit finished();
}
void DebuggerRunControl::handleStarted()
{
plugin()->runControlStarted(this);
}
void DebuggerRunControl::handleFinished()
{
plugin()->runControlFinished(this);
}
void DebuggerRunControl::showMessage(const QString &msg, int channel)
{
if (!d->m_manager)
return;
DebuggerOutputWindow *ow = d->m_manager->debuggerOutputWindow();
QTC_ASSERT(ow, return);
switch (channel) {
case StatusBar:
d->m_manager->showStatusMessage(msg, timeout);
ow->showOutput(LogStatus, msg);
break;
case AppOutput:
emit addToOutputWindowInline(this, msg, false);
break;
case AppError:
emit addToOutputWindowInline(this, msg, true);
break;
case LogMiscInput:
ow->showInput(LogMisc, msg);
ow->showOutput(LogMisc, msg);
break;
case LogInput:
ow->showInput(channel, msg);
ow->showOutput(channel, msg);
break;
default:
ow->showOutput(channel, msg);
case AppStuff:
emit appendMessage(this, msg, true);
break;
}
}
void DebuggerRunControl::slotMessageAvailable(const QString &data, bool isError)
{
emit appendMessage(this, data, isError);
}
void DebuggerRunControl::stop()
{
d->m_running = false;
emit stopRequested();
m_running = false;
QTC_ASSERT(m_engine, return);
m_engine->exitDebugger();
}
void DebuggerRunControl::debuggingFinished()
{
d->m_running = false;
m_running = false;
emit finished();
}
bool DebuggerRunControl::isRunning() const
{
return d->m_running;
return m_running;
}
const DebuggerStartParameters &DebuggerRunControl::sp() const
Internal::DebuggerEngine *DebuggerRunControl::engine()
{
return d->m_startParameters;
QTC_ASSERT(m_engine, /**/);
return m_engine;
}
ModulesHandler *DebuggerRunControl::modulesHandler() const
{
return d->m_modulesHandler;
}
BreakHandler *DebuggerRunControl::breakHandler() const
{
return d->m_manager->breakHandler();
}
RegisterHandler *DebuggerRunControl::registerHandler() const
{
return d->m_registerHandler;
}
StackHandler *DebuggerRunControl::stackHandler() const
{
return d->m_manager->stackHandler();
}
ThreadsHandler *DebuggerRunControl::threadsHandler() const
{
return d->m_manager->threadsHandler();
}
WatchHandler *DebuggerRunControl::watchHandler() const
{
return d->m_manager->watchHandler();
}
SnapshotHandler *DebuggerRunControl::snapshotHandler() const
{
return d->m_snapshotHandler;
}
void DebuggerRunControl::cleanup()
{
modulesHandler()->removeAll();
}
Internal::IDebuggerEngine *DebuggerRunControl::engine()
{
QTC_ASSERT(d->m_engine, /**/);
return d->m_engine;
}
void DebuggerRunControl::startDebugger(IDebuggerEngine *engine)
{
d->m_engine = engine;
d->m_engine->setRunControl(this);
d->m_manager->modulesWindow()->setModel(d->m_modulesHandler->model());
d->m_manager->registerWindow()->setModel(d->m_registerHandler->model());
d->m_manager->snapshotWindow()->setModel(d->m_snapshotHandler->model());
d->m_engine->startDebugger();
}
void DebuggerRunControl::notifyInferiorPid(qint64 pid)
{
//STATE_DEBUG(d->m_inferiorPid << pid);
if (d->m_inferiorPid == pid)
return;
d->m_inferiorPid = pid;
QTimer::singleShot(0, this, SLOT(raiseApplication()));
}
qint64 DebuggerRunControl::inferiorPid() const
{
return d->m_inferiorPid;
}
void DebuggerRunControl::raiseApplication()
{
bringApplicationToForeground(d->m_inferiorPid);
}
//////////////////////////////////////////////////////////////////////
//
// AbstractDebuggerEngine
//
//////////////////////////////////////////////////////////////////////
/*
void IDebuggerEngine::showStatusMessage(const QString &msg, int timeout)
{
m_manager->showStatusMessage(msg, timeout);
}
*/
DebuggerState IDebuggerEngine::state() const
{
return m_manager->state();
}
void IDebuggerEngine::setState(DebuggerState state, bool forced)
{
m_manager->setState(state, forced);
}
bool IDebuggerEngine::debuggerActionsEnabled() const
{
return m_manager->debuggerActionsEnabled();
}
void IDebuggerEngine::showModuleSymbols
(const QString &moduleName, const Symbols &symbols)
{
QTreeWidget *w = new QTreeWidget;
w->setColumnCount(3);
w->setRootIsDecorated(false);
w->setAlternatingRowColors(true);
w->setSortingEnabled(true);
w->setHeaderLabels(QStringList() << tr("Symbol") << tr("Address") << tr("Code"));
w->setWindowTitle(tr("Symbols in \"%1\"").arg(moduleName));
foreach (const Symbol &s, symbols) {
QTreeWidgetItem *it = new QTreeWidgetItem;
it->setData(0, Qt::DisplayRole, s.name);
it->setData(1, Qt::DisplayRole, s.address);
it->setData(2, Qt::DisplayRole, s.state);
w->addTopLevelItem(it);
}
manager()->createNewDock(w);
}
ModulesHandler *IDebuggerEngine::modulesHandler() const
{
return runControl()->modulesHandler();
}
BreakHandler *IDebuggerEngine::breakHandler() const
{
return runControl()->breakHandler();
}
RegisterHandler *IDebuggerEngine::registerHandler() const
{
return runControl()->registerHandler();
}
StackHandler *IDebuggerEngine::stackHandler() const
{
return runControl()->stackHandler();
}
ThreadsHandler *IDebuggerEngine::threadsHandler() const
{
return runControl()->threadsHandler();
}
WatchHandler *IDebuggerEngine::watchHandler() const
{
return runControl()->watchHandler();
}
SnapshotHandler *IDebuggerEngine::snapshotHandler() const
{
return runControl()->snapshotHandler();
}
} // namespace Debugger
+36 -80
View File
@@ -33,11 +33,8 @@
#include "debugger_global.h"
#include "debuggerconstants.h"
#include <coreplugin/ssh/sshconnection.h>
#include <projectexplorer/runconfiguration.h>
#include <QtCore/QStringList>
namespace ProjectExplorer {
class Environment;
}
@@ -45,51 +42,12 @@ class Environment;
namespace Debugger {
class DebuggerManager;
class DebuggerStartParameters;
namespace Internal {
class IDebuggerEngine;
class BreakHandler;
class ModulesHandler;
class RegisterHandler;
class StackHandler;
class SnapshotHandler;
class ThreadsHandler;
class WatchHandler;
class DebuggerEngine;
}
class DEBUGGER_EXPORT DebuggerStartParameters
{
public:
DebuggerStartParameters();
void clear();
QString executable;
QString displayName;
QString coreFile;
QStringList processArgs;
QStringList environment;
QString workingDirectory;
qint64 attachPID;
bool useTerminal;
QString crashParameter; // for AttachCrashedExternal
// for remote debugging
QString remoteChannel;
QString remoteArchitecture;
QString symbolFileName;
QString serverStartScript;
QString sysRoot;
QString debuggerCommand;
int toolChainType;
QByteArray remoteDumperLib;
QString qtInstallPath;
QString dumperLibrary;
QStringList dumperLibraryLocations;
Core::SshServerInfo sshserver;
DebuggerStartMode startMode;
};
//DEBUGGER_EXPORT QDebug operator<<(QDebug str, const DebuggerStartParameters &);
class DEBUGGER_EXPORT DebuggerRunControlFactory
@@ -98,24 +56,25 @@ class DEBUGGER_EXPORT DebuggerRunControlFactory
Q_OBJECT
public:
explicit DebuggerRunControlFactory(DebuggerManager *manager);
DebuggerRunControlFactory(QObject *parent, DebuggerEngineType enabledEngines);
// ProjectExplorer::IRunControlFactory
bool canRun(ProjectExplorer::RunConfiguration *runConfiguration, const QString &mode) const;
virtual ProjectExplorer::RunControl *create(ProjectExplorer::RunConfiguration *runConfiguration,
const QString &mode);
virtual QString displayName() const;
virtual QWidget *createConfigurationWidget(ProjectExplorer::RunConfiguration *runConfiguration);
bool canRun(ProjectExplorer::RunConfiguration *runConfiguration,
const QString &mode) const;
ProjectExplorer::RunControl *create(ProjectExplorer::RunConfiguration
*runConfiguration, const QString &mode);
QString displayName() const;
QWidget *createConfigurationWidget(ProjectExplorer::RunConfiguration
*runConfiguration);
// This is used by the "Non-Standard" scenarios, e.g. Attach to Core.
ProjectExplorer::RunControl *create(const DebuggerStartParameters &sp);
private:
DebuggerManager *m_manager;
DebuggerEngineType m_enabledEngines;
};
// This is a job description containing all data "local" to the jobs, including
// the models of the individual debugger views.
class DEBUGGER_EXPORT DebuggerRunControl
@@ -124,51 +83,48 @@ class DEBUGGER_EXPORT DebuggerRunControl
Q_OBJECT
public:
DebuggerRunControl(DebuggerManager *manager,
const DebuggerStartParameters &startParameters);
DebuggerRunControl(QObject *parent = 0);
~DebuggerRunControl();
void setCustomEnvironment(ProjectExplorer::Environment env);
// ProjectExplorer::RunControl
virtual void start();
virtual void stop();
virtual bool isRunning() const;
QString displayName() const;
Q_SLOT void debuggingFinished();
void createEngine(const DebuggerStartParameters &startParameters);
const DebuggerStartParameters &sp() const;
void setCustomEnvironment(ProjectExplorer::Environment env);
void setEnabledEngines(DebuggerEngineType enabledEngines);
Internal::ModulesHandler *modulesHandler() const;
Internal::BreakHandler *breakHandler() const;
Internal::RegisterHandler *registerHandler() const;
Internal::StackHandler *stackHandler() const;
Internal::ThreadsHandler *threadsHandler() const;
Internal::WatchHandler *watchHandler() const;
Internal::SnapshotHandler *snapshotHandler() const;
void startFailed();
void startSuccessful();
void debuggingFinished();
void cleanup();
void startDebugger(Internal::IDebuggerEngine *engine);
void notifyInferiorPid(qint64 pid);
qint64 inferiorPid() const;
Internal::DebuggerEngine *engine();
Internal::IDebuggerEngine *engine();
void showMessage(const QString &msg, int channel);
signals:
void stopRequested();
public slots:
void showMessage(const QString &output, int channel = LogDebug, int timeout = -1);
static bool checkDebugConfiguration(int toolChain,
QString *errorMessage,
QString *settingsCategory = 0,
QString *settingsPage = 0);
private slots:
void slotMessageAvailable(const QString &data, bool isError);
void raiseApplication();
void handleStarted();
void handleFinished();
private:
void init();
class Private;
Private *d;
DebuggerEngineType engineForExecutable(const QString &executable);
DebuggerEngineType engineForMode(DebuggerStartMode mode);
Internal::DebuggerEngine *m_engine;
bool m_running;
DebuggerEngineType m_enabledEngines;
QString m_errorMessage;
QString m_settingsIdHint;
};
} // namespace Debugger
+24 -7
View File
@@ -153,8 +153,8 @@ DebuggerUISwitcher::~DebuggerUISwitcher()
delete d;
}
void DebuggerUISwitcher::addMenuAction(Core::Command *command, const QString &langName,
const QString &group)
void DebuggerUISwitcher::addMenuAction(Core::Command *command,
const QString &langName, const QString &group)
{
d->m_debugMenu->addAction(command, group);
d->m_menuCommands.insert(d->m_languages.indexOf(langName), command);
@@ -162,6 +162,9 @@ void DebuggerUISwitcher::addMenuAction(Core::Command *command, const QString &la
void DebuggerUISwitcher::setActiveLanguage(const QString &langName)
{
//qDebug() << "SET ACTIVE LANGUAGE: " << langName
// << theDebuggerAction(SwitchLanguageAutomatically)->isChecked()
// << d->m_languages;
if (theDebuggerAction(SwitchLanguageAutomatically)->isChecked()
&& d->m_languages.contains(langName))
{
@@ -173,6 +176,7 @@ int DebuggerUISwitcher::activeLanguageId() const
{
return d->m_activeLanguage;
}
void DebuggerUISwitcher::modeChanged(Core::IMode *mode)
{
d->m_isActiveMode = (mode->id() == Debugger::Constants::MODE_DEBUG);
@@ -235,6 +239,7 @@ DebuggerUISwitcher *DebuggerUISwitcher::instance()
void DebuggerUISwitcher::addLanguage(const QString &langName, const QList<int> &context)
{
//qDebug() << "ADD UI LANGUAGE: " << langName;
d->m_toolBars.insert(langName, 0);
d->m_contextsForLanguage.insert(d->m_languages.count(), context);
d->m_languages.append(langName);
@@ -250,7 +255,8 @@ void DebuggerUISwitcher::addLanguage(const QString &langName, const QList<int> &
connect(langChange, SIGNAL(triggered()), SLOT(langChangeTriggered()));
Core::Command *cmd = am->registerAction(langChange,
"Debugger.Language." + langName, d->m_globalContext);
cmd->setDefaultKeySequence(QKeySequence(QString("%1,%2").arg(prefix, QString::number(d->m_languages.count()))));
cmd->setDefaultKeySequence(QKeySequence(
QString("%1,%2").arg(prefix).arg(d->m_languages.count())));
d->m_languageMenu->addAction(cmd);
}
@@ -264,6 +270,7 @@ void DebuggerUISwitcher::langChangeTriggered()
void DebuggerUISwitcher::changeDebuggerUI(const QString &langName)
{
//qDebug() << "CHANGE DEBUGGER UI: " << langName << d->m_changingUI;
if (d->m_changingUI)
return;
d->m_changingUI = true;
@@ -271,9 +278,13 @@ void DebuggerUISwitcher::changeDebuggerUI(const QString &langName)
int langId = d->m_languages.indexOf(langName);
if (langId != d->m_activeLanguage) {
d->m_languageActionGroup->actions()[langId]->setChecked(true);
d->m_toolbarStack->setCurrentWidget(d->m_toolBars.value(langName));
if ((d->m_toolBars.value(langName)))
d->m_toolbarStack->setCurrentWidget(d->m_toolBars.value(langName));
foreach (DebugToolWindow *window, d->m_dockWidgets) {
//qDebug() << " WINDOW " << window->m_dockWidget->objectName()
// << window->m_visible;
if (window->m_languageId != langId) {
// visibleTo must be used because during init, debugger is not visible,
// although visibility is explicitly set through both default layout and
@@ -373,9 +384,11 @@ QWidget *DebuggerUISwitcher::createMainWindow(Core::BaseMode *mode)
/*!
Keep track of dock widgets so they can be shown/hidden for different languages
*/
QDockWidget *DebuggerUISwitcher::createDockWidget(const QString &langName, QWidget *widget,
Qt::DockWidgetArea area, bool visibleByDefault)
QDockWidget *DebuggerUISwitcher::createDockWidget(const QString &langName,
QWidget *widget, Qt::DockWidgetArea area, bool visibleByDefault)
{
//qDebug() << "CREATE DOCK" << widget->objectName() << langName
// << d->m_activeLanguage << "VISIBLE BY DEFAULT: " << visibleByDefault;
QDockWidget *dockWidget = d->m_mainWindow->addDockForWidget(widget);
d->m_mainWindow->addDockWidget(area, dockWidget);
DebugToolWindow *window = new DebugToolWindow;
@@ -446,20 +459,23 @@ void DebuggerUISwitcher::writeSettings() const
void DebuggerUISwitcher::readSettings()
{
//qDebug() << "\n SWITCHER READ SETTINGS \n";
QSettings *s = Core::ICore::instance()->settings();
s->beginGroup(QLatin1String("DebugMode"));
d->m_mainWindow->restoreSettings(s);
s->endGroup();
/*
foreach(Internal::DebugToolWindow *toolWindow, d->m_dockWidgets) {
toolWindow->m_visible = toolWindow->m_dockWidget->isVisibleTo(d->m_mainWindow);
}
*/
}
void DebuggerUISwitcher::initialize()
{
createViewsMenuItems();
//qDebug() << "UI SWITCHER INITIALIZE";
emit dockArranged(QString());
readSettings();
@@ -472,6 +488,7 @@ void DebuggerUISwitcher::initialize()
void DebuggerUISwitcher::resetDebuggerLayout()
{
//qDebug() << "RESET DEBUGGER LAYOUT" << d->m_languages.at(d->m_activeLanguage);
emit dockArranged(d->m_languages.at(d->m_activeLanguage));
}
@@ -54,6 +54,7 @@ void AbstractGdbAdapter::shutdown()
void AbstractGdbAdapter::startInferiorPhase2()
{
qDebug() << "START INFERIOR PHASE 2";
}
const char *AbstractGdbAdapter::inferiorShutdownCommand() const
@@ -50,10 +50,13 @@ class AbstractGdbAdapter : public QObject
Q_OBJECT
public:
enum DumperHandling { DumperNotAvailable,
DumperLoadedByAdapter,
DumperLoadedByGdbPreload,
DumperLoadedByGdb };
enum DumperHandling
{
DumperNotAvailable,
DumperLoadedByAdapter,
DumperLoadedByGdbPreload,
DumperLoadedByGdb
};
AbstractGdbAdapter(GdbEngine *engine, QObject *parent = 0);
virtual ~AbstractGdbAdapter();
@@ -107,10 +110,8 @@ protected:
{ m_engine->setState(state); }
const DebuggerStartParameters &startParameters() const
{ return m_engine->startParameters(); }
DebuggerRunControl *runControl() const
{ return m_engine->runControl(); }
void showMessage(const QString &msg, int channel = LogDebug, int timeout = 1)
{ runControl()->showMessage(msg, channel, timeout); }
{ m_engine->showMessage(msg, channel, timeout); }
void showMessageBox(int icon, const QString &title, const QString &text) const
{ m_engine->showMessageBox(icon, title, text); }
@@ -47,7 +47,6 @@ AbstractPlainGdbAdapter::AbstractPlainGdbAdapter(GdbEngine *engine,
{
}
void AbstractPlainGdbAdapter::startInferior()
{
QTC_ASSERT(state() == InferiorStarting, qDebug() << state());
+26 -25
View File
@@ -32,6 +32,7 @@
#include "abstractgdbadapter.h"
#include "debuggeractions.h"
#include "debuggerstringutils.h"
#include "debuggerplugin.h"
#include "stackhandler.h"
#include "watchhandler.h"
@@ -113,7 +114,7 @@ void GdbEngine::updateLocalsClassic(const QVariant &cookie)
//PENDING_DEBUG("\nRESET PENDING");
//m_toolTipCache.clear();
m_toolTipExpression.clear();
manager()->watchHandler()->beginCycle();
watchHandler()->beginCycle();
QByteArray level = QByteArray::number(currentFrame());
// '2' is 'list with type and value'
@@ -290,7 +291,7 @@ void GdbEngine::updateSubItemClassic(const WatchData &data0)
qDebug() << "UPDATE SUBITEM: CUSTOMVALUE";
# endif
runDebuggingHelperClassic(data,
manager()->watchHandler()->isExpandedIName(data.iname));
watchHandler()->isExpandedIName(data.iname));
return;
}
@@ -356,8 +357,7 @@ void GdbEngine::updateSubItemClassic(const WatchData &data0)
# if DEBUG_SUBITEM
qDebug() << "UPDATE SUBITEM: CUSTOMVALUE WITH CHILDREN";
# endif
runDebuggingHelperClassic(data,
manager()->watchHandler()->isExpandedIName(data.iname));
runDebuggingHelperClassic(data, watchHandler()->isExpandedIName(data.iname));
return;
}
@@ -419,11 +419,11 @@ void GdbEngine::handleDebuggingHelperValue2Classic(const GdbResponse &response)
setWatchDataType(data, response.data.findChild("type"));
setWatchDataDisplayedType(data, response.data.findChild("displaytype"));
QList<WatchData> list;
parseWatchData(manager()->watchHandler()->expandedINames(),
parseWatchData(watchHandler()->expandedINames(),
data, contents, &list);
//for (int i = 0; i != list.size(); ++i)
// qDebug() << "READ: " << list.at(i).toString();
manager()->watchHandler()->insertBulkData(list);
watchHandler()->insertBulkData(list);
}
void GdbEngine::handleDebuggingHelperValue3Classic(const GdbResponse &response)
@@ -514,11 +514,11 @@ void GdbEngine::tryLoadDebuggingHelpersClassic()
m_debuggingHelperState = DebuggingHelperLoadTried;
QByteArray dlopenLib;
if (runControl()->sp().startMode == AttachToRemote
|| runControl()->sp().startMode == StartRemoteGdb)
dlopenLib = runControl()->sp().remoteDumperLib;
const DebuggerStartMode startMode = startParameters().startMode;
if (startMode == AttachToRemote || startMode == StartRemoteGdb)
dlopenLib = startParameters().remoteDumperLib;
else
dlopenLib = manager()->qtDumperLibraryName().toLocal8Bit();
dlopenLib = qtDumperLibraryName().toLocal8Bit();
// Do not use STRINGIFY for RTLD_NOW as we really want to expand that to a number.
#if defined(Q_OS_WIN) || defined(Q_OS_SYMBIAN)
@@ -580,10 +580,10 @@ void GdbEngine::updateAllClassic()
postCommand("-stack-list-frames", WatchUpdate,
CB(handleStackListFrames),
QVariant::fromValue<StackCookie>(StackCookie(false, true)));
manager()->stackHandler()->setCurrentIndex(0);
stackHandler()->setCurrentIndex(0);
if (supportsThreads())
postCommand("-thread-list-ids", WatchUpdate, CB(handleThreadListIds), 0);
manager()->reloadRegisters();
reloadRegisters();
updateLocals();
}
@@ -593,7 +593,7 @@ void GdbEngine::setDebugDebuggingHelpersClassic(const QVariant &on)
if (on.toBool()) {
showMessage(_("SWITCHING ON DUMPER DEBUGGING"));
postCommand("set unwindonsignal off");
m_manager->breakByFunction(_("qDumpObjectData440"));
breakByFunction(_("qDumpObjectData440"));
//updateLocals();
} else {
showMessage(_("SWITCHING OFF DUMPER DEBUGGING"));
@@ -660,11 +660,12 @@ void GdbEngine::handleStackListLocalsClassic(const GdbResponse &response)
// is not known at this point.
QStringList uninitializedVariables;
if (theDebuggerAction(UseCodeModel)->isChecked()) {
const StackFrame frame = qVariantCanConvert<Debugger::Internal::StackFrame>(response.cookie) ?
qVariantValue<Debugger::Internal::StackFrame>(response.cookie) :
m_manager->stackHandler()->currentFrame();
const StackFrame frame =
qVariantCanConvert<Debugger::Internal::StackFrame>(response.cookie)
? qVariantValue<Debugger::Internal::StackFrame>(response.cookie)
: stackHandler()->currentFrame();
if (frame.isUsable())
getUninitializedVariables(m_manager->cppCodeModelSnapshot(),
getUninitializedVariables(plugin()->cppCodeModelSnapshot(),
frame.function, frame.file, frame.line,
&uninitializedVariables);
}
@@ -683,23 +684,23 @@ void GdbEngine::handleStackListLocalsClassic(const GdbResponse &response)
list.append(rd);
}
manager()->watchHandler()->insertBulkData(list);
manager()->watchHandler()->updateWatchers();
watchHandler()->insertBulkData(list);
watchHandler()->updateWatchers();
}
bool GdbEngine::checkDebuggingHelpersClassic()
{
PRECONDITION;
if (!manager()->qtDumperLibraryEnabled())
if (!qtDumperLibraryEnabled())
return false;
const QString lib = qtDumperLibraryName();
const QFileInfo fi(lib);
if (!fi.exists()) {
const QStringList &locations = manager()->qtDumperLibraryLocations();
const QStringList &locations = qtDumperLibraryLocations();
const QString loc = locations.join(QLatin1String(", "));
const QString msg = tr("The debugging helper library was not found at %1.").arg(loc);
showMessage(msg);
manager()->showQtDumperLibraryWarning(msg);
showQtDumperLibraryWarning(msg);
return false;
}
return true;
@@ -719,7 +720,7 @@ void GdbEngine::handleQueryDebuggingHelperClassic(const GdbResponse &response)
// currently causes errors.
const double dumperVersion = getDumperVersion(contents);
if (dumperVersion < dumperVersionRequired) {
manager()->showQtDumperLibraryWarning(
showQtDumperLibraryWarning(
QtDumperHelper::msgDumperOutdated(dumperVersionRequired, dumperVersion));
m_debuggingHelperState = DebuggingHelperUnavailable;
return;
@@ -750,7 +751,7 @@ void GdbEngine::handleDebuggingHelperVersionCheckClassic(const GdbResponse &resp
QString debuggeeQtVersion = value.section(QLatin1Char('"'), 1, 1);
QString dumperQtVersion = m_dumperHelper.qtVersionString();
if (dumperQtVersion != debuggeeQtVersion) {
manager()->showMessageBox(QMessageBox::Warning,
showMessageBox(QMessageBox::Warning,
tr("Debugging helpers: Qt version mismatch"),
tr("The Qt version used to build the debugging helpers (%1) "
"does not match the Qt version used to build the debugged "
@@ -821,7 +822,7 @@ void GdbEngine::handleVarListChildrenHelperClassic(const GdbMi &item,
setWatchDataValue(data, item);
setWatchDataAddress(data, item.findChild("addr"));
setWatchDataChildCount(data, item.findChild("numchild"));
if (!manager()->watchHandler()->isExpandedIName(data.iname))
if (!watchHandler()->isExpandedIName(data.iname))
data.setChildrenUnneeded();
data.name = _(exp);
+111 -113
View File
@@ -30,9 +30,11 @@
#define QT_NO_CAST_FROM_ASCII
#include "gdbengine.h"
#include "gdboptionspage.h"
#include "debuggeruiswitcher.h"
#include "debuggermainwindow.h"
#include "debuggerplugin.h"
#include "attachgdbadapter.h"
#include "coregdbadapter.h"
@@ -46,7 +48,6 @@
#include "debuggeractions.h"
#include "debuggeragents.h"
#include "debuggerconstants.h"
#include "debuggermanager.h"
#include "debuggertooltip.h"
#include "debuggerstringutils.h"
#include "gdbmi.h"
@@ -55,6 +56,7 @@
#include "moduleshandler.h"
#include "registerhandler.h"
#include "snapshothandler.h"
#include "sourcefileshandler.h"
#include "stackhandler.h"
#include "threadshandler.h"
#include "watchhandler.h"
@@ -172,9 +174,8 @@ static QByteArray parsePlainConsoleStream(const GdbResponse &response)
//
///////////////////////////////////////////////////////////////////////
GdbEngine::GdbEngine(DebuggerManager *manager) :
IDebuggerEngine(manager),
m_gdbBinaryToolChainMap(DebuggerSettings::instance()->gdbBinaryToolChainMap())
GdbEngine::GdbEngine(const DebuggerStartParameters &startParameters)
: DebuggerEngine(startParameters)
{
m_gdbAdapter = 0;
m_progress = 0;
@@ -185,6 +186,7 @@ GdbEngine::GdbEngine(DebuggerManager *manager) :
// Needs no resetting in initializeVariables()
m_busy = false;
initializeVariables();
connect(theDebuggerAction(AutoDerefPointers), SIGNAL(valueChanged(QVariant)),
this, SLOT(setAutoDerefPointers(QVariant)));
@@ -211,7 +213,6 @@ void GdbEngine::disconnectDebuggingHelperActions()
DebuggerStartMode GdbEngine::startMode() const
{
QTC_ASSERT(m_runControl, return NoStartMode);
return startParameters().startMode;
}
@@ -337,8 +338,9 @@ static void dump(const char *first, const char *middle, const QString & to)
void GdbEngine::readDebugeeOutput(const QByteArray &data)
{
m_manager->messageAvailable(m_outputCodec->toUnicode(
data.constData(), data.length(), &m_outputCodecState), true);
QString msg = m_outputCodec->toUnicode(data.constData(), data.length(),
&m_outputCodecState);
showMessage(msg, AppStuff);
}
void GdbEngine::handleResponse(const QByteArray &buff)
@@ -449,7 +451,7 @@ void GdbEngine::handleResponse(const QByteArray &buff)
QByteArray id = result.findChild("id").data();
showStatusMessage(tr("Thread group %1 created").arg(_(id)), 1000);
const int pid = id.toInt();
runControl()->notifyInferiorPid(pid);
notifyInferiorPid(pid);
} else if (asyncClass == "thread-created") {
//"{id="1",group-id="28902"}"
QByteArray id = result.findChild("id").data();
@@ -502,7 +504,7 @@ void GdbEngine::handleResponse(const QByteArray &buff)
m_pendingConsoleStreamOutput += data;
// Parse pid from noise.
if (!runControl()->inferiorPid()) {
if (!inferiorPid()) {
// Linux/Mac gdb: [New [Tt]hread 0x545 (LWP 4554)]
static QRegExp re1(_("New .hread 0x[0-9a-f]+ \\(LWP ([0-9]*)\\)"));
// MinGW 6.8: [New thread 2437.0x435345]
@@ -542,7 +544,7 @@ void GdbEngine::handleResponse(const QByteArray &buff)
// On Windows, the contents seem to depend on the debugger
// version and/or OS version used.
if (data.startsWith("warning:"))
manager()->messageAvailable(_(data.mid(9)), true); // cut "warning: "
showMessage(_(data.mid(9)), AppStuff); // cut "warning: "
break;
}
@@ -564,7 +566,7 @@ void GdbEngine::handleResponse(const QByteArray &buff)
m_progress->reportFinished();
}
if (state() == InferiorStopped) { // Result of manual command.
m_manager->resetLocation();
resetLocation();
setTokenBarrier();
setState(InferiorRunningRequested);
}
@@ -678,11 +680,12 @@ void GdbEngine::interruptInferior()
void GdbEngine::interruptInferiorTemporarily()
{
interruptInferior();
foreach (const GdbCommand &cmd, m_commandsToRunOnTemporaryBreak)
foreach (const GdbCommand &cmd, m_commandsToRunOnTemporaryBreak) {
if (cmd.flags & LosesChild) {
setState(InferiorStopping_Kill);
break;
}
}
}
void GdbEngine::maybeHandleInferiorPidChanged(const QString &pid0)
@@ -692,11 +695,11 @@ void GdbEngine::maybeHandleInferiorPidChanged(const QString &pid0)
showMessage(_("Cannot parse PID from %1").arg(pid0));
return;
}
if (pid == runControl()->inferiorPid())
if (pid == inferiorPid())
return;
showMessage(_("FOUND PID %1").arg(pid));
runControl()->notifyInferiorPid(pid);
showMessage(_("FOUND PID %1").arg(pid));
notifyInferiorPid(pid);
}
void GdbEngine::postCommand(const QByteArray &command, AdapterCallback callback,
@@ -970,7 +973,7 @@ void GdbEngine::handleResultRecord(GdbResponse *response)
GdbResultDone)) {
#ifdef Q_OS_WIN
// Ignore spurious 'running' responses to 'attach'
const bool warning = !(runControl()->sp().startMode == AttachExternal
const bool warning = !(startParameters().startMode == AttachExternal
&& cmd.command.startsWith("attach"));
#else
const bool warning = true;
@@ -1079,7 +1082,7 @@ void GdbEngine::handleQuerySources(const GdbResponse &response)
}
}
if (m_shortToFullName != oldShortToFull)
manager()->sourceFileWindow()->setSourceFiles(m_shortToFullName);
sourceFilesHandler()->setSourceFiles(m_shortToFullName);
}
}
@@ -1275,7 +1278,7 @@ void GdbEngine::handleStopResponse(const GdbMi &data)
// Gdb <= 6.8 reports a frame but no reason, 6.8.50+ reports everything.
// The case of the user really setting a breakpoint at _start is simply
// unsupported.
if (!runControl()->inferiorPid()) // For programs without -pthread under gdb <= 6.8.
if (!inferiorPid()) // For programs without -pthread under gdb <= 6.8.
postCommand("info proc", CB(handleInfoProc));
continueInferiorInternal();
return;
@@ -1313,13 +1316,13 @@ void GdbEngine::handleStopResponse(const GdbMi &data)
if (isLeavableFunction(funcName, fileName)) {
//showMessage(_("LEAVING ") + funcName);
++stepCounter;
m_manager->executeStepOut();
executeStepOutX();
return;
}
if (isSkippableFunction(funcName, fileName)) {
//showMessage(_("SKIPPING ") + funcName);
++stepCounter;
m_manager->executeStep();
executeStepX();
return;
}
//if (stepCounter)
@@ -1349,7 +1352,7 @@ void GdbEngine::handleStopResponse(const GdbMi &data)
&& reason == "signal-received") {
QByteArray name = data.findChild("signal-name").data();
if (name != STOP_SIGNAL
&& (runControl()->sp().startMode != AttachToRemote
&& (startParameters().startMode != AttachToRemote
|| name != CROSS_STOP_SIGNAL))
initHelpers = false;
}
@@ -1427,7 +1430,7 @@ void GdbEngine::handleStop1(const GdbMi &data)
// Ignore these as they are showing up regularly when
// stopping debugging.
if (name != STOP_SIGNAL
&& (runControl()->sp().startMode != AttachToRemote
&& (startParameters().startMode != AttachToRemote
|| name != CROSS_STOP_SIGNAL)) {
QString msg = tr("<p>The inferior stopped because it received a "
"signal from the Operating System.<p>"
@@ -1484,7 +1487,7 @@ void GdbEngine::handleStop1(const GdbMi &data)
//
// Registers
//
manager()->reloadRegisters();
reloadRegisters();
}
void GdbEngine::handleInfoProc(const GdbResponse &response)
@@ -1529,9 +1532,9 @@ void GdbEngine::handleHasPython(const GdbResponse &response)
QByteArray cmd = "set environment ";
cmd += Debugger::Constants::Internal::LD_PRELOAD_ENV_VAR;
cmd += ' ';
cmd += runControl()->sp().startMode == StartRemoteGdb
? runControl()->sp().remoteDumperLib
: cmd += manager()->qtDumperLibraryName().toLocal8Bit();
cmd += startParameters().startMode == StartRemoteGdb
? startParameters().remoteDumperLib
: cmd += qtDumperLibraryName().toLocal8Bit();
postCommand(cmd);
m_debuggingHelperState = DebuggingHelperLoadTried;
}
@@ -1695,13 +1698,13 @@ void GdbEngine::detachDebugger()
shutdown();
}
void GdbEngine::exitDebugger() // called from the manager
void GdbEngine::exitDebugger()
{
disconnectDebuggingHelperActions();
shutdown();
}
void GdbEngine::abortDebugger() // called from the manager
void GdbEngine::abortDebugger()
{
disconnectDebuggingHelperActions();
shutdown();
@@ -1720,61 +1723,54 @@ static inline QString msgNoBinaryForToolChain(int tc)
return GdbEngine::tr("There is no gdb binary available for '%1'").arg(toolChainName);
}
bool GdbEngine::checkConfiguration(int toolChain, QString *errorMessage, QString *settingsPage) const
static QString gdbBinaryForToolChain(int toolChain)
{
if (m_gdbBinaryToolChainMap->key(toolChain).isEmpty()) {
*errorMessage = msgNoBinaryForToolChain(toolChain);
*settingsPage = GdbOptionsPage::settingsId();
return false;
}
return true;
return DebuggerSettings::instance()->gdbBinaryToolChainMap().key(toolChain);
}
AbstractGdbAdapter *GdbEngine::createAdapter()
{
QTC_ASSERT(runControl(), return 0);
const DebuggerStartParameters &sp = runControl()->sp();
const DebuggerStartParameters &sp = startParameters();
//qDebug() << "CREATE ADAPTER: " << sp.toolChainType;
switch (sp.toolChainType) {
case ProjectExplorer::ToolChain::WINSCW: // S60
case ProjectExplorer::ToolChain::GCCE:
case ProjectExplorer::ToolChain::RVCT_ARMV5:
case ProjectExplorer::ToolChain::RVCT_ARMV6:
case ProjectExplorer::ToolChain::RVCT_ARMV5_GNUPOC:
case ProjectExplorer::ToolChain::GCCE_GNUPOC:
return new TrkGdbAdapter(this);
default:
break;
case ProjectExplorer::ToolChain::WINSCW: // S60
case ProjectExplorer::ToolChain::GCCE:
case ProjectExplorer::ToolChain::RVCT_ARMV5:
case ProjectExplorer::ToolChain::RVCT_ARMV6:
case ProjectExplorer::ToolChain::RVCT_ARMV5_GNUPOC:
case ProjectExplorer::ToolChain::GCCE_GNUPOC:
return new TrkGdbAdapter(this);
default:
break;
}
// @todo: remove testing hack
if (sp.processArgs.size() == 3 && sp.processArgs.at(0) == _("@sym@"))
return new TrkGdbAdapter(this);
switch (sp.startMode) {
case AttachCore:
return new CoreGdbAdapter(this);
case AttachToRemote:
return new RemoteGdbServerAdapter(this, sp.toolChainType);
case StartRemoteGdb:
return new RemotePlainGdbAdapter(this);
case AttachExternal:
return new AttachGdbAdapter(this);
default:
if (sp.useTerminal)
return new TermGdbAdapter(this);
return new LocalPlainGdbAdapter(this);
case AttachCore:
return new CoreGdbAdapter(this);
case AttachToRemote:
return new RemoteGdbServerAdapter(this, sp.toolChainType);
case StartRemoteGdb:
return new RemotePlainGdbAdapter(this);
case AttachExternal:
return new AttachGdbAdapter(this);
default:
if (sp.useTerminal)
return new TermGdbAdapter(this);
return new LocalPlainGdbAdapter(this);
}
}
void GdbEngine::startDebugger()
{
QTC_ASSERT(runControl(), return);
QTC_ASSERT(state() == EngineStarting, qDebug() << state());
// This should be set by the constructor or in exitDebugger()
// via initializeVariables()
//QTC_ASSERT(m_debuggingHelperState == DebuggingHelperUninitialized,
// initializeVariables());
//QTC_ASSERT(m_gdbAdapter == 0, delete m_gdbAdapter; m_gdbAdapter = 0);
initializeVariables();
//qDebug() << "GDB START DEBUGGER";
QTC_ASSERT(state() == DebuggerNotReady, setState(DebuggerNotReady));
setState(EngineStarting);
QTC_ASSERT(m_debuggingHelperState == DebuggingHelperUninitialized, /**/);
QTC_ASSERT(m_gdbAdapter == 0, /**/);
m_progress = new QFutureInterface<void>();
m_progress->setProgressRange(0, 100);
@@ -1783,14 +1779,15 @@ void GdbEngine::startDebugger()
fp->setKeepOnFinish(false);
m_progress->reportStarted();
delete m_gdbAdapter;
m_gdbAdapter = createAdapter();
//qDebug() << "CREATED ADAPTER: " << m_gdbAdapter;
connectAdapter();
if (m_gdbAdapter->dumperHandling() != AbstractGdbAdapter::DumperNotAvailable)
connectDebuggingHelperActions();
m_progress->setProgressValue(20);
QTC_ASSERT(state() == EngineStarting, /**/);
m_gdbAdapter->startAdapter();
}
@@ -1823,7 +1820,7 @@ void GdbEngine::autoContinueInferior()
void GdbEngine::continueInferior()
{
m_manager->resetLocation();
resetLocation();
setTokenBarrier();
continueInferiorInternal();
showStatusMessage(tr("Running requested..."), 5000);
@@ -1837,7 +1834,7 @@ void GdbEngine::executeStep()
showStatusMessage(tr("Step requested..."), 5000);
if (m_gdbAdapter->isTrkAdapter() && stackHandler()->stackSize() > 0)
postCommand("sal step," + stackHandler()->topAddress().toLatin1());
if (manager()->isReverseDebugging())
if (isReverseDebugging())
postCommand("reverse-step", RunRequest, CB(handleExecuteStep));
else
postCommand("-exec-step", RunRequest, CB(handleExecuteStep));
@@ -1876,7 +1873,7 @@ void GdbEngine::executeStepI()
setTokenBarrier();
setState(InferiorRunningRequested);
showStatusMessage(tr("Step by instruction requested..."), 5000);
if (manager()->isReverseDebugging())
if (isReverseDebugging())
postCommand("reverse-stepi", RunRequest, CB(handleExecuteContinue));
else
postCommand("-exec-step-instruction", RunRequest, CB(handleExecuteContinue));
@@ -1900,7 +1897,7 @@ void GdbEngine::executeNext()
showStatusMessage(tr("Step next requested..."), 5000);
if (m_gdbAdapter->isTrkAdapter() && stackHandler()->stackSize() > 0)
postCommand("sal next," + stackHandler()->topAddress().toLatin1());
if (manager()->isReverseDebugging())
if (isReverseDebugging())
postCommand("reverse-next", RunRequest, CB(handleExecuteNext));
else
postCommand("-exec-next", RunRequest, CB(handleExecuteNext));
@@ -1938,7 +1935,7 @@ void GdbEngine::executeNextI()
setTokenBarrier();
setState(InferiorRunningRequested);
showStatusMessage(tr("Step next instruction requested..."), 5000);
if (manager()->isReverseDebugging())
if (isReverseDebugging())
postCommand("reverse-nexti", RunRequest, CB(handleExecuteContinue));
else
postCommand("-exec-next-instruction", RunRequest, CB(handleExecuteContinue));
@@ -2283,7 +2280,7 @@ void GdbEngine::handleBreakList(const GdbMi &table)
foreach (const GdbMi &bkpt, bkpts) {
BreakpointData temp;
setBreakpointDataFromOutput(&temp, bkpt);
BreakpointData *data = breakHandler()->findSimilarBreakpoint(temp);
BreakpointData *data = breakHandler()->findSimilarBreakpoint(&temp);
//qDebug() << "\n\nGOT: " << bkpt.toString() << '\n' << temp.toString();
if (data) {
//qDebug() << " FROM: " << data->toString();
@@ -2698,7 +2695,7 @@ void GdbEngine::handleModulesList(const GdbResponse &response)
}
}
}
runControl()->modulesHandler()->setModules(modules);
modulesHandler()->setModules(modules);
}
@@ -2743,7 +2740,7 @@ void GdbEngine::reloadSourceFilesInternal()
void GdbEngine::selectThread(int index)
{
threadsHandler()->setCurrentThread(index);
QList<ThreadData> threads = threadsHandler()->threads();
Threads threads = threadsHandler()->threads();
QTC_ASSERT(index < threads.size(), return);
int id = threads.at(index).id;
showStatusMessage(tr("Retrieving data for stack view..."), 10000);
@@ -2755,7 +2752,7 @@ void GdbEngine::handleStackSelectThread(const GdbResponse &)
QTC_ASSERT(state() == InferiorUnrunnable || state() == InferiorStopped, /**/);
//qDebug("FIXME: StackHandler::handleOutput: SelectThread");
showStatusMessage(tr("Retrieving data for stack view..."), 3000);
manager()->reloadRegisters();
reloadRegisters();
reloadStack(true);
updateLocals();
}
@@ -2889,7 +2886,7 @@ void GdbEngine::handleStackListFrames(const GdbResponse &response)
void GdbEngine::activateFrame(int frameIndex)
{
m_manager->resetLocation();
resetLocation();
if (state() != InferiorStopped && state() != InferiorUnrunnable)
return;
@@ -2930,7 +2927,7 @@ void GdbEngine::handleThreadInfo(const GdbResponse &response)
// file="/.../app.cpp",fullname="/../app.cpp",line="1175"},
// state="stopped",core="0"}],current-thread-id="1"
const QList<GdbMi> items = response.data.findChild("threads").children();
QList<ThreadData> threads;
Threads threads;
for (int index = 0, n = items.size(); index != n; ++index) {
bool ok = false;
const GdbMi item = items.at(index);
@@ -2962,7 +2959,7 @@ void GdbEngine::handleThreadListIds(const GdbResponse &response)
// "72^done,{thread-ids={thread-id="2",thread-id="1"},number-of-threads="2"}
// In gdb 7.1+ additionally: current-thread-id="1"
const QList<GdbMi> items = response.data.findChild("thread-ids").children();
QList<ThreadData> threads;
Threads threads;
int currentIndex = -1;
for (int index = 0, n = items.size(); index != n; ++index) {
ThreadData thread;
@@ -3017,10 +3014,10 @@ void GdbEngine::handleMakeSnapshot(const GdbResponse &response)
void GdbEngine::activateSnapshot(int index)
{
QTC_ASSERT(runControl(), return);
SnapshotData snapshot = snapshotHandler()->setCurrentIndex(index);
DebuggerStartParameters &sp = const_cast<DebuggerStartParameters &>(runControl()->sp());
DebuggerStartParameters &sp =
const_cast<DebuggerStartParameters &>(startParameters());
sp.startMode = AttachCore;
sp.coreFile = snapshot.location();
@@ -3096,7 +3093,7 @@ void GdbEngine::reloadRegisters()
void GdbEngine::setRegisterValue(int nr, const QString &value)
{
Register reg = runControl()->registerHandler()->registers().at(nr);
Register reg = registerHandler()->registers().at(nr);
//qDebug() << "NOT IMPLEMENTED: CHANGE REGISTER " << nr << reg.name << ":"
// << value;
postCommand("-var-delete \"R@\"");
@@ -3119,7 +3116,7 @@ void GdbEngine::handleRegisterListNames(const GdbResponse &response)
foreach (const GdbMi &item, response.data.findChild("register-names").children())
registers.append(Register(item.data()));
runControl()->registerHandler()->setRegisters(registers);
registerHandler()->setRegisters(registers);
if (m_gdbAdapter->isTrkAdapter())
m_gdbAdapter->trkReloadRegisters();
@@ -3130,7 +3127,7 @@ void GdbEngine::handleRegisterListValues(const GdbResponse &response)
if (response.resultClass != GdbResultDone)
return;
Registers registers = runControl()->registerHandler()->registers();
Registers registers = registerHandler()->registers();
// 24^done,register-values=[{number="0",value="0xf423f"},...]
const GdbMi values = response.data.findChild("register-values");
@@ -3167,7 +3164,7 @@ void GdbEngine::handleRegisterListValues(const GdbResponse &response)
reg.value = value;
}
}
runControl()->registerHandler()->setRegisters(registers);
registerHandler()->setRegisters(registers);
}
@@ -3463,7 +3460,7 @@ void GdbEngine::handleVarCreate(const GdbResponse &response)
if (response.resultClass == GdbResultDone) {
data.variable = data.iname;
setWatchDataType(data, response.data.findChild("type"));
if (runControl()->watchHandler()->isExpandedIName(data.iname)
if (watchHandler()->isExpandedIName(data.iname)
&& !response.data.findChild("children").isValid())
data.setChildrenNeeded();
else
@@ -3592,7 +3589,7 @@ void GdbEngine::insertData(const WatchData &data0)
qDebug() << "BOGUS VALUE:" << data.toString();
return;
}
runControl()->watchHandler()->insertData(data);
watchHandler()->insertData(data);
}
void GdbEngine::assignValueInDebugger(const QString &expression, const QString &value)
@@ -3603,11 +3600,6 @@ void GdbEngine::assignValueInDebugger(const QString &expression, const QString &
Discardable, CB(handleVarAssign));
}
QString GdbEngine::qtDumperLibraryName() const
{
return m_manager->qtDumperLibraryName();
}
void GdbEngine::watchPoint(const QPoint &pnt)
{
//qDebug() << "WATCH " << pnt;
@@ -3970,12 +3962,6 @@ void GdbEngine::handleFetchDisassemblerByCli(const GdbResponse &response)
}
}
void GdbEngine::gotoLocation(const StackFrame &frame, bool setMarker)
{
// qDebug() << "GOTO " << frame << setMarker;
m_manager->gotoLocation(frame, setMarker);
}
//
// Starting up & shutting down
//
@@ -3984,14 +3970,15 @@ bool GdbEngine::startGdb(const QStringList &args, const QString &gdb, const QStr
{
gdbProc()->disconnect(); // From any previous runs
m_gdb = QString::fromLatin1(qgetenv("QTC_DEBUGGER_PATH"));
m_gdb = QString::fromLocal8Bit(qgetenv("QTC_DEBUGGER_PATH"));
if (m_gdb.isEmpty())
m_gdb = m_gdbBinaryToolChainMap->key(m_runControl->sp().toolChainType);
m_gdb = gdbBinaryForToolChain(startParameters().toolChainType);
if (m_gdb.isEmpty())
m_gdb = gdb;
if (m_gdb.isEmpty()) {
handleAdapterStartFailed(msgNoBinaryForToolChain(m_runControl->sp().toolChainType),
GdbOptionsPage::settingsId());
handleAdapterStartFailed(
msgNoBinaryForToolChain(startParameters().toolChainType),
GdbOptionsPage::settingsId());
return false;
}
showMessage(_("STARTING GDB ") + m_gdb);
@@ -4224,7 +4211,8 @@ void GdbEngine::handleAdapterStarted()
void GdbEngine::handleInferiorPrepared()
{
const QByteArray qtInstallPath = m_runControl->sp().qtInstallPath.toLocal8Bit();
startSuccessful();
const QByteArray qtInstallPath = startParameters().qtInstallPath.toLocal8Bit();
if (!qtInstallPath.isEmpty()) {
QByteArray qtBuildPath;
#if defined(Q_OS_WIN)
@@ -4288,15 +4276,10 @@ void GdbEngine::handleAdapterCrashed(const QString &msg)
showMessageBox(QMessageBox::Critical, tr("Adapter crashed"), msg);
}
void GdbEngine::addOptionPages(QList<Core::IOptionsPage *> *opts) const
{
opts->push_back(new GdbOptionsPage(m_gdbBinaryToolChainMap));
}
QMessageBox *GdbEngine::showMessageBox(int icon, const QString &title,
const QString &text, int buttons)
{
return m_manager->showMessageBox(icon, title, text, buttons);
return plugin()->showMessageBox(icon, title, text, buttons);
}
void GdbEngine::setUseDebuggingHelpers(const QVariant &on)
@@ -4320,7 +4303,7 @@ void GdbEngine::createFullBacktrace()
void GdbEngine::handleCreateFullBacktrace(const GdbResponse &response)
{
if (response.resultClass == GdbResultDone) {
m_manager->openTextEditor(_("Backtrace $"),
plugin()->openTextEditor(_("Backtrace $"),
_(response.data.findChild("consolestreamoutput").data()));
}
}
@@ -4330,9 +4313,24 @@ void GdbEngine::handleCreateFullBacktrace(const GdbResponse &response)
// Factory
//
IDebuggerEngine *createGdbEngine(DebuggerManager *manager)
bool checkGdbConfiguration(int toolChain, QString *errorMessage, QString *settingsPage)
{
return new GdbEngine(manager);
if (gdbBinaryForToolChain(toolChain).isEmpty()) {
*errorMessage = msgNoBinaryForToolChain(toolChain);
*settingsPage = GdbOptionsPage::settingsId();
return false;
}
return true;
}
DebuggerEngine *createGdbEngine(const DebuggerStartParameters &startParameters)
{
return new GdbEngine(startParameters);
}
void addGdbOptionPages(QList<Core::IOptionsPage *> *opts)
{
opts->push_back(new GdbOptionsPage());
}
} // namespace Internal
+9 -21
View File
@@ -30,8 +30,7 @@
#ifndef DEBUGGER_GDBENGINE_H
#define DEBUGGER_GDBENGINE_H
#include "idebuggerengine.h"
#include "debuggermanager.h" // only for StartParameters
#include "debuggerengine.h"
#include "gdbmi.h"
#include "localgdbprocess.h"
#include "watchutils.h"
@@ -56,7 +55,6 @@ class QTimer;
QT_END_NAMESPACE
namespace Debugger {
class DebuggerManager;
namespace Internal {
class AbstractGdbAdapter;
@@ -83,15 +81,12 @@ enum DebuggingHelperState
};
class GdbEngine : public IDebuggerEngine
class GdbEngine : public DebuggerEngine
{
Q_OBJECT
public:
typedef QMultiMap<QString, int> GdbBinaryToolChainMap;
typedef QSharedPointer<GdbBinaryToolChainMap> GdbBinaryToolChainMapPtr;
explicit GdbEngine(DebuggerManager *manager);
explicit GdbEngine(const DebuggerStartParameters &startParameters);
~GdbEngine();
private:
@@ -107,10 +102,6 @@ private:
private: ////////// General Interface //////////
virtual void addOptionPages(QList<Core::IOptionsPage*> *opts) const;
virtual bool checkConfiguration(int toolChain, QString *errorMessage,
QString *settingsPage = 0) const;
virtual void startDebugger();
virtual unsigned debuggerCapabilities() const;
virtual void exitDebugger();
@@ -125,8 +116,6 @@ private: ////////// General State //////////
void initializeVariables();
DebuggerStartMode startMode() const;
const DebuggerStartParameters &startParameters() const
{ return m_runControl->sp(); }
Q_SLOT void setAutoDerefPointers(const QVariant &on);
bool m_registerNamesListed;
@@ -332,8 +321,6 @@ private: ////////// View & Data Stuff //////////
virtual void selectThread(int index);
virtual void activateFrame(int index);
void gotoLocation(const StackFrame &frame, bool setLocationMarker);
//
// Breakpoint specific stuff
//
@@ -502,8 +489,9 @@ private: ////////// View & Data Stuff //////////
QSet<QByteArray> m_processedNames;
private: ////////// Dumper Management //////////
QString qtDumperLibraryName() const;
//
// Dumper Management
//
bool checkDebuggingHelpers();
bool checkDebuggingHelpersClassic();
void setDebuggingHelperStateClassic(DebuggingHelperState);
@@ -515,13 +503,13 @@ private: ////////// Dumper Management //////////
Q_SLOT void setDebugDebuggingHelpersClassic(const QVariant &on);
Q_SLOT void setUseDebuggingHelpers(const QVariant &on);
const GdbBinaryToolChainMapPtr m_gdbBinaryToolChainMap;
DebuggingHelperState m_debuggingHelperState;
QtDumperHelper m_dumperHelper;
QString m_gdb;
private: ////////// Convenience Functions //////////
//
// Convenience Functions
//
QString errorMessage(QProcess::ProcessError error);
QMessageBox *showMessageBox(int icon, const QString &title, const QString &text,
int buttons = 0);
+5 -4
View File
@@ -38,8 +38,7 @@
namespace Debugger {
namespace Internal {
GdbOptionsPage::GdbOptionsPage(const GdbBinaryToolChainMapPtr &binaryToolChainMap) :
m_binaryToolChainMap(binaryToolChainMap)
GdbOptionsPage::GdbOptionsPage()
{
}
@@ -72,7 +71,8 @@ QWidget *GdbOptionsPage::createPage(QWidget *parent)
{
QWidget *w = new QWidget(parent);
m_ui.setupUi(w);
m_ui.gdbChooserWidget->setGdbBinaries(*m_binaryToolChainMap);
m_ui.gdbChooserWidget
->setGdbBinaries(DebuggerSettings::instance()->gdbBinaryToolChainMap());
m_ui.scriptFileChooser->setExpectedKind(Utils::PathChooser::File);
m_ui.scriptFileChooser->setPromptDialogTitle(tr("Choose Location of Startup Script File"));
@@ -131,7 +131,8 @@ QWidget *GdbOptionsPage::createPage(QWidget *parent)
void GdbOptionsPage::apply()
{
m_group.apply(Core::ICore::instance()->settings());
*m_binaryToolChainMap = m_ui.gdbChooserWidget->gdbBinaries();
DebuggerSettings::instance()
->setGdbBinaryToolChainMap(m_ui.gdbChooserWidget->gdbBinaries());
}
void GdbOptionsPage::finish()
+1 -8
View File
@@ -35,8 +35,6 @@
#include <coreplugin/dialogs/ioptionspage.h>
#include <utils/savedaction.h>
#include <QtCore/QSharedPointer>
#include <QtCore/QMultiMap>
namespace Debugger {
namespace Internal {
@@ -45,10 +43,7 @@ class GdbOptionsPage : public Core::IOptionsPage
{
Q_OBJECT
public:
typedef QMultiMap<QString, int> GdbBinaryToolChainMap;
typedef QSharedPointer<GdbBinaryToolChainMap> GdbBinaryToolChainMapPtr;
explicit GdbOptionsPage(const GdbBinaryToolChainMapPtr &binaryToolChainMap);
explicit GdbOptionsPage();
virtual QString id() const { return settingsId(); }
virtual QString displayName() const;
@@ -64,8 +59,6 @@ public:
static QString settingsId();
private:
const GdbBinaryToolChainMapPtr m_binaryToolChainMap;
Ui::GdbOptionsPage m_ui;
Utils::SavedActionSet m_group;
QString m_searchKeywords;
@@ -123,7 +123,7 @@ void LocalPlainGdbAdapter::checkForReleaseBuild()
void LocalPlainGdbAdapter::interruptInferior()
{
const qint64 attachedPID = runControl()->inferiorPid();
const qint64 attachedPID = m_engine->inferiorPid();
if (attachedPID <= 0) {
showMessage(_("TRYING TO INTERRUPT INFERIOR BEFORE PID WAS OBTAINED"));
return;
+7 -8
View File
@@ -51,9 +51,9 @@ void GdbEngine::updateLocalsPython(const QByteArray &varList)
PRECONDITION;
m_processedNames.clear();
manager()->watchHandler()->beginCycle();
watchHandler()->beginCycle();
//m_toolTipExpression.clear();
WatchHandler *handler = m_manager->watchHandler();
WatchHandler *handler = watchHandler();
QByteArray expanded = "expanded:" + handler->expansionRequests() + ' ';
expanded += "typeformats:" + handler->typeFormatRequests() + ' ';
@@ -130,22 +130,21 @@ void GdbEngine::handleStackFramePython(const GdbResponse &response)
GdbMi data = all.findChild("data");
QList<WatchData> list;
WatchHandler *watchHandler = manager()->watchHandler();
foreach (const GdbMi &child, data.children()) {
WatchData dummy;
dummy.iname = child.findChild("iname").data();
dummy.name = _(child.findChild("name").data());
//qDebug() << "CHILD: " << child.toString();
parseWatchData(watchHandler->expandedINames(), dummy, child, &list);
parseWatchData(watchHandler()->expandedINames(), dummy, child, &list);
}
watchHandler->insertBulkData(list);
watchHandler()->insertBulkData(list);
//for (int i = 0; i != list.size(); ++i)
// qDebug() << "LOCAL: " << list.at(i).toString();
#if 0
data = all.findChild("bkpts");
if (data.isValid()) {
BreakHandler *handler = manager()->breakHandler();
BreakHandler *handler = breakHandler();
foreach (const GdbMi &child, data.children()) {
int bpNumber = child.findChild("number").data().toInt();
int found = handler->findBreakpoint(bpNumber);
@@ -199,12 +198,12 @@ void GdbEngine::updateAllPython()
reloadModulesInternal();
postCommand("-stack-list-frames", CB(handleStackListFrames),
QVariant::fromValue<StackCookie>(StackCookie(false, true)));
manager()->stackHandler()->setCurrentIndex(0);
stackHandler()->setCurrentIndex(0);
if (m_gdbAdapter->isTrkAdapter())
m_gdbAdapter->trkReloadThreads();
else
postCommand("-thread-list-ids", CB(handleThreadListIds), 0);
manager()->reloadRegisters();
reloadRegisters();
updateLocals();
}
@@ -28,25 +28,27 @@
**************************************************************************/
#include "s60debuggerbluetoothstarter.h"
#include "bluetoothlistener.h"
#include "debuggermanager.h"
#include "debuggerengine.h"
#include "trkdevice.h"
namespace Debugger {
namespace Internal {
S60DebuggerBluetoothStarter::S60DebuggerBluetoothStarter(const TrkDevicePtr& trkDevice, QObject *parent) :
trk::AbstractBluetoothStarter(trkDevice, parent)
S60DebuggerBluetoothStarter::S60DebuggerBluetoothStarter
(const TrkDevicePtr& trkDevice, QObject *parent)
: trk::AbstractBluetoothStarter(trkDevice, parent)
{
}
trk::BluetoothListener *S60DebuggerBluetoothStarter::createListener()
{
DebuggerManager *dm = DebuggerManager::instance();
trk::BluetoothListener *rc = new trk::BluetoothListener(dm);
DebuggerEngine *engine = 0; // FIXME: ABC
trk::BluetoothListener *rc = new trk::BluetoothListener(engine);
rc->setMode(trk::BluetoothListener::Listen);
connect(rc, SIGNAL(message(QString)), dm, SLOT(showDebuggerOutput(QString)));
connect(rc, SIGNAL(terminated()), dm, SLOT(startFailed()));
connect(rc, SIGNAL(message(QString)), engine, SLOT(showDebuggerOutput(QString)));
connect(rc, SIGNAL(terminated()), engine, SLOT(startFailed()));
return rc;
}
+2 -2
View File
@@ -120,7 +120,7 @@ void TermGdbAdapter::startInferior()
{
QTC_ASSERT(state() == InferiorStarting, qDebug() << state());
const qint64 attachedPID = m_stubProc.applicationPID();
runControl()->notifyInferiorPid(attachedPID);
m_engine->notifyInferiorPid(attachedPID);
m_engine->postCommand("attach " + QByteArray::number(attachedPID),
CB(handleStubAttached));
}
@@ -159,7 +159,7 @@ void TermGdbAdapter::handleEntryPoint(const GdbResponse &response)
void TermGdbAdapter::interruptInferior()
{
const qint64 attachedPID = runControl()->inferiorPid();
const qint64 attachedPID = m_engine->inferiorPid();
QTC_ASSERT(attachedPID > 0, return);
if (!interruptProcess(attachedPID))
showMessage(_("CANNOT INTERRUPT %1").arg(attachedPID));
+6 -7
View File
@@ -1724,7 +1724,8 @@ bool TrkGdbAdapter::initializeDevice(const QString &remoteChannel, QString *erro
return false;
}
// Run config: Acquire from device manager.
m_trkDevice = SymbianUtils::SymbianDeviceManager::instance()->acquireDevice(remoteChannel);
m_trkDevice = SymbianUtils::SymbianDeviceManager::instance()
->acquireDevice(remoteChannel);
if (m_trkDevice.isNull()) {
*errorMessage = tr("Unable to acquire a device on '%1'. It appears to be in use.").arg(remoteChannel);
return false;
@@ -2140,7 +2141,7 @@ void TrkGdbAdapter::trkReloadRegisters()
{
// Take advantage of direct access to cached register values.
QTC_ASSERT(m_snapshot.registerValid, /**/);
RegisterHandler *handler = m_engine->runControl()->registerHandler();
RegisterHandler *handler = m_engine->registerHandler();
Registers registers = handler->registers();
QTC_ASSERT(registers.size() >= 26,
@@ -2164,12 +2165,10 @@ void TrkGdbAdapter::trkReloadThreads()
{
// Take advantage of direct access to cached register values.
QTC_ASSERT(m_snapshot.registerValid, /**/);
QList<ThreadData> threads;
foreach (const Session::Thread &thread, m_session.threads) {
Threads threads;
foreach (const Session::Thread &thread, m_session.threads)
threads.append(thread);
}
ThreadsHandler *handler = m_engine->manager()->threadsHandler();
handler->setThreads(threads);
m_engine->threadsHandler()->setThreads(threads);
}
} // namespace Internal
-69
View File
@@ -1,69 +0,0 @@
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (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 http://qt.nokia.com/contact.
**
**************************************************************************/
#include "idebuggerengine.h"
#include "debuggermanager.h"
#include <utils/qtcassert.h>
namespace Debugger {
namespace Internal {
void IDebuggerEngine::fetchMemory(MemoryViewAgent *, QObject *,
quint64 addr, quint64 length)
{
Q_UNUSED(addr);
Q_UNUSED(length);
}
void IDebuggerEngine::setRegisterValue(int regnr, const QString &value)
{
Q_UNUSED(regnr);
Q_UNUSED(value);
}
bool IDebuggerEngine::checkConfiguration(int toolChain,
QString *errorMessage, QString *settingsPage) const
{
Q_UNUSED(toolChain);
Q_UNUSED(errorMessage);
Q_UNUSED(settingsPage);
return true;
}
void IDebuggerEngine::showMessage(const QString &msg, int channel, int timeout) const
{
QTC_ASSERT(runControl(), return);
runControl()->showMessage(msg, channel, timeout);
}
} // namespace Internal
} // namespace Debugger
-176
View File
@@ -1,176 +0,0 @@
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (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 http://qt.nokia.com/contact.
**
**************************************************************************/
#ifndef DEBUGGER_IDEBUGGERENGINE_H
#define DEBUGGER_IDEBUGGERENGINE_H
#include "debuggerconstants.h"
#include "moduleshandler.h" // For 'Symbols'.
#include <QtCore/QObject>
#include <QtCore/QList>
#include <QtCore/QSharedPointer>
QT_BEGIN_NAMESPACE
class QPoint;
class QString;
QT_END_NAMESPACE
namespace TextEditor {
class ITextEditor;
}
namespace Core {
class IOptionsPage;
}
namespace Debugger {
class DebuggerManager;
class DebuggerRunControl;
namespace Internal {
class DisassemblerViewAgent;
class MemoryViewAgent;
class Symbol;
class WatchData;
class BreakHandler;
class ModulesHandler;
class RegisterHandler;
class StackHandler;
class SnapshotHandler;
class ThreadsHandler;
class WatchHandler;
class IDebuggerEngine : public QObject
{
Q_OBJECT
public:
IDebuggerEngine(DebuggerManager *manager, QObject *parent = 0)
: QObject(parent), m_manager(manager), m_runControl()
{}
// FIXME: Move this to DebuggerEngineFactory::create(); ?
void setRunControl(DebuggerRunControl *runControl)
{ m_runControl = runControl; }
DebuggerRunControl *runControl() const
{ return m_runControl; }
virtual void shutdown() = 0;
virtual void setToolTipExpression(const QPoint &mousePos, TextEditor::ITextEditor *editor, int cursorPos) = 0;
virtual void startDebugger() = 0;
virtual void exitDebugger() = 0;
virtual void abortDebugger() { exitDebugger(); }
virtual void detachDebugger() {}
virtual void updateWatchData(const WatchData &data) = 0;
virtual void executeStep() = 0;
virtual void executeStepOut() = 0;
virtual void executeNext() = 0;
virtual void executeStepI() = 0;
virtual void executeNextI() = 0;
virtual void executeReturn() {}
virtual void continueInferior() = 0;
virtual void interruptInferior() = 0;
virtual void executeRunToLine(const QString &fileName, int lineNumber) = 0;
virtual void executeRunToFunction(const QString &functionName) = 0;
virtual void executeJumpToLine(const QString &fileName, int lineNumber) = 0;
virtual void assignValueInDebugger(const QString &expr, const QString &value) = 0;
virtual void executeDebuggerCommand(const QString &command) = 0;
virtual void activateFrame(int index) = 0;
virtual void selectThread(int index) = 0;
virtual void makeSnapshot() {}
virtual void activateSnapshot(int index) { Q_UNUSED(index); }
virtual void attemptBreakpointSynchronization() = 0;
virtual void reloadModules() = 0;
virtual void loadSymbols(const QString &moduleName) = 0;
virtual void loadAllSymbols() = 0;
virtual void requestModuleSymbols(const QString &moduleName) = 0;
virtual void reloadRegisters() = 0;
virtual void reloadSourceFiles() = 0;
virtual void reloadFullStack() = 0;
virtual void watchPoint(const QPoint &) {}
virtual void fetchMemory(MemoryViewAgent *, QObject *,
quint64 addr, quint64 length);
virtual void fetchDisassembler(DisassemblerViewAgent *) {}
virtual void setRegisterValue(int regnr, const QString &value);
virtual void addOptionPages(QList<Core::IOptionsPage*> *) const {}
virtual unsigned debuggerCapabilities() const { return 0; }
virtual bool checkConfiguration(int toolChain,
QString *errorMessage, QString *settingsPage = 0) const;
virtual bool isSynchroneous() const { return false; }
virtual QString qtNamespace() const { return QString(); }
public slots:
// Convenience
void showMessage(const QString &msg, int channel = LogDebug, int timeout = -1) const;
void showStatusMessage(const QString &msg, int timeout = -1) const
{ showMessage(msg, StatusBar, timeout); }
public:
DebuggerManager *manager() const { return m_manager; }
bool debuggerActionsEnabled() const;
void showModuleSymbols(const QString &moduleName, const Symbols &symbols);
ModulesHandler *modulesHandler() const;
BreakHandler *breakHandler() const;
RegisterHandler *registerHandler() const;
StackHandler *stackHandler() const;
ThreadsHandler *threadsHandler() const;
WatchHandler *watchHandler() const;
SnapshotHandler *snapshotHandler() const;
protected:
DebuggerState state() const;
void setState(DebuggerState state, bool forced = false);
DebuggerManager *m_manager;
DebuggerRunControl *m_runControl;
signals:
void startSuccessful();
void startFailed();
};
} // namespace Internal
} // namespace Debugger
#endif // DEBUGGER_IDEBUGGERENGINE_H
+29 -25
View File
@@ -28,8 +28,7 @@
**************************************************************************/
#include "moduleshandler.h"
#include "idebuggerengine.h"
#include "debuggerrunner.h"
#include "debuggerengine.h"
#include <utils/qtcassert.h>
@@ -55,7 +54,7 @@ namespace Internal {
class ModulesModel : public QAbstractItemModel
{
public:
explicit ModulesModel(ModulesHandler *parent, DebuggerRunControl *runControl);
explicit ModulesModel(ModulesHandler *parent, DebuggerEngine *engine);
// QAbstractItemModel
int columnCount(const QModelIndex &parent) const
@@ -75,21 +74,19 @@ public:
void setModules(const Modules &m);
const Modules &modules() const { return m_modules; }
IDebuggerEngine *engine() { return m_runControl->engine(); }
const IDebuggerEngine *engine() const { return m_runControl->engine(); }
private:
int indexOfModule(const QString &name) const;
DebuggerRunControl *m_runControl;
DebuggerEngine *m_engine;
const QVariant m_yes;
const QVariant m_no;
Modules m_modules;
};
ModulesModel::ModulesModel(ModulesHandler *parent, DebuggerRunControl *runControl)
ModulesModel::ModulesModel(ModulesHandler *parent, DebuggerEngine *engine)
: QAbstractItemModel(parent),
m_runControl(runControl), m_yes(tr("yes")), m_no(tr("no"))
m_engine(engine), m_yes(tr("yes")), m_no(tr("no"))
{}
QVariant ModulesModel::headerData(int section,
@@ -110,11 +107,11 @@ QVariant ModulesModel::headerData(int section,
QVariant ModulesModel::data(const QModelIndex &index, int role) const
{
if (role == EngineCapabilityRole)
return engine()->debuggerCapabilities();
if (role == EngineCapabilitiesRole)
return m_engine->debuggerCapabilities();
if (role == EngineActionsEnabledRole)
return engine()->debuggerActionsEnabled();
return m_engine->debuggerActionsEnabled();
int row = index.row();
if (row < 0 || row >= m_modules.size())
@@ -152,19 +149,26 @@ QVariant ModulesModel::data(const QModelIndex &index, int role) const
bool ModulesModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
if (role == RequestReloadModulesRole) {
engine()->reloadModules();
return true;
Q_UNUSED(index);
switch (role) {
case RequestReloadModulesRole:
m_engine->reloadModules();
return true;
case RequestModuleSymbolsRole:
m_engine->loadSymbols(value.toString());
return true;
case RequestAllSymbolsRole:
m_engine->loadAllSymbols();
return true;
case RequestOpenFileRole:
m_engine->openFile(value.toString());
return true;
}
if (role == RequestModuleSymbolsRole) {
engine()->loadSymbols(value.toString());
return true;
}
if (role == RequestAllSymbolsRole) {
engine()->loadAllSymbols();
return true;
}
return QAbstractItemModel::setData(index, value, role);
return false;
}
void ModulesModel::addModule(const Module &m)
@@ -213,9 +217,9 @@ void ModulesModel::removeModule(const QString &moduleName)
//
//////////////////////////////////////////////////////////////////
ModulesHandler::ModulesHandler(DebuggerRunControl *runControl)
ModulesHandler::ModulesHandler(DebuggerEngine *engine)
{
m_model = new ModulesModel(this, runControl);
m_model = new ModulesModel(this, engine);
m_proxyModel = new QSortFilterProxyModel(this);
m_proxyModel->setSourceModel(m_model);
}
+2 -4
View File
@@ -40,11 +40,9 @@ QT_END_NAMESPACE
namespace Debugger {
class DebuggerRunControl;
namespace Internal {
class DebuggerEngine;
class ModulesModel;
//////////////////////////////////////////////////////////////////
@@ -94,7 +92,7 @@ typedef QList<Module> Modules;
class ModulesHandler : public QObject
{
public:
explicit ModulesHandler(DebuggerRunControl *runControl);
explicit ModulesHandler(DebuggerEngine *engine);
QAbstractItemModel *model() const;
+15 -12
View File
@@ -72,8 +72,8 @@ ModulesWindow::ModulesWindow(QWidget *parent)
void ModulesWindow::moduleActivated(const QModelIndex &index)
{
qDebug() << "ACTIVATED: " << index.row() << index.column()
<< model()->data(index);
emit fileOpenRequested(model()->data(index).toString());
<< index.data().toString();
setModelData(RequestOpenFileRole, index.data().toString());
}
void ModulesWindow::resizeEvent(QResizeEvent *event)
@@ -104,7 +104,7 @@ void ModulesWindow::contextMenuEvent(QContextMenuEvent *ev)
const bool enabled =
model() && model()->data(index, EngineActionsEnabledRole).toBool();
const unsigned capabilities =
model()->data(index, EngineCapabilityRole).toInt();
model()->data(index, EngineCapabilitiesRole).toInt();
QMenu menu;
QAction *act0 = new QAction(tr("Update Module List"), &menu);
@@ -149,8 +149,7 @@ void ModulesWindow::contextMenuEvent(QContextMenuEvent *ev)
QAction *act = menu.exec(ev->globalPos());
if (act == act0) {
QTC_ASSERT(model(), return);
model()->setData(QModelIndex(), QVariant(), RequestReloadModulesRole);
setModelData(RequestReloadModulesRole);
} else if (act == actAdjustColumnWidths) {
resizeColumnsToContents();
} else if (act == actAlwaysAdjustColumnWidth) {
@@ -158,16 +157,13 @@ void ModulesWindow::contextMenuEvent(QContextMenuEvent *ev)
//} else if (act == act3) {
// emit displaySourceRequested(name);
} else if (act == act4) {
QTC_ASSERT(model(), return);
model()->setData(QModelIndex(), QVariant(), RequestAllSymbolsRole);
setModelData(RequestAllSymbolsRole);
} else if (act == act5) {
QTC_ASSERT(model(), return);
model()->setData(QModelIndex(), name, RequestModuleSymbolsRole);
setModelData(RequestModuleSymbolsRole, name);
} else if (act == act6) {
emit fileOpenRequested(name);
setModelData(RequestOpenFileRole, name);
} else if (act == act7) {
QTC_ASSERT(model(), return);
model()->setData(QModelIndex(), name, RequestModuleSymbolsRole);
setModelData(RequestModuleSymbolsRole, name);
}
}
@@ -198,5 +194,12 @@ void ModulesWindow::setModel(QAbstractItemModel *model)
setAlwaysResizeColumnsToContents(true);
}
void ModulesWindow::setModelData
(int role, const QVariant &value, const QModelIndex &index)
{
QTC_ASSERT(model(), return);
model()->setData(index, value, role);
}
} // namespace Internal
} // namespace Debugger
+2 -3
View File
@@ -42,9 +42,6 @@ class ModulesWindow : public QTreeView
public:
explicit ModulesWindow(QWidget *parent = 0);
signals:
void fileOpenRequested(QString);
private slots:
void resizeColumnsToContents();
void setAlwaysResizeColumnsToContents(bool on);
@@ -55,6 +52,8 @@ private:
void resizeEvent(QResizeEvent *ev);
void contextMenuEvent(QContextMenuEvent *ev);
void setModel(QAbstractItemModel *model);
void setModelData(int role, const QVariant &value = QVariant(),
const QModelIndex &index = QModelIndex());
bool m_alwaysResizeColumnsToContents;
};
+39 -38
View File
@@ -32,16 +32,18 @@
#include "pdbengine.h"
#include "debuggeractions.h"
#include "debuggerdialogs.h"
#include "breakhandler.h"
#include "debuggerconstants.h"
#include "debuggermanager.h"
#include "debuggerdialogs.h"
#include "debuggerplugin.h"
#include "debuggerstringutils.h"
#include "breakhandler.h"
#include "moduleshandler.h"
#include "registerhandler.h"
#include "stackhandler.h"
#include "watchhandler.h"
#include "watchutils.h"
#include "debuggerstringutils.h"
#include "../gdb/gdbmi.h"
#include <utils/qtcassert.h>
@@ -83,8 +85,8 @@ namespace Internal {
//
///////////////////////////////////////////////////////////////////////
PdbEngine::PdbEngine(DebuggerManager *manager)
: IDebuggerEngine(manager)
PdbEngine::PdbEngine(const DebuggerStartParameters &startParameters)
: DebuggerEngine(startParameters)
{}
PdbEngine::~PdbEngine()
@@ -138,16 +140,15 @@ void PdbEngine::exitDebugger()
void PdbEngine::startDebugger()
{
QTC_ASSERT(runControl(), return);
setState(AdapterStarting);
m_scriptFileName = QFileInfo(runControl()->sp().executable).absoluteFilePath();
m_scriptFileName = QFileInfo(startParameters().executable).absoluteFilePath();
QFile scriptFile(m_scriptFileName);
if (!scriptFile.open(QIODevice::ReadOnly|QIODevice::Text)) {
//showMessage("STARTING " +m_scriptFileName + "FAILED");
showMessage(QString::fromLatin1("Cannot open %1: %2").
arg(m_scriptFileName, scriptFile.errorString()), LogError);
emit startFailed();
startFailed();
return;
}
setState(AdapterStarted);
@@ -192,7 +193,7 @@ void PdbEngine::startDebugger()
Core::ICore::instance()->showWarningWithOptions(title, msg);
}
shutdown();
emit startFailed();
startFailed();
return;
}
@@ -220,7 +221,7 @@ void PdbEngine::interruptInferior()
void PdbEngine::executeStep()
{
m_manager->resetLocation();
resetLocation();
setState(InferiorRunningRequested);
setState(InferiorRunning);
postCommand("step", CB(handleUpdateAll));
@@ -228,7 +229,7 @@ void PdbEngine::executeStep()
void PdbEngine::executeStepI()
{
m_manager->resetLocation();
resetLocation();
setState(InferiorRunningRequested);
setState(InferiorRunning);
postCommand("step", CB(handleUpdateAll));
@@ -236,7 +237,7 @@ void PdbEngine::executeStepI()
void PdbEngine::executeStepOut()
{
m_manager->resetLocation();
resetLocation();
setState(InferiorRunningRequested);
setState(InferiorRunning);
postCommand("finish", CB(handleUpdateAll));
@@ -244,7 +245,7 @@ void PdbEngine::executeStepOut()
void PdbEngine::executeNext()
{
m_manager->resetLocation();
resetLocation();
setState(InferiorRunningRequested);
setState(InferiorRunning);
postCommand("next", CB(handleUpdateAll));
@@ -252,7 +253,7 @@ void PdbEngine::executeNext()
void PdbEngine::executeNextI()
{
m_manager->resetLocation();
resetLocation();
setState(InferiorRunningRequested);
setState(InferiorRunning);
postCommand("next", CB(handleUpdateAll));
@@ -260,7 +261,7 @@ void PdbEngine::executeNextI()
void PdbEngine::continueInferior()
{
m_manager->resetLocation();
resetLocation();
setState(InferiorRunningRequested);
setState(InferiorRunning);
// Callback will be triggered e.g. when breakpoint is hit.
@@ -289,29 +290,29 @@ void PdbEngine::executeJumpToLine(const QString &fileName, int lineNumber)
void PdbEngine::activateFrame(int frameIndex)
{
manager()->resetLocation();
resetLocation();
if (state() != InferiorStopped && state() != InferiorUnrunnable)
return;
StackHandler *stackHandler = manager()->stackHandler();
int oldIndex = stackHandler->currentIndex();
StackHandler *handler = stackHandler();
int oldIndex = handler->currentIndex();
//if (frameIndex == stackHandler->stackSize()) {
//if (frameIndex == handler->stackSize()) {
// reloadFullStack();
// return;
//}
QTC_ASSERT(frameIndex < stackHandler->stackSize(), return);
QTC_ASSERT(frameIndex < handler->stackSize(), return);
if (oldIndex != frameIndex) {
// Assuming the command always succeeds this saves a roundtrip.
// Otherwise the lines below would need to get triggered
// after a response to this -stack-select-frame here.
stackHandler->setCurrentIndex(frameIndex);
handler->setCurrentIndex(frameIndex);
//postCommand("-stack-select-frame " + QByteArray::number(frameIndex),
// CB(handleStackSelectFrame));
}
manager()->gotoLocation(stackHandler->currentFrame(), true);
gotoLocation(handler->currentFrame(), true);
}
void PdbEngine::selectThread(int index)
@@ -336,7 +337,7 @@ static QByteArray breakpointLocation(const BreakpointData *data)
void PdbEngine::attemptBreakpointSynchronization()
{
BreakHandler *handler = manager()->breakHandler();
BreakHandler *handler = breakHandler();
//qDebug() << "ATTEMPT BP SYNC";
bool updateNeeded = false;
for (int index = 0; index != handler->size(); ++index) {
@@ -368,7 +369,7 @@ void PdbEngine::handleBreakInsert(const PdbResponse &response)
//qDebug() << "BP RESPONSE: " << response.data;
// "Breakpoint 1 at /pdb/math.py:10"
int index = response.cookie.toInt();
BreakHandler *handler = manager()->breakHandler();
BreakHandler *handler = breakHandler();
BreakpointData *data = handler->at(index);
QTC_ASSERT(data, return);
QTC_ASSERT(response.data.startsWith("Breakpoint "), return);
@@ -419,7 +420,7 @@ void PdbEngine::handleListModules(const PdbResponse &response)
module.modulePath = path;
modules.append(module);
}
runControl()->modulesHandler()->setModules(modules);
modulesHandler()->setModules(modules);
}
void PdbEngine::requestModuleSymbols(const QString &moduleName)
@@ -516,7 +517,7 @@ void PdbEngine::setToolTipExpression(const QPoint &mousePos,
}
#if 0
//if (m_manager->status() != InferiorStopped)
//if (status() != InferiorStopped)
// return;
// FIXME: 'exp' can contain illegal characters
@@ -567,7 +568,7 @@ void PdbEngine::handlePdbError(QProcess::ProcessError error)
default:
m_pdbProc.kill();
setState(EngineShuttingDown, true);
m_manager->showMessageBox(QMessageBox::Critical, tr("Pdb I/O Error"),
plugin()->showMessageBox(QMessageBox::Critical, tr("Pdb I/O Error"),
errorMessage(error));
break;
}
@@ -664,7 +665,7 @@ void PdbEngine::handleResponse(const QByteArray &response0)
frame.file = _(fileName);
frame.line = lineNumber;
if (frame.line > 0 && QFileInfo(frame.file).exists()) {
manager()->gotoLocation(frame, true);
gotoLocation(frame, true);
setState(InferiorStopping);
setState(InferiorStopped);
return;
@@ -685,7 +686,7 @@ void PdbEngine::updateAll()
setState(InferiorStopping);
setState(InferiorStopped);
WatchHandler *handler = m_manager->watchHandler();
WatchHandler *handler = watchHandler();
QByteArray watchers;
//if (!m_toolTipExpression.isEmpty())
@@ -767,13 +768,13 @@ void PdbEngine::handleBacktrace(const PdbResponse &response)
const int frameCount = stackFrames.size();
for (int i = 0; i != frameCount; ++i)
stackFrames[i].level = frameCount - stackFrames[i].level - 1;
manager()->stackHandler()->setFrames(stackFrames);
stackHandler()->setFrames(stackFrames);
// Select current frame.
if (currentIndex != -1) {
currentIndex = frameCount - currentIndex - 1;
manager()->stackHandler()->setCurrentIndex(currentIndex);
manager()->gotoLocation(stackFrames.at(currentIndex), true);
stackHandler()->setCurrentIndex(currentIndex);
gotoLocation(stackFrames.at(currentIndex), true);
}
}
@@ -788,15 +789,15 @@ void PdbEngine::handleListLocals(const PdbResponse &response)
//GdbMi data = all.findChild("data");
QList<WatchData> list;
WatchHandler *watchHandler = manager()->watchHandler();
WatchHandler *handler = watchHandler();
foreach (const GdbMi &child, all.children()) {
WatchData dummy;
dummy.iname = child.findChild("iname").data();
dummy.name = _(child.findChild("name").data());
//qDebug() << "CHILD: " << child.toString();
parseWatchData(watchHandler->expandedINames(), dummy, child, &list);
parseWatchData(handler->expandedINames(), dummy, child, &list);
}
watchHandler->insertBulkData(list);
handler->insertBulkData(list);
}
void PdbEngine::handleLoadDumper(const PdbResponse &response)
@@ -811,9 +812,9 @@ unsigned PdbEngine::debuggerCapabilities() const
return ReloadModuleCapability;
}
IDebuggerEngine *createPdbEngine(DebuggerManager *manager)
DebuggerEngine *createPdbEngine(const DebuggerStartParameters &startParameters)
{
return new PdbEngine(manager);
return new PdbEngine(startParameters);
}
+4 -4
View File
@@ -30,7 +30,7 @@
#ifndef DEBUGGER_PDBENGINE_H
#define DEBUGGER_PDBENGINE_H
#include "idebuggerengine.h"
#include "debuggerengine.h"
#include <QtCore/QProcess>
#include <QtCore/QQueue>
@@ -53,16 +53,16 @@ public:
QVariant cookie;
};
class PdbEngine : public IDebuggerEngine
class PdbEngine : public DebuggerEngine
{
Q_OBJECT
public:
PdbEngine(DebuggerManager *manager);
explicit PdbEngine(const DebuggerStartParameters &startParameters);
~PdbEngine();
private:
// IDebuggerEngine implementation
// DebuggerEngine implementation
void executeStep();
void executeStepOut();
void executeNext();
+12 -15
View File
@@ -29,17 +29,16 @@
#include "qmlengine.h"
#include "debuggerstringutils.h"
#include "debuggerdialogs.h"
#include "breakhandler.h"
#include "debuggerconstants.h"
#include "debuggermanager.h"
#include "debuggerdialogs.h"
#include "debuggerstringutils.h"
#include "breakhandler.h"
#include "moduleshandler.h"
#include "registerhandler.h"
#include "stackhandler.h"
#include "watchhandler.h"
#include "watchutils.h"
#include "moduleshandler.h"
#include <utils/qtcassert.h>
@@ -104,8 +103,8 @@ QString QmlEngine::QmlCommand::toString() const
//
///////////////////////////////////////////////////////////////////////
QmlEngine::QmlEngine(DebuggerManager *manager)
: IDebuggerEngine(manager)
QmlEngine::QmlEngine(const DebuggerStartParameters &startParameters)
: DebuggerEngine(startParameters)
{
m_congestion = 0;
m_inAir = 0;
@@ -169,7 +168,7 @@ void QmlEngine::socketError(QAbstractSocket::SocketError)
QString msg = tr("%1.").arg(m_socket->errorString());
//QMessageBox::critical(q->mainWindow(), tr("Error"), msg);
showStatusMessage(msg);
manager()->notifyInferiorExited();
exitDebugger();
}
void QmlEngine::executeDebuggerCommand(const QString &command)
@@ -198,22 +197,20 @@ void QmlEngine::shutdown()
void QmlEngine::exitDebugger()
{
SDEBUG("QmlEngine::exitDebugger()");
manager()->notifyInferiorExited();
}
void QmlEngine::startDebugger()
{
QTC_ASSERT(runControl(), return);
qDebug() << "STARTING QML ENGINE";
setState(InferiorRunningRequested);
showStatusMessage(tr("Running requested..."), 5000);
const DebuggerStartParameters &sp = runControl()->sp();
const DebuggerStartParameters &sp = startParameters();
const int pos = sp.remoteChannel.indexOf(QLatin1Char(':'));
const QString host = sp.remoteChannel.left(pos);
const quint16 port = sp.remoteChannel.mid(pos + 1).toInt();
//QTimer::singleShot(0, this, SLOT(runInferior()));
m_socket->connectToHost(host, port);
emit startSuccessful();
startSuccessful();
}
void QmlEngine::continueInferior()
@@ -526,7 +523,7 @@ void QmlEngine::updateLocals()
void QmlEngine::updateWatchData(const WatchData &)
{
//qq->watchHandler()->rebuildModel();
//watchHandler()->rebuildModel();
showStatusMessage(tr("Stopped."), 5000);
}
@@ -536,9 +533,9 @@ void QmlEngine::updateSubItem(const WatchData &data0)
QTC_ASSERT(false, return);
}
IDebuggerEngine *createQmlEngine(DebuggerManager *manager)
DebuggerEngine *createQmlEngine(const DebuggerStartParameters &sp)
{
return new QmlEngine(manager);
return new QmlEngine(sp);
}
} // namespace Internal
+5 -5
View File
@@ -47,8 +47,8 @@ QT_BEGIN_NAMESPACE
class QTcpSocket;
QT_END_NAMESPACE
#include "idebuggerengine.h"
#include "debuggermanager.h"
#include "debuggerengine.h"
namespace Debugger {
namespace Internal {
@@ -57,16 +57,16 @@ class ScriptAgent;
class WatchData;
class QmlResponse;
class QmlEngine : public IDebuggerEngine
class QmlEngine : public DebuggerEngine
{
Q_OBJECT
public:
explicit QmlEngine(DebuggerManager *parent);
explicit QmlEngine(const DebuggerStartParameters &startParameters);
~QmlEngine();
private:
// IDebuggerEngine implementation
// DebuggerEngine implementation
void executeStep();
void executeStepOut();
void executeNext();
+38 -4
View File
@@ -29,7 +29,10 @@
#include "registerhandler.h"
#include "debuggeractions.h"
#include "debuggeragents.h"
#include "debuggerconstants.h"
#include "debuggerengine.h"
#include <utils/qtcassert.h>
@@ -49,8 +52,8 @@ using namespace Debugger::Constants;
//
//////////////////////////////////////////////////////////////////
RegisterHandler::RegisterHandler(QObject *parent)
: QAbstractTableModel(parent)
RegisterHandler::RegisterHandler(DebuggerEngine *engine)
: m_engine(engine)
{
setNumberBase(16);
}
@@ -67,8 +70,19 @@ int RegisterHandler::columnCount(const QModelIndex &parent) const
QVariant RegisterHandler::data(const QModelIndex &index, int role) const
{
if (role == RegisterNumberBaseRole)
return m_base;
switch (role) {
case EngineStateRole:
return m_engine->state();
case EngineCapabilitiesRole:
return m_engine->debuggerCapabilities();
case EngineActionsEnabledRole:
return m_engine->debuggerActionsEnabled();
case RegisterNumberBaseRole:
return m_base;
}
if (!index.isValid() || index.row() >= m_registers.size())
return QVariant();
@@ -136,6 +150,26 @@ Qt::ItemFlags RegisterHandler::flags(const QModelIndex &idx) const
return notEditable;
}
bool RegisterHandler::setData(const QModelIndex &index, const QVariant &value, int role)
{
switch (role) {
case RequestSetRegisterRole:
m_engine->setRegisterValue(index.row(), value.toString());
return true;
case RequestReloadRegistersRole:
m_engine->reloadRegisters();
return true;
case RequestShowMemoryRole:
(void) new MemoryViewAgent(m_engine, value.toString());
return true;
default:
return QAbstractTableModel::setData(index, value, role);
}
}
void RegisterHandler::removeAll()
{
m_registers.clear();
+5 -8
View File
@@ -36,12 +36,7 @@
namespace Debugger {
namespace Internal {
enum RegisterRole
{
RegisterNumberBaseRole = Qt::UserRole, // Currently used number base
RegisterAddressRole, // Start value for opening memory view
RegisterChangedRole // Used for painting changed values
};
class DebuggerEngine;
class Register
{
@@ -62,7 +57,7 @@ class RegisterHandler : public QAbstractTableModel
Q_OBJECT
public:
RegisterHandler(QObject *parent = 0);
explicit RegisterHandler(DebuggerEngine *engine);
QAbstractItemModel *model() { return this; }
@@ -76,13 +71,15 @@ private:
int rowCount(const QModelIndex &parent = QModelIndex()) const;
int columnCount(const QModelIndex &parent = QModelIndex()) const;
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
bool setData(const QModelIndex &index, const QVariant &, int role);
QVariant headerData(int section, Qt::Orientation orientation,
int role = Qt::DisplayRole) const;
Qt::ItemFlags flags(const QModelIndex &idx) const;
DebuggerEngine *m_engine; // Not owned.
Registers m_registers;
int m_base;
int m_strlen; // approximate width of an value in chars
int m_strlen; // approximate width of a value in chars.
};
} // namespace Internal
+35 -20
View File
@@ -28,11 +28,8 @@
**************************************************************************/
#include "registerwindow.h"
#include "registerhandler.h"
#include "debuggeractions.h"
#include "debuggeragents.h"
#include "debuggermanager.h"
#include "debuggerconstants.h"
#include <utils/qtcassert.h>
@@ -64,8 +61,8 @@ namespace Internal {
class RegisterDelegate : public QItemDelegate
{
public:
RegisterDelegate(DebuggerManager *manager, QObject *parent)
: QItemDelegate(parent), m_manager(manager)
RegisterDelegate(RegisterWindow *owner, QObject *parent)
: QItemDelegate(parent), m_owner(owner)
{}
QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &,
@@ -80,7 +77,7 @@ public:
{
QLineEdit *lineEdit = qobject_cast<QLineEdit *>(editor);
QTC_ASSERT(lineEdit, return);
lineEdit->setText(index.model()->data(index, Qt::DisplayRole).toString());
lineEdit->setText(index.data(Qt::DisplayRole).toString());
}
void setModelData(QWidget *editor, QAbstractItemModel *model,
@@ -93,7 +90,7 @@ public:
QString value = lineEdit->text();
//model->setData(index, value, Qt::EditRole);
if (index.column() == 1)
m_manager->setRegisterValue(index.row(), value);
m_owner->model()->setData(index, value, RequestSetRegisterRole);
}
void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option,
@@ -134,7 +131,7 @@ public:
}
private:
DebuggerManager *m_manager;
RegisterWindow *m_owner;
};
@@ -144,15 +141,15 @@ private:
//
///////////////////////////////////////////////////////////////////////
RegisterWindow::RegisterWindow(DebuggerManager *manager)
: m_manager(manager), m_alwaysResizeColumnsToContents(true)
RegisterWindow::RegisterWindow(QWidget *parent)
: QTreeView(parent), m_alwaysResizeColumnsToContents(true)
{
QAction *act = theDebuggerAction(UseAlternatingRowColors);
setWindowTitle(tr("Registers"));
setAttribute(Qt::WA_MacShowFocusRect, false);
setAlternatingRowColors(act->isChecked());
setRootIsDecorated(false);
setItemDelegate(new RegisterDelegate(m_manager, this));
setItemDelegate(new RegisterDelegate(this, this));
connect(act, SIGNAL(toggled(bool)),
this, SLOT(setAlternatingRowColorsHelper(bool)));
@@ -167,18 +164,18 @@ void RegisterWindow::contextMenuEvent(QContextMenuEvent *ev)
{
QMenu menu;
const unsigned engineCapabilities = m_manager->debuggerCapabilities();
const bool actionsEnabled = m_manager->debuggerActionsEnabled();
const unsigned engineCapabilities = modelData(EngineCapabilitiesRole).toUInt();
const bool actionsEnabled = modelData(EngineActionsEnabledRole).toInt();
const int state = modelData(EngineStateRole).toInt();
QAction *actReload = menu.addAction(tr("Reload Register Listing"));
actReload->setEnabled((engineCapabilities & RegisterCapability)
&& (m_manager->state() == InferiorStopped
|| m_manager->state() == InferiorUnrunnable));
&& (state == InferiorStopped || state == InferiorUnrunnable));
menu.addSeparator();
QModelIndex idx = indexAt(ev->pos());
QString address = model()->data(idx, RegisterAddressRole).toString();
QString address = modelData(RegisterAddressRole, idx).toString();
QAction *actShowMemory = menu.addAction(QString());
if (address.isEmpty()) {
actShowMemory->setText(tr("Open Memory Editor"));
@@ -190,7 +187,7 @@ void RegisterWindow::contextMenuEvent(QContextMenuEvent *ev)
}
menu.addSeparator();
int base = model()->data(QModelIndex(), RegisterNumberBaseRole).toInt();
int base = modelData(RegisterNumberBaseRole).toInt();
QAction *act16 = menu.addAction(tr("Hexadecimal"));
act16->setCheckable(true);
act16->setChecked(base == 16);
@@ -221,9 +218,9 @@ void RegisterWindow::contextMenuEvent(QContextMenuEvent *ev)
else if (act == actAlwaysAdjust)
setAlwaysResizeColumnsToContents(!m_alwaysResizeColumnsToContents);
else if (act == actReload)
m_manager->reloadRegisters();
setModelData(RequestReloadRegistersRole);
else if (act == actShowMemory)
(void) new MemoryViewAgent(m_manager, address);
setModelData(RequestShowMemoryRole, address);
else if (act) {
base = (act == act10 ? 10 : act == act8 ? 8 : act == act2 ? 2 : 16);
QMetaObject::invokeMethod(model(), "setNumberBase", Q_ARG(int, base));
@@ -245,12 +242,30 @@ void RegisterWindow::setAlwaysResizeColumnsToContents(bool on)
header()->setResizeMode(1, mode);
}
void RegisterWindow::setModel(QAbstractItemModel *model)
{
QTreeView::setModel(model);
setAlwaysResizeColumnsToContents(true);
}
void RegisterWindow::reloadRegisters()
{
// FIXME: Only trigger when becoming visible?
setModelData(RequestReloadRegistersRole);
}
void RegisterWindow::setModelData
(int role, const QVariant &value, const QModelIndex &index)
{
QTC_ASSERT(model(), return);
model()->setData(index, value, role);
}
QVariant RegisterWindow::modelData(int role, const QModelIndex &index)
{
QTC_ASSERT(model(), return QVariant());
return model()->data(index, role);
}
} // namespace Internal
} // namespace Debugger
+5 -5
View File
@@ -33,9 +33,6 @@
#include <QtGui/QTreeView>
namespace Debugger {
class DebuggerManager;
namespace Internal {
class RegisterWindow : public QTreeView
@@ -43,19 +40,22 @@ class RegisterWindow : public QTreeView
Q_OBJECT
public:
explicit RegisterWindow(DebuggerManager *manager);
explicit RegisterWindow(QWidget *parent = 0);
void setModel(QAbstractItemModel *model);
public slots:
void resizeColumnsToContents();
void setAlwaysResizeColumnsToContents(bool on);
void setAlternatingRowColorsHelper(bool on) { setAlternatingRowColors(on); }
void reloadRegisters();
private:
void resizeEvent(QResizeEvent *ev);
void contextMenuEvent(QContextMenuEvent *ev);
DebuggerManager *m_manager;
void setModelData(int role, const QVariant &value = QVariant(),
const QModelIndex &index = QModelIndex());
QVariant modelData(int role, const QModelIndex &index = QModelIndex());
bool m_alwaysResizeColumnsToContents;
};
+23 -21
View File
@@ -31,10 +31,9 @@
#include "scriptengine.h"
#include "debuggerdialogs.h"
#include "breakhandler.h"
#include "debuggerconstants.h"
#include "debuggermanager.h"
#include "debuggerdialogs.h"
#include "moduleshandler.h"
#include "registerhandler.h"
#include "stackhandler.h"
@@ -192,8 +191,8 @@ void ScriptAgent::scriptUnload(qint64 scriptId)
//
///////////////////////////////////////////////////////////////////////
ScriptEngine::ScriptEngine(DebuggerManager *manager)
: IDebuggerEngine(manager)
ScriptEngine::ScriptEngine(const DebuggerStartParameters &startParameters)
: DebuggerEngine(startParameters)
{
}
@@ -231,6 +230,9 @@ void ScriptEngine::exitDebugger()
void ScriptEngine::startDebugger()
{
qDebug() << "STARTING SCRIPT DEBUGGER";
QTC_ASSERT(state() == DebuggerNotReady, setState(DebuggerNotReady));
setState(EngineStarting);
setState(AdapterStarting);
if (m_scriptEngine.isNull())
m_scriptEngine = Core::ICore::instance()->scriptManager()->scriptEngine();
@@ -248,13 +250,13 @@ void ScriptEngine::startDebugger()
setState(AdapterStarted);
setState(InferiorStarting);
QTC_ASSERT(runControl(), return);
m_scriptFileName = QFileInfo(runControl()->sp().executable).absoluteFilePath();
m_scriptFileName = QFileInfo(startParameters().executable).absoluteFilePath();
qDebug() << "SCRIPT FILE: " << m_scriptFileName;
QFile scriptFile(m_scriptFileName);
if (!scriptFile.open(QIODevice::ReadOnly|QIODevice::Text)) {
showMessage(QString::fromLatin1("Cannot open %1: %2").
arg(m_scriptFileName, scriptFile.errorString()), LogError);
emit startFailed();
startFailed();
return;
}
QTextStream stream(&scriptFile);
@@ -265,7 +267,7 @@ void ScriptEngine::startDebugger()
showStatusMessage(tr("Running requested..."), 5000);
showMessage(QLatin1String("Running: ") + m_scriptFileName, LogMisc);
QTimer::singleShot(0, this, SLOT(runInferior()));
emit startSuccessful();
startSuccessful();
}
void ScriptEngine::continueInferior()
@@ -419,7 +421,7 @@ void ScriptEngine::selectThread(int index)
void ScriptEngine::attemptBreakpointSynchronization()
{
BreakHandler *handler = manager()->breakHandler();
BreakHandler *handler = breakHandler();
bool updateNeeded = false;
for (int index = 0; index != handler->size(); ++index) {
BreakpointData *data = handler->at(index);
@@ -602,8 +604,8 @@ bool ScriptEngine::checkForBreakCondition(bool byFunction)
if (byFunction && functionName.isEmpty())
return false;
BreakpointData *data = byFunction ?
findBreakPointByFunction(manager()->breakHandler(), functionName) :
findBreakPointByFileName(manager()->breakHandler(), lineNumber, fileName);
findBreakPointByFunction(breakHandler(), functionName) :
findBreakPointByFileName(breakHandler(), lineNumber, fileName);
if (!data)
return false;
@@ -625,7 +627,7 @@ bool ScriptEngine::checkForBreakCondition(bool byFunction)
StackFrame frame;
frame.file = fileName;
frame.line = lineNumber;
manager()->gotoLocation(frame, true);
gotoLocation(frame, true);
updateLocals();
return true;
}
@@ -633,7 +635,7 @@ bool ScriptEngine::checkForBreakCondition(bool byFunction)
void ScriptEngine::updateLocals()
{
QScriptContext *context = m_scriptEngine->currentContext();
manager()->watchHandler()->beginCycle();
watchHandler()->beginCycle();
//SDEBUG("UPDATE LOCALS");
//
@@ -655,7 +657,7 @@ void ScriptEngine::updateLocals()
//frame.address = ...;
stackFrames.append(frame);
}
manager()->stackHandler()->setFrames(stackFrames);
stackHandler()->setFrames(stackFrames);
//
// Build locals, deactivate agent meanwhile.
@@ -666,9 +668,9 @@ void ScriptEngine::updateLocals()
data.iname = "local";
data.name = QString::fromLatin1(data.iname);
data.scriptValue = context->activationObject();
manager()->watchHandler()->beginCycle();
watchHandler()->beginCycle();
updateSubItem(data);
manager()->watchHandler()->endCycle();
watchHandler()->endCycle();
// FIXME: Use an extra thread. This here is evil
m_stopped = true;
showStatusMessage(tr("Stopped."), 5000);
@@ -772,7 +774,7 @@ void ScriptEngine::updateSubItem(const WatchData &data0)
data1.exp = it.name().toLatin1();
data1.name = it.name();
data1.scriptValue = it.value();
if (manager()->watchHandler()->isExpandedIName(data1.iname)) {
if (watchHandler()->isExpandedIName(data1.iname)) {
data1.setChildrenNeeded();
} else {
data1.setChildrenUnneeded();
@@ -789,14 +791,14 @@ void ScriptEngine::updateSubItem(const WatchData &data0)
}
SDEBUG(msgDebugInsert(data, children));
manager()->watchHandler()->insertData(data);
watchHandler()->insertData(data);
if (!children.isEmpty())
manager()->watchHandler()->insertBulkData(children);
watchHandler()->insertBulkData(children);
}
IDebuggerEngine *createScriptEngine(DebuggerManager *manager)
DebuggerEngine *createScriptEngine(const DebuggerStartParameters &sp)
{
return new ScriptEngine(manager);
return new ScriptEngine(sp);
}
} // namespace Internal
+4 -4
View File
@@ -30,7 +30,7 @@
#ifndef DEBUGGER_SCRIPTENGINE_H
#define DEBUGGER_SCRIPTENGINE_H
#include "idebuggerengine.h"
#include "debuggerengine.h"
#include <QtCore/QSharedPointer>
#include <QtCore/QScopedPointer>
@@ -52,16 +52,16 @@ class WatchData;
* processEvents() triggered by QScriptEngine::setProcessEventsInterval().
* Stopping is emulated by manually calling processEvents() from the debugger engine. */
class ScriptEngine : public IDebuggerEngine
class ScriptEngine : public DebuggerEngine
{
Q_OBJECT
public:
ScriptEngine(DebuggerManager *manager);
ScriptEngine(const DebuggerStartParameters &startParameters);
~ScriptEngine();
private:
// IDebuggerEngine implementation
// DebuggerEngine implementation
void executeStep();
void executeStepOut();
void executeNext();
+5 -7
View File
@@ -31,8 +31,7 @@
#include "debuggeractions.h"
#include "debuggerconstants.h"
#include "debuggerrunner.h"
#include "idebuggerengine.h"
#include "debuggerengine.h"
#include <utils/qtcassert.h>
#include <utils/savedaction.h>
@@ -112,9 +111,8 @@ QDebug operator<<(QDebug d, const SnapshotData &f)
//
////////////////////////////////////////////////////////////////////////
SnapshotHandler::SnapshotHandler(DebuggerRunControl *runControl, QObject *parent)
: QAbstractTableModel(parent),
m_runControl(runControl),
SnapshotHandler::SnapshotHandler(DebuggerEngine *engine)
: m_engine(engine),
m_positionIcon(QIcon(":/debugger/images/location_16.png")),
m_emptyIcon(QIcon(":/debugger/images/debugger_empty_14.png"))
{
@@ -211,11 +209,11 @@ bool SnapshotHandler::setData
(const QModelIndex &index, const QVariant &value, int role)
{
if (role == RequestMakeSnapshotRole) {
m_runControl->engine()->makeSnapshot();
m_engine->makeSnapshot();
return true;
}
if (role == RequestActivateSnapshotRole) {
m_runControl->engine()->activateSnapshot(value.toInt());
m_engine->activateSnapshot(value.toInt());
return true;
}
if (role == RequestRemoveSnapshotRole) {
+6 -7
View File
@@ -36,11 +36,10 @@
#include <QtCore/QDateTime>
namespace Debugger {
class DebuggerRunControl;
namespace Internal {
class DebuggerEngine;
////////////////////////////////////////////////////////////////////////
//
// SnapshotData
@@ -64,8 +63,8 @@ public:
void setLocation(const QString &location) { m_location = location; }
QString location() const { return m_location; }
void setFrames(const QList<StackFrame> &frames) { m_frames = frames; }
QList<StackFrame> frames() const { return m_frames; }
void setFrames(const StackFrames &frames) { m_frames = frames; }
StackFrames frames() const { return m_frames; }
QString function() const; // Topmost entry.
@@ -90,7 +89,7 @@ class SnapshotHandler : public QAbstractTableModel
Q_OBJECT
public:
SnapshotHandler(DebuggerRunControl *runControl, QObject *parent = 0);
explicit SnapshotHandler(DebuggerEngine *engine);
~SnapshotHandler();
void setFrames(const Snapshots &snapshots, bool canExpand = false);
@@ -114,7 +113,7 @@ private:
Qt::ItemFlags flags(const QModelIndex &index) const;
Q_SLOT void resetModel() { reset(); }
DebuggerRunControl *m_runControl;
DebuggerEngine *m_engine;
int m_currentIndex;
Snapshots m_snapshots;
const QVariant m_positionIcon;
+146
View File
@@ -0,0 +1,146 @@
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (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 http://qt.nokia.com/contact.
**
**************************************************************************/
#include "sourcefileshandler.h"
#include "debuggerconstants.h"
#include "debuggerengine.h"
#include <QtCore/QDebug>
#include <QtCore/QFileInfo>
#include <QtGui/QSortFilterProxyModel>
namespace Debugger {
namespace Internal {
SourceFilesHandler::SourceFilesHandler(DebuggerEngine *engine)
: m_engine(engine)
{
QSortFilterProxyModel *proxy = new QSortFilterProxyModel(this);
proxy->setSourceModel(this);
m_proxyModel = proxy;
}
void SourceFilesHandler::clearModel()
{
if (m_shortNames.isEmpty())
return;
m_shortNames.clear();
m_fullNames.clear();
reset();
}
QVariant SourceFilesHandler::headerData(int section,
Qt::Orientation orientation, int role) const
{
if (orientation == Qt::Horizontal && role == Qt::DisplayRole) {
static QString headers[] = {
tr("Internal name") + " ",
tr("Full name") + " ",
};
return headers[section];
}
return QVariant();
}
Qt::ItemFlags SourceFilesHandler::flags(const QModelIndex &index) const
{
if (index.row() >= m_fullNames.size())
return 0;
QFileInfo fi(m_fullNames.at(index.row()));
return fi.isReadable() ? QAbstractItemModel::flags(index) : Qt::ItemFlags(0);
}
QVariant SourceFilesHandler::data(const QModelIndex &index, int role) const
{
switch (role) {
case EngineActionsEnabledRole:
return m_engine->debuggerActionsEnabled();
}
int row = index.row();
if (row < 0 || row >= m_shortNames.size())
return QVariant();
switch (index.column()) {
case 0:
if (role == Qt::DisplayRole)
return m_shortNames.at(row);
// FIXME: add icons
//if (role == Qt::DecorationRole)
// return module.symbolsRead ? icon2 : icon;
break;
case 1:
if (role == Qt::DisplayRole)
return m_fullNames.at(row);
//if (role == Qt::DecorationRole)
// return module.symbolsRead ? icon2 : icon;
break;
}
return QVariant();
}
bool SourceFilesHandler::setData
(const QModelIndex &index, const QVariant &value, int role)
{
Q_UNUSED(index);
switch (role) {
case RequestReloadSourceFilesRole:
m_engine->reloadSourceFiles();
return true;
case RequestOpenFileRole:
m_engine->openFile(value.toString());
return true;
}
return false;
}
void SourceFilesHandler::setSourceFiles(const QMap<QString, QString> &sourceFiles)
{
m_shortNames.clear();
m_fullNames.clear();
QMap<QString, QString>::ConstIterator it = sourceFiles.begin();
QMap<QString, QString>::ConstIterator et = sourceFiles.end();
for (; it != et; ++it) {
m_shortNames.append(it.key());
m_fullNames.append(it.value());
}
reset();
}
void SourceFilesHandler::removeAll()
{
setSourceFiles(QMap<QString, QString>());
//header()->setResizeMode(0, QHeaderView::ResizeToContents);
}
} // namespace Internal
} // namespace Debugger
+80
View File
@@ -0,0 +1,80 @@
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (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 http://qt.nokia.com/contact.
**
**************************************************************************/
#ifndef DEBUGGER_SOURCEFILESHANDLER_H
#define DEBUGGER_SOURCEFILESHANDLER_H
#include <QtCore/QAbstractItemModel>
#include <QtCore/QMap>
#include <QtCore/QStringList>
namespace Debugger {
namespace Internal {
class DebuggerEngine;
class SourceFilesHandler : public QAbstractItemModel
{
Q_OBJECT
public:
explicit SourceFilesHandler(DebuggerEngine *engine);
int columnCount(const QModelIndex &parent) const
{ return parent.isValid() ? 0 : 2; }
int rowCount(const QModelIndex &parent) const
{ return parent.isValid() ? 0 : m_shortNames.size(); }
QModelIndex parent(const QModelIndex &) const { return QModelIndex(); }
QModelIndex index(int row, int column, const QModelIndex &) const
{ return createIndex(row, column); }
QVariant headerData(int section, Qt::Orientation orientation, int role) const;
QVariant data(const QModelIndex &index, int role) const;
bool setData(const QModelIndex &index, const QVariant &value, int role);
Qt::ItemFlags flags(const QModelIndex &index) const;
void clearModel();
void update() { reset(); }
void setSourceFiles(const QMap<QString, QString> &sourceFiles);
void removeAll();
QAbstractItemModel *model() { return m_proxyModel; }
private:
DebuggerEngine *m_engine;
QStringList m_shortNames;
QStringList m_fullNames;
QAbstractItemModel *m_proxyModel;
};
} // namespace Internal
} // namespace Debugger
#endif // DEBUGGER_SOURCEFILESHANDLER_H
+21 -136
View File
@@ -28,132 +28,22 @@
**************************************************************************/
#include "sourcefileswindow.h"
#include "debuggeractions.h"
#include "debuggermanager.h"
#include "debuggerconstants.h"
#include <utils/qtcassert.h>
#include <utils/savedaction.h>
#include <QtCore/QDebug>
#include <QtCore/QFileInfo>
#include <utils/savedaction.h>
#include <QtGui/QAction>
#include <QtGui/QComboBox>
#include <QtGui/QHeaderView>
#include <QtGui/QMenu>
#include <QtGui/QResizeEvent>
#include <QtGui/QSortFilterProxyModel>
#include <QtGui/QTreeView>
#include <QtGui/QVBoxLayout>
using Debugger::Internal::SourceFilesWindow;
using Debugger::Internal::SourceFilesModel;
//////////////////////////////////////////////////////////////////
//
// SourceFilesModel
//
//////////////////////////////////////////////////////////////////
class Debugger::Internal::SourceFilesModel : public QAbstractItemModel
{
Q_OBJECT
public:
SourceFilesModel(QObject *parent = 0) : QAbstractItemModel(parent) {}
// QAbstractItemModel
int columnCount(const QModelIndex &parent) const
{ return parent.isValid() ? 0 : 2; }
int rowCount(const QModelIndex &parent) const
{ return parent.isValid() ? 0 : m_shortNames.size(); }
QModelIndex parent(const QModelIndex &) const { return QModelIndex(); }
QModelIndex index(int row, int column, const QModelIndex &) const
{ return createIndex(row, column); }
QVariant headerData(int section, Qt::Orientation orientation, int role) const;
QVariant data(const QModelIndex &index, int role) const;
bool setData(const QModelIndex &index, const QVariant &value, int role);
Qt::ItemFlags flags(const QModelIndex &index) const;
void clearModel();
void update() { reset(); }
void setSourceFiles(const QMap<QString, QString> &sourceFiles);
public:
QStringList m_shortNames;
QStringList m_fullNames;
};
void SourceFilesModel::clearModel()
{
if (m_shortNames.isEmpty())
return;
m_shortNames.clear();
m_fullNames.clear();
reset();
}
QVariant SourceFilesModel::headerData(int section,
Qt::Orientation orientation, int role) const
{
if (orientation == Qt::Horizontal && role == Qt::DisplayRole) {
static QString headers[] = {
tr("Internal name") + " ",
tr("Full name") + " ",
};
return headers[section];
}
return QVariant();
}
Qt::ItemFlags SourceFilesModel::flags(const QModelIndex &index) const
{
if (index.row() >= m_fullNames.size())
return 0;
QFileInfo fi(m_fullNames.at(index.row()));
return fi.isReadable() ? QAbstractItemModel::flags(index) : Qt::ItemFlags(0);
}
QVariant SourceFilesModel::data(const QModelIndex &index, int role) const
{
int row = index.row();
if (row < 0 || row >= m_shortNames.size())
return QVariant();
switch (index.column()) {
case 0:
if (role == Qt::DisplayRole)
return m_shortNames.at(row);
// FIXME: add icons
//if (role == Qt::DecorationRole)
// return module.symbolsRead ? icon2 : icon;
break;
case 1:
if (role == Qt::DisplayRole)
return m_fullNames.at(row);
//if (role == Qt::DecorationRole)
// return module.symbolsRead ? icon2 : icon;
break;
}
return QVariant();
}
bool SourceFilesModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
return QAbstractItemModel::setData(index, value, role);
}
void SourceFilesModel::setSourceFiles(const QMap<QString, QString> &sourceFiles)
{
m_shortNames.clear();
m_fullNames.clear();
QMap<QString, QString>::ConstIterator it = sourceFiles.begin();
QMap<QString, QString>::ConstIterator et = sourceFiles.end();
for (; it != et; ++it) {
m_shortNames.append(it.key());
m_fullNames.append(it.value());
}
reset();
}
//////////////////////////////////////////////////////////////////
//
@@ -161,16 +51,14 @@ void SourceFilesModel::setSourceFiles(const QMap<QString, QString> &sourceFiles)
//
//////////////////////////////////////////////////////////////////
namespace Debugger {
namespace Internal {
SourceFilesWindow::SourceFilesWindow(QWidget *parent)
: QTreeView(parent)
{
m_model = new SourceFilesModel(this);
QAction *act = theDebuggerAction(UseAlternatingRowColors);
QSortFilterProxyModel *proxyModel = new QSortFilterProxyModel(this);
proxyModel->setSourceModel(m_model);
setModel(proxyModel);
setAttribute(Qt::WA_MacShowFocusRect, false);
setFrameStyle(QFrame::NoFrame);
setWindowTitle(tr("Source Files"));
@@ -188,20 +76,20 @@ SourceFilesWindow::SourceFilesWindow(QWidget *parent)
void SourceFilesWindow::sourceFileActivated(const QModelIndex &index)
{
qDebug() << "ACTIVATED: " << index.row() << index.column()
<< model()->data(index);
emit fileOpenRequested(model()->data(index).toString());
setModelData(RequestOpenFileRole, index.data());
}
void SourceFilesWindow::contextMenuEvent(QContextMenuEvent *ev)
{
QModelIndex index = indexAt(ev->pos());
index = index.sibling(index.row(), 0);
QString name = model()->data(index).toString();
QString name = index.data().toString();
bool engineActionsEnabled = index.data(EngineActionsEnabledRole).toBool();
QMenu menu;
QAction *act1 = new QAction(tr("Reload Data"), &menu);
act1->setEnabled(Debugger::DebuggerManager::instance()->debuggerActionsEnabled());
act1->setEnabled(engineActionsEnabled);
//act1->setCheckable(true);
QAction *act2 = 0;
if (name.isEmpty()) {
@@ -220,21 +108,18 @@ void SourceFilesWindow::contextMenuEvent(QContextMenuEvent *ev)
QAction *act = menu.exec(ev->globalPos());
if (act == act1)
emit reloadSourceFilesRequested();
setModelData(RequestReloadSourceFilesRole);
else if (act == act2)
emit fileOpenRequested(name);
setModelData(RequestOpenFileRole, name);
}
void SourceFilesWindow::setSourceFiles(const QMap<QString, QString> &sourceFiles)
void SourceFilesWindow::setModelData
(int role, const QVariant &value, const QModelIndex &index)
{
m_model->setSourceFiles(sourceFiles);
header()->setResizeMode(0, QHeaderView::ResizeToContents);
QTC_ASSERT(model(), return);
model()->setData(index, value, role);
}
void SourceFilesWindow::removeAll()
{
m_model->setSourceFiles(QMap<QString, QString>());
header()->setResizeMode(0, QHeaderView::ResizeToContents);
}
} // namespace Internal
} // namespace Debugger
#include "sourcefileswindow.moc"
+4 -10
View File
@@ -30,13 +30,13 @@
#ifndef DEBUGGER_SOURCEFILEWINDOW_H
#define DEBUGGER_SOURCEFILEWINDOW_H
#include <QtCore/QMap>
#include <QtGui/QTreeView>
namespace Debugger {
namespace Internal {
class SourceFilesModel;
class SourceFilesWindow : public QTreeView
{
Q_OBJECT
@@ -44,20 +44,14 @@ class SourceFilesWindow : public QTreeView
public:
SourceFilesWindow(QWidget *parent = 0);
void setSourceFiles(const QMap<QString, QString> &sourceFiles);
void removeAll();
signals:
void reloadSourceFilesRequested();
void fileOpenRequested(QString file);
private slots:
void sourceFileActivated(const QModelIndex &index);
void setAlternatingRowColorsHelper(bool on) { setAlternatingRowColors(on); }
private:
void contextMenuEvent(QContextMenuEvent *ev);
SourceFilesModel *m_model;
void setModelData(int role, const QVariant &value = QVariant(),
const QModelIndex &index = QModelIndex());
};
} // namespace Internal
+4 -2
View File
@@ -30,9 +30,9 @@
#ifndef DEBUGGER_STACKFRAME_H
#define DEBUGGER_STACKFRAME_H
#include <QtCore/QString>
#include <QtCore/QList>
#include <QtCore/QMetaType>
#include <QtCore/QString>
QT_BEGIN_NAMESPACE
class QDebug;
@@ -41,14 +41,16 @@ QT_END_NAMESPACE
namespace Debugger {
namespace Internal {
struct StackFrame
class StackFrame
{
public:
StackFrame();
void clear();
bool isUsable() const;
QString toToolTip() const;
QString toString() const;
public:
int level;
QString function;
QString file; // We try to put an absolute file name in there.
+60 -17
View File
@@ -30,6 +30,8 @@
#include "stackhandler.h"
#include "debuggeractions.h"
#include "debuggeragents.h"
#include "debuggerengine.h"
#include <utils/qtcassert.h>
#include <utils/savedaction.h>
@@ -37,29 +39,34 @@
#include <QtCore/QAbstractTableModel>
#include <QtCore/QDebug>
#include <QtCore/QFileInfo>
#include <QtCore/QDir>
namespace Debugger {
namespace Internal {
////////////////////////////////////////////////////////////////////////
//
// StackHandler
//
////////////////////////////////////////////////////////////////////////
StackHandler::StackHandler(QObject *parent)
: QAbstractTableModel(parent),
m_positionIcon(QIcon(":/debugger/images/location_16.png")),
StackHandler::StackHandler(DebuggerEngine *engine)
: m_positionIcon(QIcon(":/debugger/images/location_16.png")),
m_emptyIcon(QIcon(":/debugger/images/debugger_empty_14.png"))
{
m_engine = engine;
m_disassemblerViewAgent = new DisassemblerViewAgent(engine);
m_currentIndex = 0;
m_canExpand = false;
connect(theDebuggerAction(OperateByInstruction), SIGNAL(triggered()),
this, SLOT(resetModel()));
}
StackHandler::~StackHandler()
{
//delete m_disassemblerViewAgent;
}
int StackHandler::rowCount(const QModelIndex &parent) const
{
// Since the stack is not a tree, row count is 0 for any valid parent
@@ -73,6 +80,17 @@ int StackHandler::columnCount(const QModelIndex &parent) const
QVariant StackHandler::data(const QModelIndex &index, int role) const
{
switch (role) {
case EngineStateRole:
return m_engine->state();
case EngineCapabilitiesRole:
return m_engine->debuggerCapabilities();
case EngineActionsEnabledRole:
return m_engine->debuggerActionsEnabled();
}
if (!index.isValid() || index.row() >= m_stackFrames.size() + m_canExpand)
return QVariant();
@@ -104,25 +122,51 @@ QVariant StackHandler::data(const QModelIndex &index, int role) const
return QVariant();
}
if (role == Qt::ToolTipRole) {
//: Tooltip for variable
return frame.toToolTip();
}
if (role == Qt::DecorationRole && index.column() == 0) {
// Return icon that indicates whether this is the active stack frame
return (index.row() == m_currentIndex) ? m_positionIcon : m_emptyIcon;
}
if (role == Qt::UserRole)
return QVariant::fromValue(frame);
if (role == StackFrameAddressRole)
return frame.address;
//: Tooltip for variable
if (role == Qt::ToolTipRole)
return frame.toToolTip();
return QVariant();
}
QVariant StackHandler::headerData(int section, Qt::Orientation orientation, int role) const
bool StackHandler::setData(const QModelIndex &index, const QVariant &value, int role)
{
if (orientation == Qt::Horizontal && role == Qt::DisplayRole) {
switch (role) {
case RequestActivateFrameRole:
m_engine->activateFrame(value.toInt());
return true;
case RequestShowMemoryRole:
(void) new MemoryViewAgent(m_engine, value.toString());
return true;
case RequestShowDisassemblerRole: {
const StackFrame &frame = m_stackFrames.at(value.toInt());
m_disassemblerViewAgent->setFrame(frame);
return true;
}
case RequestReloadFullStackRole:
m_engine->reloadFullStack();
return true;
default:
return QAbstractTableModel::setData(index, value, role);
}
}
QVariant StackHandler::headerData(int section, Qt::Orientation orient, int role) const
{
if (orient == Qt::Horizontal && role == Qt::DisplayRole) {
switch (section) {
case 0: return tr("Level");
case 1: return tr("Function");
@@ -176,7 +220,7 @@ void StackHandler::removeAll()
reset();
}
void StackHandler::setFrames(const QList<StackFrame> &frames, bool canExpand)
void StackHandler::setFrames(const StackFrames &frames, bool canExpand)
{
m_canExpand = canExpand;
m_stackFrames = frames;
@@ -185,7 +229,7 @@ void StackHandler::setFrames(const QList<StackFrame> &frames, bool canExpand)
reset();
}
QList<StackFrame> StackHandler::frames() const
StackFrames StackHandler::frames() const
{
return m_stackFrames;
}
@@ -198,6 +242,5 @@ bool StackHandler::isDebuggingDebuggingHelpers() const
return false;
}
} // namespace Internal
} // namespace Debugger
+14 -7
View File
@@ -37,9 +37,13 @@
#include <QtGui/QIcon>
namespace Debugger {
namespace Internal {
class DebuggerEngine;
class DisassemblerViewAgent;
////////////////////////////////////////////////////////////////////////
//
// StackModel
@@ -54,6 +58,7 @@ struct StackCookie
bool gotoLocation;
};
////////////////////////////////////////////////////////////////////////
//
// StackModel
@@ -66,10 +71,11 @@ class StackHandler : public QAbstractTableModel
Q_OBJECT
public:
StackHandler(QObject *parent = 0);
explicit StackHandler(DebuggerEngine *engine);
~StackHandler();
void setFrames(const QList<StackFrame> &frames, bool canExpand = false);
QList<StackFrame> frames() const;
void setFrames(const StackFrames &frames, bool canExpand = false);
StackFrames frames() const;
void setCurrentIndex(int index);
int currentIndex() const { return m_currentIndex; }
StackFrame currentFrame() const;
@@ -78,7 +84,7 @@ public:
// Called from StackHandler after a new stack list has been received
void removeAll();
QAbstractItemModel *stackModel() { return this; }
QAbstractItemModel *model() { return this; }
bool isDebuggingDebuggingHelpers() const;
private:
@@ -86,19 +92,20 @@ private:
int rowCount(const QModelIndex &parent) const;
int columnCount(const QModelIndex &parent) const;
QVariant data(const QModelIndex &index, int role) const;
bool setData(const QModelIndex &index, const QVariant &, int role);
QVariant headerData(int section, Qt::Orientation orientation, int role) const;
Qt::ItemFlags flags(const QModelIndex &index) const;
Q_SLOT void resetModel() { reset(); }
QList<StackFrame> m_stackFrames;
DebuggerEngine *m_engine;
DisassemblerViewAgent *m_disassemblerViewAgent;
StackFrames m_stackFrames;
int m_currentIndex;
const QVariant m_positionIcon;
const QVariant m_emptyIcon;
bool m_canExpand;
};
} // namespace Internal
} // namespace Debugger
+34 -14
View File
@@ -31,8 +31,7 @@
#include "stackframe.h"
#include "debuggeractions.h"
#include "debuggeragents.h"
#include "debuggermanager.h"
#include "debuggerconstants.h"
#include <utils/qtcassert.h>
#include <utils/savedaction.h>
@@ -53,12 +52,11 @@
namespace Debugger {
namespace Internal {
StackWindow::StackWindow(DebuggerManager *manager, QWidget *parent)
: QTreeView(parent), m_manager(manager), m_alwaysResizeColumnsToContents(false)
StackWindow::StackWindow(QWidget *parent)
: QTreeView(parent), m_alwaysResizeColumnsToContents(false)
{
setAttribute(Qt::WA_MacShowFocusRect, false);
setFrameStyle(QFrame::NoFrame);
m_disassemblerAgent = new DisassemblerViewAgent(manager);
QAction *act = theDebuggerAction(UseAlternatingRowColors);
setWindowTitle(tr("Stack"));
@@ -68,6 +66,8 @@ StackWindow::StackWindow(DebuggerManager *manager, QWidget *parent)
setIconSize(QSize(10, 10));
header()->setDefaultAlignment(Qt::AlignLeft);
header()->resizeSection(0, 60);
header()->resizeSection(3, 60);
connect(this, SIGNAL(activated(QModelIndex)),
this, SLOT(rowActivated(QModelIndex)));
@@ -75,11 +75,14 @@ StackWindow::StackWindow(DebuggerManager *manager, QWidget *parent)
this, SLOT(setAlternatingRowColorsHelper(bool)));
connect(theDebuggerAction(UseAddressInStackView), SIGNAL(toggled(bool)),
this, SLOT(showAddressColumn(bool)));
connect(theDebuggerAction(ExpandStack), SIGNAL(triggered()),
this, SLOT(reloadFullStack()));
connect(theDebuggerAction(MaximalStackDepth), SIGNAL(triggered()),
this, SLOT(reloadFullStack()));
}
StackWindow::~StackWindow()
{
delete m_disassemblerAgent;
}
void StackWindow::showAddressColumn(bool on)
@@ -89,18 +92,16 @@ void StackWindow::showAddressColumn(bool on)
void StackWindow::rowActivated(const QModelIndex &index)
{
m_manager->activateFrame(index.row());
setModelData(RequestActivateFrameRole, index.row());
}
void StackWindow::contextMenuEvent(QContextMenuEvent *ev)
{
QModelIndex idx = indexAt(ev->pos());
StackFrame frame = model()->data(idx, Qt::UserRole).value<StackFrame>();
QString address = frame.address;
const QModelIndex index = indexAt(ev->pos());
const QString address = modelData(StackFrameAddressRole, index).toString();
const unsigned engineCapabilities = modelData(EngineCapabilitiesRole).toUInt();
QMenu menu;
const unsigned engineCapabilities = m_manager->debuggerCapabilities();
menu.addAction(theDebuggerAction(ExpandStack));
QAction *actCopyContents = menu.addAction(tr("Copy Contents to Clipboard"));
@@ -153,9 +154,9 @@ void StackWindow::contextMenuEvent(QContextMenuEvent *ev)
else if (act == actAlwaysAdjust)
setAlwaysResizeColumnsToContents(!m_alwaysResizeColumnsToContents);
else if (act == actShowMemory)
(void) new MemoryViewAgent(m_manager, address);
setModelData(RequestShowMemoryRole, address);
else if (act == actShowDisassembler)
m_disassemblerAgent->setFrame(frame);
setModelData(RequestShowDisassemblerRole, index.row());
}
void StackWindow::copyContentsToClipboard()
@@ -178,6 +179,11 @@ void StackWindow::copyContentsToClipboard()
clipboard->setText(str, QClipboard::Clipboard);
}
void StackWindow::reloadFullStack()
{
setModelData(RequestReloadFullStackRole);
}
void StackWindow::resizeColumnsToContents()
{
for (int i = model()->columnCount(); --i >= 0; )
@@ -193,5 +199,19 @@ void StackWindow::setAlwaysResizeColumnsToContents(bool on)
header()->setResizeMode(i, mode);
}
void StackWindow::setModelData
(int role, const QVariant &value, const QModelIndex &index)
{
QTC_ASSERT(model(), return);
model()->setData(index, value, role);
}
QVariant StackWindow::modelData(int role, const QModelIndex &index)
{
QTC_ASSERT(model(), return QVariant());
return model()->data(index, role);
}
} // namespace Internal
} // namespace Debugger
+6 -6
View File
@@ -33,17 +33,14 @@
#include <QtGui/QTreeView>
namespace Debugger {
class DebuggerManager;
namespace Internal {
class DisassemblerViewAgent;
class StackWindow : public QTreeView
{
Q_OBJECT
public:
StackWindow(DebuggerManager *manager, QWidget *parent = 0);
explicit StackWindow(QWidget *parent = 0);
~StackWindow();
public slots:
@@ -54,13 +51,16 @@ private slots:
void rowActivated(const QModelIndex &index);
void setAlternatingRowColorsHelper(bool on) { setAlternatingRowColors(on); }
void showAddressColumn(bool on);
void reloadFullStack();
private:
void contextMenuEvent(QContextMenuEvent *ev);
void copyContentsToClipboard();
DebuggerManager *m_manager;
DisassemblerViewAgent *m_disassemblerAgent;
void setModelData(int role, const QVariant &value = QVariant(),
const QModelIndex &index = QModelIndex());
QVariant modelData(int role, const QModelIndex &index = QModelIndex());
bool m_alwaysResizeColumnsToContents;
};
+11 -15
View File
@@ -29,19 +29,17 @@
#include "tcfengine.h"
#include "debuggerstringutils.h"
#include "debuggerdialogs.h"
#include "breakhandler.h"
#include "debuggerconstants.h"
#include "debuggermanager.h"
#include "debuggerdialogs.h"
#include "debuggerstringutils.h"
#include "json.h"
#include "breakhandler.h"
#include "moduleshandler.h"
#include "registerhandler.h"
#include "stackhandler.h"
#include "watchhandler.h"
#include "watchutils.h"
#include "moduleshandler.h"
#include "json.h"
#include <utils/qtcassert.h>
#include <QtCore/QDateTime>
@@ -106,8 +104,8 @@ QString TcfEngine::TcfCommand::toString() const
//
///////////////////////////////////////////////////////////////////////
TcfEngine::TcfEngine(DebuggerManager *manager)
: IDebuggerEngine(manager)
TcfEngine::TcfEngine(const DebuggerStartParameters &startParameters)
: DebuggerEngine(startParameters)
{
m_congestion = 0;
m_inAir = 0;
@@ -171,7 +169,7 @@ void TcfEngine::socketError(QAbstractSocket::SocketError)
QString msg = tr("%1.").arg(m_socket->errorString());
//QMessageBox::critical(q->mainWindow(), tr("Error"), msg);
showStatusMessage(msg);
manager()->notifyInferiorExited();
exitDebugger();
}
void TcfEngine::executeDebuggerCommand(const QString &command)
@@ -200,15 +198,13 @@ void TcfEngine::shutdown()
void TcfEngine::exitDebugger()
{
SDEBUG("TcfEngine::exitDebugger()");
manager()->notifyInferiorExited();
}
void TcfEngine::startDebugger()
{
QTC_ASSERT(runControl(), return);
setState(InferiorRunningRequested);
showStatusMessage(tr("Running requested..."), 5000);
const DebuggerStartParameters &sp = runControl()->sp();
const DebuggerStartParameters &sp = startParameters();
const int pos = sp.remoteChannel.indexOf(QLatin1Char(':'));
const QString host = sp.remoteChannel.left(pos);
const quint16 port = sp.remoteChannel.mid(pos + 1).toInt();
@@ -558,9 +554,9 @@ void TcfEngine::updateSubItem(const WatchData &data0)
QTC_ASSERT(false, return);
}
IDebuggerEngine *createTcfEngine(DebuggerManager *manager)
DebuggerEngine *createTcfEngine(const DebuggerStartParameters &sp)
{
return new TcfEngine(manager);
return new TcfEngine(sp);
}
} // namespace Internal
+4 -5
View File
@@ -47,8 +47,7 @@ QT_BEGIN_NAMESPACE
class QTcpSocket;
QT_END_NAMESPACE
#include "idebuggerengine.h"
#include "debuggermanager.h"
#include "debuggerengine.h"
#include "json.h"
namespace Debugger {
@@ -57,16 +56,16 @@ namespace Internal {
class ScriptAgent;
class WatchData;
class TcfEngine : public IDebuggerEngine
class TcfEngine : public DebuggerEngine
{
Q_OBJECT
public:
explicit TcfEngine(DebuggerManager *parent);
explicit TcfEngine(const DebuggerStartParameters &startParameters);
~TcfEngine();
private:
// IDebuggerEngine implementation
// DebuggerEngine implementation
void executeStep();
void executeStepOut();
void executeNext();
+31 -11
View File
@@ -29,6 +29,10 @@
#include "threadshandler.h"
#include "debuggerconstants.h"
#include "debuggerengine.h"
namespace Debugger {
namespace Internal {
@@ -60,8 +64,8 @@ void ThreadData::notifyRunning()
//
///////////////////////////////////////////////////////////////////////
ThreadsHandler::ThreadsHandler(QObject *parent) :
QAbstractTableModel(parent),
ThreadsHandler::ThreadsHandler(DebuggerEngine *engine)
: m_engine(engine),
m_currentIndex(0),
m_positionIcon(QLatin1String(":/debugger/images/location_16.png")),
m_emptyIcon(QLatin1String(":/debugger/images/debugger_empty_14.png"))
@@ -97,9 +101,12 @@ QVariant ThreadsHandler::data(const QModelIndex &index, int role) const
case ThreadData::FileColumn:
return thread.fileName;
case ThreadData::LineColumn:
return thread.lineNumber >= 0 ? QString::number(thread.lineNumber) : QString();
return thread.lineNumber >= 0
? QString::number(thread.lineNumber) : QString();
case ThreadData::AddressColumn:
return thread.address > 0 ? QLatin1String("0x") + QString::number(thread.address, 16) : QString();
return thread.address > 0
? QLatin1String("0x") + QString::number(thread.address, 16)
: QString();
case ThreadData::CoreColumn:
return thread.core;
case ThreadData::StateColumn:
@@ -110,9 +117,11 @@ QVariant ThreadsHandler::data(const QModelIndex &index, int role) const
return tr("Thread: %1").arg(thread.id);
// Stopped
if (thread.fileName.isEmpty())
return tr("Thread: %1 at %2 (0x%3)").arg(thread.id).arg(thread.function).arg(thread.address, 0, 16);
return tr("Thread: %1 at %2 (0x%3)").arg(thread.id)
.arg(thread.function).arg(thread.address, 0, 16);
return tr("Thread: %1 at %2, %3:%4 (0x%5)").
arg(thread.id).arg(thread.function, thread.fileName).arg(thread.lineNumber).arg(thread.address, 0, 16);
arg(thread.id).arg(thread.function, thread.fileName)
.arg(thread.lineNumber).arg(thread.address, 0, 16);
} else if (role == Qt::DecorationRole && index.column() == 0) {
// Return icon that indicates whether this is the active stack frame
return (index.row() == m_currentIndex) ? m_positionIcon : m_emptyIcon;
@@ -121,7 +130,8 @@ QVariant ThreadsHandler::data(const QModelIndex &index, int role) const
return QVariant();
}
QVariant ThreadsHandler::headerData(int section, Qt::Orientation orientation, int role) const
QVariant ThreadsHandler::headerData
(int section, Qt::Orientation orientation, int role) const
{
if (orientation != Qt::Horizontal || role != Qt::DisplayRole)
return QVariant();
@@ -144,6 +154,16 @@ QVariant ThreadsHandler::headerData(int section, Qt::Orientation orientation, in
return QVariant();
}
bool ThreadsHandler::setData
(const QModelIndex &index, const QVariant &value, int role)
{
if (role == RequestSelectThreadRole) {
m_engine->selectThread(value.toInt());
return true;
}
return QAbstractTableModel::setData(index, value, role);
}
int ThreadsHandler::currentThreadId() const
{
if (m_currentIndex < 0 || m_currentIndex >= m_threads.size())
@@ -167,7 +187,7 @@ void ThreadsHandler::setCurrentThread(int index)
emit dataChanged(i, i);
}
void ThreadsHandler::setThreads(const QList<ThreadData> &threads)
void ThreadsHandler::setThreads(const Threads &threads)
{
m_threads = threads;
if (m_currentIndex >= m_threads.size())
@@ -175,7 +195,7 @@ void ThreadsHandler::setThreads(const QList<ThreadData> &threads)
reset();
}
QList<ThreadData> ThreadsHandler::threads() const
Threads ThreadsHandler::threads() const
{
return m_threads;
}
@@ -194,8 +214,8 @@ void ThreadsHandler::notifyRunning()
return;
if (m_threads.front().address == 0)
return;
const QList<ThreadData>::iterator end = m_threads.end();
for (QList<ThreadData>::iterator it = m_threads.begin(); it != end; ++it)
const Threads::iterator end = m_threads.end();
for (Threads::iterator it = m_threads.begin(); it != end; ++it)
it->notifyRunning();
emit dataChanged(index(0, 1),
index(m_threads.size() - 1, ThreadData::ColumnCount - 1));
+13 -6
View File
@@ -39,6 +39,8 @@
namespace Debugger {
namespace Internal {
class DebuggerEngine;
////////////////////////////////////////////////////////////////////////
//
// ThreadData
@@ -77,6 +79,8 @@ struct ThreadData
int lineNumber;
};
typedef QVector<ThreadData> Threads;
////////////////////////////////////////////////////////////////////////
//
@@ -90,15 +94,15 @@ class ThreadsHandler : public QAbstractTableModel
Q_OBJECT
public:
ThreadsHandler(QObject *parent = 0);
explicit ThreadsHandler(DebuggerEngine *engine);
int currentThreadId() const;
void setCurrentThread(int index);
void selectThread(int index);
void setThreads(const QList<ThreadData> &threads);
void setThreads(const Threads &threads);
void removeAll();
QList<ThreadData> threads() const;
QAbstractItemModel *threadsModel() { return this; }
Threads threads() const;
QAbstractItemModel *model() { return this; }
// Clear out all frame information
void notifyRunning();
@@ -107,10 +111,13 @@ private:
int rowCount(const QModelIndex &parent = QModelIndex()) const;
int columnCount(const QModelIndex &parent = QModelIndex()) const;
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
bool setData(const QModelIndex &index, const QVariant &value, int role);
QVariant headerData(int section, Qt::Orientation orientation,
int role = Qt::DisplayRole) const;
private:
QList<ThreadData> m_threads;
DebuggerEngine *m_engine;
Threads m_threads;
int m_currentIndex;
const QIcon m_positionIcon;
const QIcon m_emptyIcon;
+14 -3
View File
@@ -30,6 +30,7 @@
#include "threadswindow.h"
#include "debuggeractions.h"
#include "debuggerconstants.h"
#include <utils/savedaction.h>
@@ -38,7 +39,9 @@
#include <QtGui/QHeaderView>
#include <QtGui/QMenu>
using Debugger::Internal::ThreadsWindow;
namespace Debugger {
namespace Internal {
ThreadsWindow::ThreadsWindow(QWidget *parent)
: QTreeView(parent), m_alwaysResizeColumnsToContents(false)
@@ -62,7 +65,7 @@ ThreadsWindow::ThreadsWindow(QWidget *parent)
void ThreadsWindow::rowActivated(const QModelIndex &index)
{
emit threadSelected(index.row());
selectThread(index.row());
}
void ThreadsWindow::contextMenuEvent(QContextMenuEvent *ev)
@@ -79,7 +82,7 @@ void ThreadsWindow::contextMenuEvent(QContextMenuEvent *ev)
menu.addAction(theDebuggerAction(SettingsDialog));
QAction *act = menu.exec(ev->globalPos());
if(!act)
if (!act)
return;
if (act == adjustColumnAction) {
@@ -103,3 +106,11 @@ void ThreadsWindow::setAlwaysResizeColumnsToContents(bool on)
? QHeaderView::ResizeToContents : QHeaderView::Interactive;
header()->setResizeMode(0, mode);
}
void ThreadsWindow::selectThread(int index)
{
model()->setData(QModelIndex(), index, RequestSelectThreadRole);
}
} // namespace Internal
} // namespace Debugger
+1 -3
View File
@@ -42,12 +42,10 @@ class ThreadsWindow : public QTreeView
public:
ThreadsWindow(QWidget *parent = 0);
signals:
void threadSelected(int);
public slots:
void resizeColumnsToContents();
void setAlwaysResizeColumnsToContents(bool on);
void selectThread(int index);
private slots:
void rowActivated(const QModelIndex &index);
+11
View File
@@ -260,6 +260,17 @@ QString WatchData::shadowedName(const QString &name, int seen)
return shadowedNameFormat().arg(name, seen);
}
quint64 WatchData::coreAddress() const
{
if (!addr.isEmpty()) {
bool ok;
const quint64 address = addr.toULongLong(&ok, 16);
if (ok)
return address;
}
return quint64(0);
}
} // namespace Internal
} // namespace Debugger
+1
View File
@@ -101,6 +101,7 @@ public:
bool isValid() const { return !iname.isEmpty(); }
bool isEqual(const WatchData &other) const;
quint64 coreAddress() const;
static QString msgNotInScope();
static QString shadowedName(const QString &name, int seen);
+119 -45
View File
@@ -28,10 +28,14 @@
**************************************************************************/
#include "watchhandler.h"
#include "watchutils.h"
#include "breakhandler.h"
#include "breakpoint.h"
#include "debuggeractions.h"
#include "debuggermanager.h"
#include "idebuggerengine.h"
#include "debuggeragents.h"
#include "debuggerengine.h"
#include "debuggerplugin.h"
#include "watchutils.h"
#if USE_MODEL_TEST
#include "modeltest.h"
@@ -76,6 +80,8 @@ static const QString strNotInScope =
static int watcherCounter = 0;
static int generationCounter = 0;
static DebuggerPlugin *plugin() { return DebuggerPlugin::instance(); }
////////////////////////////////////////////////////////////////////
//
// WatchItem
@@ -178,6 +184,11 @@ void WatchModel::endCycle()
m_fetchTriggered.clear();
emit enableUpdates(true);
}
DebuggerEngine *WatchModel::engine() const
{
return m_handler->m_engine;
}
void WatchModel::dump()
{
@@ -375,9 +386,8 @@ QString WatchModel::niceType(const QString &typeIn) const
QString type = niceTypeHelper(typeIn);
if (!theDebuggerBoolSetting(ShowStdNamespace))
type = type.remove("std::");
IDebuggerEngine *engine = m_handler->m_manager->currentEngine();
if (engine && !theDebuggerBoolSetting(ShowQtNamespace))
type = type.remove(engine->qtNamespace());
if (!theDebuggerBoolSetting(ShowQtNamespace))
type = type.remove(engine()->qtNamespace());
return type;
}
@@ -459,7 +469,7 @@ void WatchModel::fetchMore(const QModelIndex &index)
if (item->children.isEmpty()) {
WatchData data = *item;
data.setChildrenNeeded();
m_handler->m_manager->updateWatchData(data);
engine()->updateWatchData(data);
}
}
@@ -583,6 +593,14 @@ static inline quint64 pointerValue(QString data)
QVariant WatchModel::data(const QModelIndex &idx, int role) const
{
switch (role) {
case EngineCapabilitiesRole:
return engine()->debuggerCapabilities();
case EngineActionsEnabledRole:
return engine()->debuggerActionsEnabled();
}
const WatchItem *item = watchItem(idx);
const WatchItem &data = *item;
@@ -623,16 +641,16 @@ QVariant WatchModel::data(const QModelIndex &idx, int role) const
break;
}
case ExpressionRole:
case LocalsExpressionRole:
return data.exp;
case INameRole:
case LocalsINameRole:
return data.iname;
case ExpandedRole:
case LocalsExpandedRole:
return m_handler->m_expandedINames.contains(data.iname);
case TypeFormatListRole:
case LocalsTypeFormatListRole:
if (!data.typeFormats.isEmpty())
return data.typeFormats.split(',');
if (isIntType(data.type))
@@ -647,28 +665,33 @@ QVariant WatchModel::data(const QModelIndex &idx, int role) const
<< tr("UCS4 string");
break;
case TypeFormatRole:
case LocalsTypeFormatRole:
return m_handler->m_typeFormats.value(data.type, -1);
case IndividualFormatRole:
case LocalsIndividualFormatRole:
return m_handler->m_individualFormats.value(data.addr, -1);
case AddressRole:
if (!data.addr.isEmpty()) {
bool ok;
const quint64 address = data.addr.toULongLong(&ok, 16);
if (ok)
return QVariant(address);
}
return QVariant(quint64(0));
case RawValueRole:
case LocalsRawValueRole:
return data.value;
case PointerValue:
case LocalsPointerValueRole:
if (isPointerType(data.type))
return pointerValue(data.value);
return QVariant(quint64(0));
case LocalsIsWatchpointAtAddressRole:
return engine()->breakHandler()
->watchPointAt(data.coreAddress());
case LocalsAddressRole:
return data.coreAddress();
case LocalsIsWatchpointAtPointerValueRole:
if (isPointerType(data.type))
return engine()->breakHandler()
->watchPointAt(pointerValue(data.addr));
return false;
default:
break;
}
@@ -677,8 +700,54 @@ QVariant WatchModel::data(const QModelIndex &idx, int role) const
bool WatchModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
switch (role) {
case RequestAssignValueRole: {
QString str = value.toString();
int i = str.indexOf('=');
if (i != -1)
engine()->assignValueInDebugger(str.left(i), str.mid(i + 1));
return true;
}
case RequestAssignTypeRole: {
QString str = value.toString();
int i = str.indexOf('=');
if (i != -1)
engine()->assignValueInDebugger(str.left(i), str.mid(i + 1));
return true;
}
case RequestToggleWatchRole: {
BreakHandler *handler = engine()->breakHandler();
const quint64 address = value.toULongLong();
const QByteArray addressBA =
QByteArray("0x") + QByteArray::number(address, 16);
const int index = handler->findWatchPointIndexByAddress(addressBA);
if (index == -1) {
BreakpointData *data = new BreakpointData;
data->type = BreakpointData::WatchpointType;
data->address = addressBA;
handler->appendBreakpoint(data);
} else {
handler->removeBreakpoint(index);
}
engine()->attemptBreakpointSynchronization();
return true;
}
case RequestShowMemoryRole: {
(void) new MemoryViewAgent(engine(), value.toULongLong());
return true;
}
case RequestClearCppCodeModelSnapshotRole: {
plugin()->clearCppCodeModelSnapshot();
return true;
}
}
WatchItem &data = *watchItem(index);
if (role == ExpandedRole) {
if (role == LocalsExpandedRole) {
if (value.toBool()) {
// Should already have been triggered by fetchMore()
//QTC_ASSERT(m_handler->m_expandedINames.contains(data.iname), /**/);
@@ -686,17 +755,17 @@ bool WatchModel::setData(const QModelIndex &index, const QVariant &value, int ro
} else {
m_handler->m_expandedINames.remove(data.iname);
}
} else if (role == TypeFormatRole) {
} else if (role == LocalsTypeFormatRole) {
m_handler->setFormat(data.type, value.toInt());
m_handler->m_manager->updateWatchData(data);
} else if (role == IndividualFormatRole) {
engine()->updateWatchData(data);
} else if (role == LocalsIndividualFormatRole) {
const int format = value.toInt();
if (format == -1) {
m_handler->m_individualFormats.remove(data.addr);
} else {
m_handler->m_individualFormats[data.addr] = format;
}
m_handler->m_manager->updateWatchData(data);
engine()->updateWatchData(data);
}
emit dataChanged(index, index);
return true;
@@ -985,9 +1054,9 @@ void WatchModel::formatRequests(QByteArray *out, const WatchItem *item) const
//
///////////////////////////////////////////////////////////////////////
WatchHandler::WatchHandler(DebuggerManager *manager)
WatchHandler::WatchHandler(DebuggerEngine *engine)
{
m_manager = manager;
m_engine = engine;
m_expandPointers = true;
m_inChange = false;
@@ -1021,7 +1090,7 @@ void WatchHandler::endCycle()
m_locals->endCycle();
m_watchers->endCycle();
m_tooltips->endCycle();
m_manager->updateWatchersWindow();
updateWatchersWindow();
}
void WatchHandler::cleanup()
@@ -1063,9 +1132,8 @@ void WatchHandler::insertData(const WatchData &data)
if (data.isSomethingNeeded() && data.iname.contains('.')) {
MODEL_DEBUG("SOMETHING NEEDED: " << data.toString());
IDebuggerEngine *engine = m_manager->currentEngine();
if (engine && !engine->isSynchroneous()) {
m_manager->updateWatchData(data);
if (!m_engine->isSynchroneous()) {
m_engine->updateWatchData(data);
} else {
qDebug() << "ENDLESS LOOP: SOMETHING NEEDED: " << data.toString();
WatchData data1 = data;
@@ -1116,7 +1184,7 @@ void WatchHandler::insertBulkData(const QList<WatchData> &list)
foreach (const WatchData &data, list) {
if (data.isSomethingNeeded())
m_manager->updateWatchData(data);
m_engine->updateWatchData(data);
}
}
@@ -1151,13 +1219,12 @@ void WatchHandler::watchExpression(const QString &exp)
if (exp.isEmpty() || exp == watcherEditPlaceHolder())
data.setAllUnneeded();
data.iname = watcherName(data.exp);
IDebuggerEngine *engine = m_manager->currentEngine();
if (engine && engine->isSynchroneous())
m_manager->updateWatchData(data);
if (m_engine && m_engine->isSynchroneous())
m_engine->updateWatchData(data);
else
insertData(data);
m_manager->updateWatchData(data);
m_manager->updateWatchersWindow();
m_engine->updateWatchData(data);
updateWatchersWindow();
saveWatchers();
}
@@ -1275,6 +1342,13 @@ void WatchHandler::removeWatchExpression(const QString &exp0)
}
}
void WatchHandler::updateWatchersWindow()
{
const bool showWatchers = m_watchers->rowCount(QModelIndex()) > 0;
const bool showReturn = m_return->rowCount(QModelIndex()) > 0;
plugin()->updateWatchersWindow(showWatchers, showReturn);
}
void WatchHandler::updateWatchers()
{
//qDebug() << "UPDATE WATCHERS";
@@ -1291,7 +1365,7 @@ void WatchHandler::updateWatchers()
void WatchHandler::loadWatchers()
{
QVariant value = m_manager->sessionValue("Watchers");
QVariant value = plugin()->sessionValue("Watchers");
foreach (const QString &exp, value.toStringList())
m_watcherNames[exp.toLatin1()] = watcherCounter++;
@@ -1316,12 +1390,12 @@ QStringList WatchHandler::watchedExpressions() const
void WatchHandler::saveWatchers()
{
//qDebug() << "SAVE WATCHERS: " << m_watchers;
m_manager->setSessionValue("Watchers", QVariant(watchedExpressions()));
plugin()->setSessionValue("Watchers", QVariant(watchedExpressions()));
}
void WatchHandler::loadTypeFormats()
{
QVariant value = m_manager->sessionValue("DefaultFormats");
QVariant value = plugin()->sessionValue("DefaultFormats");
QMap<QString, QVariant> typeFormats = value.toMap();
QMapIterator<QString, QVariant> it(typeFormats);
while (it.hasNext()) {
@@ -1344,7 +1418,7 @@ void WatchHandler::saveTypeFormats()
typeFormats.insert(key, format);
}
}
m_manager->setSessionValue("DefaultFormats", QVariant(typeFormats));
plugin()->setSessionValue("DefaultFormats", QVariant(typeFormats));
}
void WatchHandler::saveSessionData()
+10 -16
View File
@@ -44,26 +44,18 @@ class QDebug;
QT_END_NAMESPACE
namespace Debugger {
class DebuggerManager;
namespace Internal {
class DebuggerEngine;
class WatchItem;
class WatchHandler;
enum WatchType { ReturnWatch, LocalsWatch, WatchersWatch, TooltipsWatch };
enum WatchRoles
enum WatchType
{
INameRole = Qt::UserRole,
ExpressionRole,
ExpandedRole, // Used to communicate preferred expanded state to the view.
TypeFormatListRole,
TypeFormatRole, // Used to communicate alternative formats to the view.
IndividualFormatRole,
AddressRole, // Memory address of variable as quint64.
RawValueRole, // Unformatted value as string.
PointerValue // Pointer value (address) as quint64.
ReturnWatch,
LocalsWatch,
WatchersWatch,
TooltipsWatch
};
enum IntegerFormat
@@ -132,6 +124,7 @@ signals:
private:
QString niceType(const QString &typeIn) const;
void formatRequests(QByteArray *out, const WatchItem *item) const;
DebuggerEngine *engine() const;
WatchHandler *m_handler;
WatchType m_type;
@@ -144,7 +137,7 @@ class WatchHandler : public QObject
Q_OBJECT
public:
explicit WatchHandler(DebuggerManager *manager);
explicit WatchHandler(DebuggerEngine *engine);
WatchModel *model(WatchType type) const;
WatchModel *modelForIName(const QByteArray &iname) const;
@@ -192,6 +185,7 @@ private:
void loadTypeFormats();
void saveTypeFormats();
void setFormat(const QString &type, int format);
void updateWatchersWindow();
bool m_expandPointers;
bool m_inChange;
@@ -212,7 +206,7 @@ private:
WatchModel *m_locals;
WatchModel *m_watchers;
WatchModel *m_tooltips;
DebuggerManager *m_manager;
DebuggerEngine *m_engine;
};
} // namespace Internal
+60 -63
View File
@@ -28,15 +28,12 @@
**************************************************************************/
#include "watchwindow.h"
#include "watchhandler.h"
#include "breakpoint.h"
#include "breakhandler.h"
#include "debuggeractions.h"
#include "debuggeragents.h"
#include "debuggerconstants.h"
#include "debuggerengine.h"
#include "debuggerdialogs.h"
#include "debuggermanager.h"
#include "idebuggerengine.h"
#include "watchhandler.h"
#include <utils/qtcassert.h>
#include <utils/savedaction.h>
@@ -80,9 +77,9 @@ public:
QLineEdit *lineEdit = qobject_cast<QLineEdit *>(editor);
QTC_ASSERT(lineEdit, return);
if (index.column() == 1)
lineEdit->setText(index.model()->data(index, Qt::DisplayRole).toString());
lineEdit->setText(index.data(Qt::DisplayRole).toString());
else
lineEdit->setText(index.model()->data(index, ExpressionRole).toString());
lineEdit->setText(index.data(LocalsExpressionRole).toString());
}
void setModelData(QWidget *editor, QAbstractItemModel *model,
@@ -91,15 +88,15 @@ public:
//qDebug() << "SET MODEL DATA";
QLineEdit *lineEdit = qobject_cast<QLineEdit*>(editor);
QTC_ASSERT(lineEdit, return);
QString value = lineEdit->text();
QString exp = model->data(index, ExpressionRole).toString();
const QString value = lineEdit->text();
const QString exp = index.data(LocalsExpressionRole).toString();
model->setData(index, value, Qt::EditRole);
if (index.column() == 1) {
// The value column.
theDebuggerAction(AssignValue)->trigger(QString(exp + '=' + value));
model->setData(index, QString(exp + '=' + value), RequestAssignValueRole);
} else if (index.column() == 2) {
// The type column.
theDebuggerAction(AssignType)->trigger(QString(exp + '=' + value));
model->setData(index, QString(exp + '=' + value), RequestAssignTypeRole);
} else if (index.column() == 0) {
// The watcher name column.
theDebuggerAction(RemoveWatchExpression)->trigger(exp);
@@ -121,9 +118,10 @@ public:
//
/////////////////////////////////////////////////////////////////////
WatchWindow::WatchWindow(Type type, DebuggerManager *manager, QWidget *parent)
: QTreeView(parent), m_alwaysResizeColumnsToContents(true), m_type(type),
m_manager(manager)
WatchWindow::WatchWindow(Type type, QWidget *parent)
: QTreeView(parent),
m_alwaysResizeColumnsToContents(true),
m_type(type)
{
m_grabbing = false;
@@ -149,12 +147,12 @@ WatchWindow::WatchWindow(Type type, DebuggerManager *manager, QWidget *parent)
void WatchWindow::expandNode(const QModelIndex &idx)
{
model()->setData(idx, true, ExpandedRole);
setModelData(LocalsExpandedRole, true, idx);
}
void WatchWindow::collapseNode(const QModelIndex &idx)
{
model()->setData(idx, false, ExpandedRole);
setModelData(LocalsExpandedRole, false, idx);
}
void WatchWindow::keyPressEvent(QKeyEvent *ev)
@@ -162,7 +160,7 @@ void WatchWindow::keyPressEvent(QKeyEvent *ev)
if (ev->key() == Qt::Key_Delete && m_type == WatchersType) {
QModelIndex idx = currentIndex();
QModelIndex idx1 = idx.sibling(idx.row(), 0);
QString exp = model()->data(idx1).toString();
QString exp = idx1.data().toString();
theDebuggerAction(RemoveWatchExpression)->trigger(exp);
} else if (ev->key() == Qt::Key_Return
&& ev->modifiers() == Qt::ControlModifier
@@ -204,38 +202,23 @@ void WatchWindow::dropEvent(QDropEvent *ev)
//QTreeView::dropEvent(ev);
}
static inline void toggleWatchPoint(DebuggerManager *manager, quint64 address)
{
const QByteArray addressBA = QByteArray("0x") + QByteArray::number(address, 16);
const int index = manager->breakHandler()->findWatchPointIndexByAddress(addressBA);
if (index == -1) {
BreakpointData *data = new BreakpointData;
data->type = BreakpointData::WatchpointType;
data->address = addressBA;
manager->breakHandler()->appendBreakpoint(data);
} else {
manager->breakHandler()->removeBreakpoint(index);
}
manager->attemptBreakpointSynchronization();
}
void WatchWindow::contextMenuEvent(QContextMenuEvent *ev)
{
const QModelIndex idx = indexAt(ev->pos());
const QModelIndex mi0 = idx.sibling(idx.row(), 0);
const QModelIndex mi1 = idx.sibling(idx.row(), 1);
const QModelIndex mi2 = idx.sibling(idx.row(), 2);
const quint64 address = model()->data(mi0, AddressRole).toULongLong();
const quint64 pointerValue = model()->data(mi0, PointerValue).toULongLong();
const QString exp = model()->data(mi0, ExpressionRole).toString();
const QString type = model()->data(mi2).toString();
const quint64 address = mi0.data(LocalsAddressRole).toULongLong();
const quint64 pointerValue = mi0.data(LocalsPointerValueRole).toULongLong();
const QString exp = mi0.data(LocalsExpressionRole).toString();
const QString type = mi2.data().toString();
const QStringList alternativeFormats =
model()->data(mi0, TypeFormatListRole).toStringList();
mi0.data(LocalsTypeFormatListRole).toStringList();
const int typeFormat =
model()->data(mi0, TypeFormatRole).toInt();
mi0.data(LocalsTypeFormatRole).toInt();
const int individualFormat =
model()->data(mi0, IndividualFormatRole).toInt();
mi0.data(LocalsIndividualFormatRole).toInt();
const int effectiveIndividualFormat =
individualFormat == -1 ? typeFormat : individualFormat;
@@ -297,12 +280,11 @@ void WatchWindow::contextMenuEvent(QContextMenuEvent *ev)
individualFormatMenu.setEnabled(false);
}
QMenu menu;
const bool actionsEnabled = m_manager->debuggerActionsEnabled();
const unsigned engineCapabilities = m_manager->debuggerCapabilities();
const bool actionsEnabled = modelData(EngineActionsEnabledRole).toBool();
const unsigned engineCapabilities = modelData(EngineCapabilitiesRole).toUInt();
const bool canHandleWatches = actionsEnabled && (engineCapabilities & AddWatcherCapability);
QMenu menu;
QAction *actInsertNewWatchItem = menu.addAction(tr("Insert New Watch Item"));
actInsertNewWatchItem->setEnabled(canHandleWatches);
QAction *actSelectWidgetToWatch = menu.addAction(tr("Select Widget to Watch"));
@@ -316,29 +298,31 @@ void WatchWindow::contextMenuEvent(QContextMenuEvent *ev)
actOpenMemoryEditor->setEnabled(actionsEnabled && canShowMemory);
// Offer to open address pointed to or variable address.
const bool createPointerActions = pointerValue && pointerValue != address;
const bool createPointerActions = pointerValue && pointerValue != address;
if (canShowMemory && address)
actOpenMemoryEditAtVariableAddress =
new QAction(tr("Open Memory Editor at Object's Address (0x%1)").arg(address, 0, 16), &menu);
if (createPointerActions)
actOpenMemoryEditAtPointerValue =
new QAction(tr("Open Memory Editor at Referenced Address (0x%1)").arg(pointerValue, 0, 16), &menu);
new QAction(tr("Open Memory Editor at Referenced Address (0x%1)").arg(pointerValue, 0, 16), &menu);
menu.addSeparator();
QAction *actSetWatchPointAtVariableAddress = 0;
QAction *actSetWatchPointAtPointerValue= 0;
QAction *actSetWatchPointAtPointerValue = 0;
const bool canSetWatchpoint = engineCapabilities & WatchpointCapability;
if (canSetWatchpoint && address) {
actSetWatchPointAtVariableAddress =
new QAction(tr("Break on Changes at Object's Address (0x%1)").arg(address, 0, 16), &menu);
actSetWatchPointAtVariableAddress->setCheckable(true);
actSetWatchPointAtVariableAddress->setChecked(m_manager->breakHandler()->watchPointAt(address));
actSetWatchPointAtVariableAddress->
setChecked(mi0.data(LocalsIsWatchpointAtAddressRole).toBool());
if (createPointerActions) {
actSetWatchPointAtPointerValue =
new QAction(tr("Break on Changes at Referenced Address (0x%1)").arg(pointerValue, 0, 16), &menu);
new QAction(tr("Break on Changes at Referenced Address (0x%1)").arg(pointerValue, 0, 16), &menu);
actSetWatchPointAtPointerValue->setCheckable(true);
actSetWatchPointAtPointerValue->setChecked(m_manager->breakHandler()->watchPointAt(pointerValue));
actSetWatchPointAtPointerValue->
setChecked(mi0.data(LocalsIsWatchpointAtPointerValueRole).toBool());
}
} else {
actSetWatchPointAtVariableAddress =
@@ -407,35 +391,34 @@ void WatchWindow::contextMenuEvent(QContextMenuEvent *ev)
theDebuggerAction(WatchExpression)
->trigger(WatchHandler::watcherEditPlaceHolder());
} else if (act == actOpenMemoryEditAtVariableAddress) {
(void) new MemoryViewAgent(m_manager, address);
setModelData(RequestShowMemoryRole, address);
} else if (act == actOpenMemoryEditAtPointerValue) {
(void) new MemoryViewAgent(m_manager, pointerValue);
setModelData(RequestShowMemoryRole, pointerValue);
} else if (act == actOpenMemoryEditor) {
AddressDialog dialog;
if (dialog.exec() == QDialog::Accepted) {
(void) new MemoryViewAgent(m_manager, dialog.address());
}
if (dialog.exec() == QDialog::Accepted)
setModelData(RequestShowMemoryRole, dialog.address());
} else if (act == actSetWatchPointAtVariableAddress) {
toggleWatchPoint(m_manager, address);
setModelData(RequestToggleWatchRole, address);
} else if (act == actSetWatchPointAtPointerValue) {
toggleWatchPoint(m_manager, pointerValue);
setModelData(RequestToggleWatchRole, pointerValue);
} else if (act == actSelectWidgetToWatch) {
grabMouse(Qt::CrossCursor);
m_grabbing = true;
} else if (act == actClearCodeModelSnapshot) {
m_manager->clearCppCodeModelSnapshot();
setModelData(RequestClearCppCodeModelSnapshotRole);
} else if (act == clearTypeFormatAction) {
model()->setData(mi1, -1, TypeFormatRole);
setModelData(LocalsTypeFormatRole, -1, mi1);
} else if (act == clearIndividualFormatAction) {
model()->setData(mi1, -1, IndividualFormatRole);
setModelData(LocalsIndividualFormatRole, -1, mi1);
} else {
for (int i = 0; i != typeFormatActions.size(); ++i) {
if (act == typeFormatActions.at(i))
model()->setData(mi1, i, TypeFormatRole);
setModelData(LocalsTypeFormatRole, 1, mi1);
}
for (int i = 0; i != individualFormatActions.size(); ++i) {
if (act == individualFormatActions.at(i))
model()->setData(mi1, i, IndividualFormatRole);
setModelData(LocalsIndividualFormatRole, 1, mi1);
}
}
}
@@ -502,7 +485,7 @@ void WatchWindow::resetHelper()
void WatchWindow::resetHelper(const QModelIndex &idx)
{
if (model()->data(idx, ExpandedRole).toBool()) {
if (idx.data(LocalsExpandedRole).toBool()) {
//qDebug() << "EXPANDING " << model()->data(idx, INameRole);
expand(idx);
for (int i = 0, n = model()->rowCount(idx); i != n; ++i) {
@@ -514,3 +497,17 @@ void WatchWindow::resetHelper(const QModelIndex &idx)
collapse(idx);
}
}
void WatchWindow::setModelData
(int role, const QVariant &value, const QModelIndex &index)
{
QTC_ASSERT(model(), return);
model()->setData(index, value, role);
}
QVariant WatchWindow::modelData(int role, const QModelIndex &index)
{
QTC_ASSERT(model(), return QVariant());
return model()->data(index, role);
}
+6 -5
View File
@@ -32,9 +32,8 @@
#include <QtGui/QTreeView>
namespace Debugger {
class DebuggerManager;
namespace Debugger {
namespace Internal {
/////////////////////////////////////////////////////////////////////
@@ -50,8 +49,7 @@ class WatchWindow : public QTreeView
public:
enum Type { ReturnType, LocalsType, TooltipType, WatchersType };
WatchWindow(Type type, DebuggerManager *manager, QWidget *parent = 0);
void setType(Type type) { m_type = type; }
WatchWindow(Type type, QWidget *parent = 0);
Type type() const { return m_type; }
public slots:
@@ -76,9 +74,12 @@ private:
void editItem(const QModelIndex &idx);
void resetHelper(const QModelIndex &idx);
void setModelData(int role, const QVariant &value = QVariant(),
const QModelIndex &index = QModelIndex());
QVariant modelData(int role, const QModelIndex &index = QModelIndex());
bool m_alwaysResizeColumnsToContents;
Type m_type;
DebuggerManager *m_manager;
bool m_grabbing;
};
+5 -4
View File
@@ -38,11 +38,12 @@
#include "components/expressionquerywidget.h"
#include "components/objectpropertiesview.h"
#include <debugger/debuggermanager.h>
#include <debugger/debuggerconstants.h>
#include <debugger/debuggerengine.h>
#include <debugger/debuggermainwindow.h>
#include <debugger/debuggerplugin.h>
#include <debugger/debuggerrunner.h>
#include <debugger/debuggeruiswitcher.h>
#include <debugger/debuggerconstants.h>
#include <utils/styledbar.h>
#include <utils/fancymainwindow.h>
@@ -176,8 +177,8 @@ QmlInspector::QmlInspector(QObject *parent)
// m_frameRateWidget = new Internal::CanvasFrameRate;
// m_frameRateWidget->setObjectName(QLatin1String("QmlDebugFrameRate"));
Debugger::DebuggerManager *debugManager = Debugger::DebuggerManager::instance();
connect(debugManager, SIGNAL(stateChanged(int)), this, SLOT(debuggerStateChanged(int)));
connect(Debugger::DebuggerPlugin::instance(),
SIGNAL(stateChanged(int)), this, SLOT(debuggerStateChanged(int)));
m_editablePropertyTypes = QStringList() << "qreal" << "bool" << "QString"
<< "int" << "QVariant" << "QUrl" << "QColor";
@@ -41,7 +41,8 @@
#include <coreplugin/icore.h>
#include <coreplugin/progressmanager/progressmanager.h>
#include <debugger/debuggermanager.h>
#include <debugger/debuggerengine.h>
#include <debugger/debuggerplugin.h>
#include <debugger/debuggerrunner.h>
#include <extensionsystem/pluginmanager.h>
#include <projectexplorer/toolchain.h>
@@ -381,11 +382,9 @@ void MaemoRunControl::handleRemoteOutput(const QString &output)
MaemoDebugRunControl::MaemoDebugRunControl(RunConfiguration *runConfiguration)
: AbstractMaemoRunControl(runConfiguration, ProjectExplorer::Constants::DEBUGMODE)
, m_debuggerManager(ExtensionSystem::PluginManager::instance()
->getObject<Debugger::DebuggerManager>())
, m_debuggerRunControl(0)
, m_startParams(new Debugger::DebuggerStartParameters)
{
QTC_ASSERT(m_debuggerManager != 0, return);
#ifdef USE_GDBSERVER
m_startParams->startMode = Debugger::AttachToRemote;
m_startParams->executable = executableOnHost();
@@ -406,8 +405,14 @@ MaemoDebugRunControl::MaemoDebugRunControl(RunConfiguration *runConfiguration)
m_startParams->remoteDumperLib = remoteDir().toUtf8() + '/'
+ QFileInfo(m_runConfig->dumperLib()).fileName().toUtf8();
connect(m_debuggerManager, SIGNAL(debuggingFinished()), this,
m_debuggerRunControl = qobject_cast<Debugger::DebuggerRunControl *>
(Debugger::DebuggerPlugin::createDebugger(*m_startParams.data()));
connect(m_debuggerRunControl, SIGNAL(debuggingFinished()), this,
SLOT(debuggingFinished()), Qt::QueuedConnection);
/*
FIXME:
connect(m_debuggerManager, SIGNAL(applicationOutputAvailable(QString, bool)),
this,
#ifdef USE_GDBSERVER
@@ -416,6 +421,7 @@ MaemoDebugRunControl::MaemoDebugRunControl(RunConfiguration *runConfiguration)
SLOT(handleRemoteOutput(QString))
#endif
, Qt::QueuedConnection);
*/
}
MaemoDebugRunControl::~MaemoDebugRunControl()
@@ -460,20 +466,18 @@ void MaemoDebugRunControl::handleRemoteOutput(const QString &output)
void MaemoDebugRunControl::startDebugging()
{
Debugger::DebuggerRunControl *runControl =
new Debugger::DebuggerRunControl(m_debuggerManager, *m_startParams.data());
m_debuggerManager->startNewDebugger(runControl);
Debugger::DebuggerPlugin::startDebugger(m_debuggerRunControl);
}
void MaemoDebugRunControl::stopInternal()
{
m_debuggerManager->exitDebugger();
m_debuggerRunControl->engine()->quitDebugger();
}
bool MaemoDebugRunControl::isRunning() const
{
return AbstractMaemoRunControl::isRunning()
|| m_debuggerManager->state() != Debugger::DebuggerNotReady;
|| m_debuggerRunControl->engine()->state() != Debugger::DebuggerNotReady;
}
void MaemoDebugRunControl::debuggingFinished()
@@ -499,5 +503,5 @@ QString MaemoDebugRunControl::gdbServerPort() const
// but we will make sure we use the right port from the information file.
}
} // namespace Internal
} // namespace Internal
} // namespace Qt4ProjectManager
@@ -48,7 +48,7 @@ class QProcess;
QT_END_NAMESPACE
namespace Debugger {
class DebuggerManager;
class DebuggerRunControl;
class DebuggerStartParameters;
} // namespace Debugger
@@ -168,7 +168,7 @@ private:
QString gdbServerPort() const;
void startDebugging();
Debugger::DebuggerManager *m_debuggerManager;
Debugger::DebuggerRunControl *m_debuggerRunControl;
QSharedPointer<Debugger::DebuggerStartParameters> m_startParams;
bool m_debuggingStarted;
@@ -51,7 +51,8 @@
#include <projectexplorer/project.h>
#include <projectexplorer/buildconfiguration.h>
#include <debugger/debuggermanager.h>
#include <debugger/debuggerengine.h>
#include <debugger/debuggerplugin.h>
#include <debugger/debuggerrunner.h>
#include <QtGui/QMessageBox>
@@ -890,7 +891,7 @@ S60DeviceDebugRunControl::S60DeviceDebugRunControl(S60DeviceRunConfiguration *ru
m_startParams(new Debugger::DebuggerStartParameters)
{
setReleaseDeviceAfterLauncherFinish(true); // Debugger controls device after install
Debugger::DebuggerManager *dm = Debugger::DebuggerManager::instance();
Debugger::DebuggerPlugin *dm = Debugger::DebuggerPlugin::instance();
S60DeviceRunConfiguration *rc = qobject_cast<S60DeviceRunConfiguration *>(runConfiguration);
QTC_ASSERT(dm && rc, return);
@@ -915,8 +916,10 @@ S60DeviceDebugRunControl::S60DeviceDebugRunControl(S60DeviceRunConfiguration *ru
void S60DeviceDebugRunControl::stop()
{
S60DeviceRunControlBase::stop();
Debugger::DebuggerManager *dm = Debugger::DebuggerManager::instance();
Debugger::DebuggerPlugin *dm = Debugger::DebuggerPlugin::instance();
QTC_ASSERT(dm, return)
// FIXME: ABC: that should use the RunControl present in
// handleLauncherFinished
if (dm->state() == Debugger::DebuggerNotReady)
dm->exitDebugger();
}
@@ -944,11 +947,11 @@ void S60DeviceDebugRunControl::initLauncher(const QString &executable, trk::Laun
void S60DeviceDebugRunControl::handleLauncherFinished()
{
using namespace Debugger;
emit appendMessage(this, tr("Launching debugger..."), false);
Debugger::DebuggerManager *dm = Debugger::DebuggerManager::instance();
Debugger::DebuggerRunControl *runControl =
new Debugger::DebuggerRunControl(dm, *m_startParams.data());
dm->startNewDebugger(runControl);
ProjectExplorer::RunControl *rc
= DebuggerPlugin::createDebugger(*m_startParams.data());
DebuggerPlugin::startDebugger(rc);
}
void S60DeviceDebugRunControl::debuggingFinished()
@@ -961,8 +964,9 @@ bool S60DeviceDebugRunControl::checkConfiguration(QString *errorMessage,
QString *settingsCategory,
QString *settingsPage) const
{
return Debugger::DebuggerManager::instance()->checkDebugConfiguration(m_startParams->toolChainType,
errorMessage,
settingsCategory,
settingsPage);
return Debugger::DebuggerRunControl::checkDebugConfiguration(
m_startParams->toolChainType,
errorMessage,
settingsCategory,
settingsPage);
}
@@ -43,7 +43,7 @@
#include <extensionsystem/pluginmanager.h>
#include <projectexplorer/projectexplorerconstants.h>
#include <projectexplorer/toolchain.h>
#include <debugger/debuggermanager.h>
#include <debugger/debuggerplugin.h>
#include <utils/qtcassert.h>
#include <QtGui/QMainWindow>
@@ -121,7 +121,7 @@ S60Manager::S60Manager(QObject *parent)
tr("Run on Device"), parent));
addAutoReleasedObject(new S60CreatePackageStepFactory);
if (Debugger::DebuggerManager::instance())
if (Debugger::DebuggerPlugin::instance())
addAutoReleasedObject(new RunControlFactory<S60DeviceDebugRunControl,
S60DeviceRunConfiguration>
(QLatin1String(ProjectExplorer::Constants::DEBUGMODE),
+1 -1
View File
@@ -749,7 +749,7 @@ void testQObject(int &argc, char *argv[])
ob1.setObjectName("A Subobject");
#endif
#if 0
#if 1
QString str = QString::fromUtf8("XXXXXXXXXXXXXXyyXXX ö");
QLabel l(str);
l.setObjectName("Some Label");