forked from qt-creator/qt-creator
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:
@@ -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"))
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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, ¤tThreadId, &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
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -42,9 +42,8 @@ namespace CdbCore {
|
||||
}
|
||||
|
||||
namespace Debugger {
|
||||
class DebuggerManager;
|
||||
|
||||
namespace Internal {
|
||||
|
||||
class CdbDumperInitThread;
|
||||
class CdbDebugEngine;
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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 \
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
@@ -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>
|
||||
|
||||
+1808
-671
File diff suppressed because it is too large
Load Diff
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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");
|
||||
|
||||
Reference in New Issue
Block a user