diff --git a/src/plugins/debugger/breakhandler.cpp b/src/plugins/debugger/breakhandler.cpp index 8cd2bf55d5e..359af3e1e78 100644 --- a/src/plugins/debugger/breakhandler.cpp +++ b/src/plugins/debugger/breakhandler.cpp @@ -42,6 +42,10 @@ #include +#if USE_BREAK_MODEL_TEST +#include "modeltest.h" +#endif + #include #include #include @@ -126,7 +130,11 @@ static QString typeToString(BreakpointType type) BreakHandler::BreakHandler() : m_syncTimerId(-1) -{} +{ +#if USE_BREAK_MODEL_TEST + new ModelTest(this, 0); +#endif +} BreakHandler::~BreakHandler() {} @@ -169,16 +177,6 @@ QIcon BreakHandler::emptyIcon() return icon; } -int BreakHandler::columnCount(const QModelIndex &parent) const -{ - return parent.isValid() ? 0 : 8; -} - -int BreakHandler::rowCount(const QModelIndex &parent) const -{ - return parent.isValid() ? 0 : m_storage.size(); -} - static inline bool fileNameMatch(const QString &f1, const QString &f2) { #ifdef Q_OS_WIN @@ -431,12 +429,9 @@ QVariant BreakHandler::headerData(int section, BreakpointId BreakHandler::findBreakpointByIndex(const QModelIndex &index) const { - int r = index.row(); - ConstIterator it = m_storage.constBegin(), et = m_storage.constEnd(); - for (int i = 0; it != et; ++it, ++i) - if (i == r) - return it.key(); - return BreakpointId(); + //qDebug() << "FIND: " << index << + // BreakpointId::fromInternalId(index.internalId()); + return BreakpointId::fromInternalId(index.internalId()); } BreakpointIds BreakHandler::findBreakpointsByIndex(const QList &list) const @@ -469,15 +464,72 @@ int BreakHandler::threadSpecFromDisplay(const QString &str) return ok ? result : -1; } -QModelIndex BreakHandler::index(int row, int col, const QModelIndex &parent) const +QModelIndex BreakHandler::createIndex(int row, int column, quint32 id) const { - Q_UNUSED(parent); - return createIndex(row, col, 0); + return QAbstractItemModel::createIndex(row, column, id); } -QModelIndex BreakHandler::parent(const QModelIndex &parent) const +QModelIndex BreakHandler::createIndex(int row, int column, void *ptr) const { - Q_UNUSED(parent); + QTC_ASSERT(false, /**/); // This function is not used. + return QAbstractItemModel::createIndex(row, column, ptr); +} + +int BreakHandler::columnCount(const QModelIndex &idx) const +{ + if (idx.column() > 0) + return 0; + const BreakpointId id = findBreakpointByIndex(idx); + return id.isMinor() ? 0 : 8; +} + +int BreakHandler::rowCount(const QModelIndex &idx) const +{ + if (idx.column() > 0) + return 0; + if (!idx.isValid()) + return m_storage.size(); + const BreakpointId id = findBreakpointByIndex(idx); + if (id.isMajor()) + return m_storage.value(id).subItems.size(); + return 0; +} + +QModelIndex BreakHandler::index(int row, int col, const QModelIndex &parent) const +{ + if (row < 0 || col < 0) + return QModelIndex(); + if (parent.column() > 0) + return QModelIndex(); + BreakpointId id = findBreakpointByIndex(parent); + if (id.isMajor()) { + ConstIterator it = m_storage.find(id); + if (row >= it->subItems.size()) + return QModelIndex(); + BreakpointId sub = id.child(row); + return createIndex(row, col, sub.toInternalId()); + } + if (id.isMinor()) + return QModelIndex(); + QTC_ASSERT(!id.isValid(), return QModelIndex()); + if (row >= m_storage.size()) + return QModelIndex(); + id = at(row); + return createIndex(row, col, id.toInternalId()); +} + +QModelIndex BreakHandler::parent(const QModelIndex &idx) const +{ + if (!idx.isValid()) + return QModelIndex(); + BreakpointId id = findBreakpointByIndex(idx); + if (id.isMajor()) + return QModelIndex(); + if (id.isMinor()) { + BreakpointId pid = id.parent(); + int row = indexOf(pid); + return createIndex(row, 0, pid.toInternalId()); + } return QModelIndex(); } @@ -489,9 +541,13 @@ QVariant BreakHandler::data(const QModelIndex &mi, int role) const return QVariant(); BreakpointId id = findBreakpointByIndex(mi); - //qDebug() << "DATA: " << id << role << mi.column(); - ConstIterator it = m_storage.find(id); - BREAK_ASSERT(it != m_storage.end(), return QVariant()); + + BreakpointId pid = id; + if (id.isMinor()) + pid = id.parent(); + + ConstIterator it = m_storage.find(pid); + QTC_ASSERT(it != m_storage.end(), return QVariant()); const BreakpointParameters &data = it->data; const BreakpointResponse &response = it->response; @@ -511,10 +567,24 @@ QVariant BreakHandler::data(const QModelIndex &mi, int role) const break; }; + if (id.isMinor()) { + QTC_ASSERT(id.minorPart() <= it->subItems.size(), return QVariant()); + const BreakpointResponse &res = it->subItems.at(id.minorPart() - 1); + switch (mi.column()) { + case 0: + if (role == Qt::DisplayRole) + return id.toString(); + case 1: + if (role == Qt::DisplayRole) + return res.functionName; + } + return QVariant(); + } + switch (mi.column()) { case 0: if (role == Qt::DisplayRole) { - return QString::number(id); + return id.toString(); //return QString("%1 - %2").arg(id).arg(response.number); } if (role == Qt::DecorationRole) @@ -894,6 +964,7 @@ void BreakHandler::notifyBreakpointReleased(BreakpointId id) it->state = BreakpointNew; it->engine = 0; it->response = BreakpointResponse(); + it->subItems.clear(); delete it->marker; it->marker = 0; if (it->data.type == WatchpointAtAddress @@ -937,8 +1008,8 @@ void BreakHandler::removeBreakpoint(BreakpointId id) cleanupBreakpoint(id); break; default: - qWarning("Warning: Cannot remove breakpoint %llu in state '%s'.", - id, qPrintable(stateToString(it->state))); + qWarning("Warning: Cannot remove breakpoint %s in state '%s'.", + qPrintable(id.toString()), qPrintable(stateToString(it->state))); it->state = BreakpointRemoveRequested; break; } @@ -963,9 +1034,42 @@ void BreakHandler::appendBreakpoint(const BreakpointParameters &data) m_storage.insert(id, item); endInsertRows(); + layoutChanged(); + updateMarker(id); scheduleSynchronization(); +} +BreakpointId BreakHandler::at(int n) const +{ + if (n < 0 || n >= m_storage.size()) + return BreakpointId(); + ConstIterator it = m_storage.constBegin(), et = m_storage.constEnd(); + for ( ; --n >= 0; ++it) + ; + return it.key(); +} + +int BreakHandler::indexOf(BreakpointId id) const +{ + int row = 0; + ConstIterator it = m_storage.constBegin(), et = m_storage.constEnd(); + for ( ; it != et; ++it, ++row) + if (it.key() == id) + return row; + return -1; +} + +void BreakHandler::appendSubBreakpoint(BreakpointId id, const BreakpointResponse &data) +{ + Iterator it = m_storage.find(id); + QTC_ASSERT(it != m_storage.end(), return); + int row = indexOf(id); + QTC_ASSERT(row != -1, return); + QModelIndex idx = createIndex(row, 0, id.toInternalId()); + beginInsertRows(idx, it->subItems.size(), it->subItems.size()); + it->subItems.append(data); + endInsertRows(); } void BreakHandler::saveSessionData() diff --git a/src/plugins/debugger/breakhandler.h b/src/plugins/debugger/breakhandler.h index d7ed2798a42..695a56f38ca 100644 --- a/src/plugins/debugger/breakhandler.h +++ b/src/plugins/debugger/breakhandler.h @@ -70,6 +70,7 @@ public: // The only way to add a new breakpoint. void appendBreakpoint(const BreakpointParameters &data); + void appendSubBreakpoint(BreakpointId id, const BreakpointResponse &data); BreakpointIds allBreakpointIds() const; BreakpointIds engineBreakpointIds(DebuggerEngine *engine) const; @@ -169,7 +170,11 @@ private: Qt::ItemFlags flags(const QModelIndex &index) const; QModelIndex index(int row, int col, const QModelIndex &parent) const; QModelIndex parent(const QModelIndex &parent) const; + QModelIndex createIndex(int row, int column, quint32 id) const; + QModelIndex createIndex(int row, int column, void *ptr) const; + int indexOf(BreakpointId id) const; + BreakpointId at(int index) const; bool isEngineRunning(BreakpointId id) const; void setState(BreakpointId id, BreakpointState state); void loadBreakpoints(); @@ -195,6 +200,7 @@ private: DebuggerEngine *engine; // Engine currently handling the breakpoint. BreakpointResponse response; BreakpointMarker *marker; + QList subItems; }; typedef QHash BreakpointStorage; typedef BreakpointStorage::ConstIterator ConstIterator; diff --git a/src/plugins/debugger/breakpoint.cpp b/src/plugins/debugger/breakpoint.cpp index 70d75db4da4..6b48be34c44 100644 --- a/src/plugins/debugger/breakpoint.cpp +++ b/src/plugins/debugger/breakpoint.cpp @@ -32,12 +32,47 @@ #include "breakpoint.h" +#include "utils/qtcassert.h" + #include #include namespace Debugger { namespace Internal { +////////////////////////////////////////////////////////////////// +// +// BreakpointId +// +////////////////////////////////////////////////////////////////// + +QDebug operator<<(QDebug d, const BreakpointId &id) +{ + d << qPrintable(id.toString()); + return d; +} + +QString BreakpointId::toString() const +{ + if (!isValid()) + return ""; + if (isMinor()) + return QString("%1.%2").arg(m_majorPart).arg(m_minorPart); + return QString::number(m_majorPart); +} + +BreakpointId BreakpointId::parent() const +{ + QTC_ASSERT(isMinor(), return BreakpointId()); + return BreakpointId(m_majorPart, 0); +} + +BreakpointId BreakpointId::child(int row) const +{ + QTC_ASSERT(isMajor(), return BreakpointId()); + return BreakpointId(m_majorPart, row + 1); +} + ////////////////////////////////////////////////////////////////// // // BreakpointParameters @@ -163,24 +198,34 @@ QString BreakpointParameters::toString() const */ BreakpointResponse::BreakpointResponse() - : number(0), pending(true), multiple(false), correctedLineNumber(0) -{} +{ + number = 0; + subNumber = 0; + pending = true; + multiple = false; + correctedLineNumber = 0; +} QString BreakpointResponse::toString() const { QString result = BreakpointParameters::toString(); QTextStream ts(&result); ts << " Number: " << number; + if (subNumber) + ts << "." << subNumber; if (pending) ts << " [pending]"; if (!fullName.isEmpty()) ts << " FullName: " << fullName; + if (!functionName.isEmpty()) + ts << " Function: " << functionName; if (multiple) ts << " Multiple: " << multiple; if (!extra.isEmpty()) ts << " Extra: " << extra; if (correctedLineNumber) ts << " CorrectedLineNumber: " << correctedLineNumber; + ts << ' '; return result + BreakpointParameters::toString(); } @@ -188,6 +233,7 @@ void BreakpointResponse::fromParameters(const BreakpointParameters &p) { BreakpointParameters::operator=(p); number = 0; + subNumber = 0; fullName.clear(); multiple = false; extra.clear(); diff --git a/src/plugins/debugger/breakpoint.h b/src/plugins/debugger/breakpoint.h index c922684178a..e9780a79709 100644 --- a/src/plugins/debugger/breakpoint.h +++ b/src/plugins/debugger/breakpoint.h @@ -33,6 +33,7 @@ #ifndef DEBUGGER_BREAKPOINT_H #define DEBUGGER_BREAKPOINT_H +#include #include #include #include @@ -40,7 +41,36 @@ namespace Debugger { namespace Internal { -typedef quint64 BreakpointId; +class BreakpointId +{ +public: + BreakpointId() { m_majorPart = m_minorPart = 0; } + explicit BreakpointId(quint16 ma) { m_majorPart = ma; m_minorPart = 0; } + BreakpointId(quint16 ma, quint16 mi) { m_majorPart = ma; m_minorPart = mi; } + + bool isValid() const { return m_majorPart != 0; } + bool isMajor() const { return m_majorPart != 0 && m_minorPart == 0; } + bool isMinor() const { return m_majorPart != 0 && m_minorPart != 0; } + bool operator!() const { return !isValid(); } + operator const void*() const { return isValid() ? this : 0; } + quint32 toInternalId() const { return m_majorPart | (m_minorPart << 16); } + QString toString() const; + bool operator==(const BreakpointId &id) const + { return m_majorPart == id.m_majorPart && m_minorPart == id.m_minorPart; } + quint16 majorPart() const { return m_majorPart; } + quint16 minorPart() const { return m_minorPart; } + BreakpointId parent() const; + BreakpointId child(int row) const; + + static BreakpointId fromInternalId(quint32 id) + { return BreakpointId(id & 0xff, id >> 16); } + +private: + quint16 m_majorPart; + quint16 m_minorPart; +}; + +QDebug operator<<(QDebug d, const BreakpointId &id); ////////////////////////////////////////////////////////////////// // @@ -165,6 +195,7 @@ public: void fromParameters(const BreakpointParameters &p); int number; //!< Breakpoint number assigned by the debugger engine. + int subNumber; //!< Breakpoint sub-number assigned by the engine. bool pending; //!< Breakpoint not fully resolved. QString fullName; //!< Full file name acknowledged by the debugger engine. bool multiple; //!< Happens in constructors/gdb. @@ -175,7 +206,15 @@ public: typedef QList BreakpointIds; +inline uint qHash(const Debugger::Internal::BreakpointId &id) +{ + return id.toInternalId(); +} + } // namespace Internal } // namespace Debugger +Q_DECLARE_METATYPE(Debugger::Internal::BreakpointId) + + #endif // DEBUGGER_BREAKPOINT_H diff --git a/src/plugins/debugger/breakwindow.cpp b/src/plugins/debugger/breakwindow.cpp index 8aabf37478f..c832a3dde33 100644 --- a/src/plugins/debugger/breakwindow.cpp +++ b/src/plugins/debugger/breakwindow.cpp @@ -524,6 +524,7 @@ void BreakWindow::setModel(QAbstractItemModel *model) resizeColumnToContents(0); // Number resizeColumnToContents(3); // Line resizeColumnToContents(6); // Ignore count + connect(model, SIGNAL(layoutChanged()), this, SLOT(expandAll())); } void BreakWindow::contextMenuEvent(QContextMenuEvent *ev) diff --git a/src/plugins/debugger/cdb/cdbengine.cpp b/src/plugins/debugger/cdb/cdbengine.cpp index 7005b007b70..f9903516011 100644 --- a/src/plugins/debugger/cdb/cdbengine.cpp +++ b/src/plugins/debugger/cdb/cdbengine.cpp @@ -192,7 +192,7 @@ struct MemoryChangeCookie struct ConditionalBreakPointCookie { - ConditionalBreakPointCookie(BreakpointId i = 0) : id(i) {} + ConditionalBreakPointCookie(BreakpointId i = BreakpointId()) : id(i) {} BreakpointId id; GdbMi stopReason; }; @@ -1817,7 +1817,7 @@ static inline QString msgTracePointTriggered(BreakpointId id, const int number, const QString &threadId) { return CdbEngine::tr("Trace point %1 (%2) in thread %3 triggered.") - .arg(id).arg(number).arg(threadId); + .arg(id.toString()).arg(number).arg(threadId); } static inline QString msgCheckingConditionalBreakPoint(BreakpointId id, const int number, @@ -1825,7 +1825,7 @@ static inline QString msgCheckingConditionalBreakPoint(BreakpointId id, const in const QString &threadId) { return CdbEngine::tr("Conditional breakpoint %1 (%2) in thread %3 triggered, examining expression '%4'.") - .arg(id).arg(number).arg(threadId, QString::fromAscii(condition)); + .arg(id.toString()).arg(number).arg(threadId, QString::fromAscii(condition)); } unsigned CdbEngine::examineStopReason(const GdbMi &stopReason, @@ -1856,11 +1856,11 @@ unsigned CdbEngine::examineStopReason(const GdbMi &stopReason, if (reason == "breakpoint") { // Note: Internal breakpoints (run to line) are reported with id=0. // Step out creates temporary breakpoints with id 10000. - BreakpointId id = 0; + BreakpointId id; int number = 0; const GdbMi breakpointIdG = stopReason.findChild("breakpointId"); if (breakpointIdG.isValid()) { - id = breakpointIdG.data().toULongLong(); + id = BreakpointId(breakpointIdG.data().toInt()); if (id && breakHandler()->engineBreakpointIds(this).contains(id)) { const BreakpointResponse parameters = breakHandler()->response(id); // Trace point? Just report. @@ -1879,7 +1879,7 @@ unsigned CdbEngine::examineStopReason(const GdbMi &stopReason, return StopReportLog; } } else { - id = 0; + id = BreakpointId(); } } QString tid = QString::number(threadId); @@ -2526,7 +2526,7 @@ void CdbEngine::attemptBreakpointSynchronization() postCommand(cdbAddBreakpointCommand(parameters, m_sourcePathMappings, id, false), 0); } if (!parameters.enabled) - postCommand("bd " + QByteArray::number(id), 0); + postCommand("bd " + QByteArray::number(id.majorPart()), 0); handler->notifyBreakpointInsertProceeding(id); handler->notifyBreakpointInsertOk(id); m_pendingBreakpointMap.insert(id, response); @@ -2534,30 +2534,33 @@ void CdbEngine::attemptBreakpointSynchronization() // Ensure enabled/disabled is correct in handler and line number is there. handler->setResponse(id, response); if (debugBreakpoints) - qDebug("Adding %llu %s\n", id, qPrintable(response.toString())); + qDebug("Adding %d %s\n", id.toInternalId(), + qPrintable(response.toString())); break; case BreakpointChangeRequested: handler->notifyBreakpointChangeProceeding(id); if (debugBreakpoints) - qDebug("Changing %llu:\n %s\nTo %s\n", id, qPrintable(handler->response(id).toString()), - qPrintable(parameters.toString())); + qDebug("Changing %d:\n %s\nTo %s\n", id.toInternalId(), + qPrintable(handler->response(id).toString()), + qPrintable(parameters.toString())); if (parameters.enabled != handler->response(id).enabled) { // Change enabled/disabled breakpoints without triggering update. - postCommand((parameters.enabled ? "be " : "bd ") + QByteArray::number(id), 0); + postCommand((parameters.enabled ? "be " : "bd ") + + QByteArray::number(id.majorPart()), 0); response.pending = false; response.enabled = parameters.enabled; handler->setResponse(id, response); } else { // Delete and re-add, triggering update addedChanged = true; - postCommand("bc " + QByteArray::number(id), 0); + postCommand("bc " + QByteArray::number(id.majorPart()), 0); postCommand(cdbAddBreakpointCommand(parameters, m_sourcePathMappings, id, false), 0); m_pendingBreakpointMap.insert(id, response); } handler->notifyBreakpointChangeOk(id); break; case BreakpointRemoveRequested: - postCommand("bc " + QByteArray::number(id), 0); + postCommand("bc " + QByteArray::number(id.majorPart()), 0); handler->notifyBreakpointRemoveProceeding(id); handler->notifyBreakpointRemoveOk(id); m_pendingBreakpointMap.remove(id); @@ -2689,9 +2692,9 @@ void CdbEngine::handleExpression(const CdbExtensionCommandPtr &command) const ConditionalBreakPointCookie cookie = qvariant_cast(command->cookie); const QString message = value ? tr("Value %1 obtained from evaluating the condition of breakpoint %2, stopping."). - arg(value).arg(cookie.id) : + arg(value).arg(cookie.id.toString()) : tr("Value 0 obtained from evaluating the condition of breakpoint %1, continuing."). - arg(cookie.id); + arg(cookie.id.toString()); showMessage(message, LogMisc); // Stop if evaluation is true, else continue if (value) { @@ -2828,8 +2831,9 @@ void CdbEngine::handleBreakPoints(const GdbMi &value) BreakpointResponse reportedResponse; const BreakpointId id = parseBreakPoint(breakPointG, &reportedResponse); if (debugBreakpoints) - qDebug(" Parsed %llu: pending=%d %s\n", id, reportedResponse.pending, - qPrintable(reportedResponse.toString())); + qDebug(" Parsed %d: pending=%d %s\n", id.majorPart(), + reportedResponse.pending, + qPrintable(reportedResponse.toString())); if (!reportedResponse.pending) { const PendingBreakPointMap::iterator it = m_pendingBreakpointMap.find(id); @@ -2843,7 +2847,8 @@ void CdbEngine::handleBreakPoints(const GdbMi &value) currentResponse.enabled = reportedResponse.enabled; formatCdbBreakPointResponse(id, currentResponse, str); if (debugBreakpoints) - qDebug(" Setting for %llu: %s\n", id, qPrintable(currentResponse.toString())); + qDebug(" Setting for %d: %s\n", id.majorPart(), + qPrintable(currentResponse.toString())); handler->setResponse(id, currentResponse); m_pendingBreakpointMap.erase(it); } diff --git a/src/plugins/debugger/cdb/cdbparsehelpers.cpp b/src/plugins/debugger/cdb/cdbparsehelpers.cpp index 0793f2f2da0..d3ed8de6336 100644 --- a/src/plugins/debugger/cdb/cdbparsehelpers.cpp +++ b/src/plugins/debugger/cdb/cdbparsehelpers.cpp @@ -135,7 +135,7 @@ static BreakpointParameters fixWinMSVCBreakpoint(const BreakpointParameters &p) QByteArray cdbAddBreakpointCommand(const BreakpointParameters &bpIn, const QList > &sourcePathMapping, - BreakpointId id /* = BreakpointId(-1) */, + BreakpointId id /* = BreakpointId() */, bool oneshot) { const BreakpointParameters bp = fixWinMSVCBreakpoint(bpIn); @@ -149,8 +149,8 @@ QByteArray cdbAddBreakpointCommand(const BreakpointParameters &bpIn, // is kept when reporting back breakpoints (which is otherwise discarded // when resolving). str << (bp.type == WatchpointAtAddress ? "ba" : "bu"); - if (id != BreakpointId(-1)) - str << id; + if (id.isValid()) + str << id.toString(); str << ' '; if (oneshot) str << "/1 "; @@ -308,7 +308,7 @@ BreakpointId parseBreakPoint(const GdbMi &gdbmi, BreakpointResponse *r, const GdbMi idG = gdbmi.findChild("id"); if (idG.isValid()) { // Might not be valid if there is not id bool ok; - const BreakpointId cid = idG.data().toULongLong(&ok); + const BreakpointId cid(idG.data().toInt(&ok)); if (ok) id = cid; } diff --git a/src/plugins/debugger/debugger.pro b/src/plugins/debugger/debugger.pro index 57e9586df88..68b5fcf7821 100644 --- a/src/plugins/debugger/debugger.pro +++ b/src/plugins/debugger/debugger.pro @@ -123,10 +123,11 @@ FORMS += attachexternaldialog.ui \ RESOURCES += debugger.qrc -false { +true { SOURCES += $$PWD/modeltest.cpp HEADERS += $$PWD/modeltest.h - DEFINES += USE_MODEL_TEST=1 + #DEFINES += USE_WATCH_MODEL_TEST=1 + #DEFINES += USE_BREAK_MODEL_TEST=1 } win32 { include(../../shared/registryaccess/registryaccess.pri) diff --git a/src/plugins/debugger/debuggerengine.cpp b/src/plugins/debugger/debuggerengine.cpp index 8120ed024b3..ed4c584e7b6 100644 --- a/src/plugins/debugger/debuggerengine.cpp +++ b/src/plugins/debugger/debuggerengine.cpp @@ -1497,7 +1497,7 @@ QString DebuggerEngine::msgWatchpointByExpressionTriggered(BreakpointId id, { return id ? tr("Data breakpoint %1 (%2) at %3 triggered.") - .arg(id).arg(number).arg(expr) + .arg(id.toString()).arg(number).arg(expr) : tr("Internal data breakpoint %1 at %2 triggered.") .arg(number).arg(expr); } @@ -1507,7 +1507,7 @@ QString DebuggerEngine::msgWatchpointByExpressionTriggered(BreakpointId id, { return id ? tr("Data breakpoint %1 (%2) at %3 in thread %4 triggered.") - .arg(id).arg(number).arg(expr).arg(threadId) + .arg(id.toString()).arg(number).arg(expr).arg(threadId) : tr("Internal data breakpoint %1 at %2 in thread %4 triggered.") .arg(number).arg(expr).arg(threadId); } @@ -1517,7 +1517,7 @@ QString DebuggerEngine::msgWatchpointByAddressTriggered(BreakpointId id, { return id ? tr("Data breakpoint %1 (%2) at 0x%3 triggered.") - .arg(id).arg(number).arg(address, 0, 16) + .arg(id.toString()).arg(number).arg(address, 0, 16) : tr("Internal data breakpoint %1 at 0x%2 triggered.") .arg(number).arg(address, 0, 16); } @@ -1527,9 +1527,9 @@ QString DebuggerEngine::msgWatchpointByAddressTriggered(BreakpointId id, { return id ? tr("Data breakpoint %1 (%2) at 0x%3 in thread %4 triggered.") - .arg(id).arg(number).arg(address, 0, 16).arg(threadId) + .arg(id.toString()).arg(number).arg(address, 0, 16).arg(threadId) : tr("Internal data breakpoint %1 at 0x%2 in thread %3 triggered.") - .arg(id).arg(number).arg(address, 0, 16).arg(threadId); + .arg(id.toString()).arg(number).arg(address, 0, 16).arg(threadId); } QString DebuggerEngine::msgBreakpointTriggered(BreakpointId id, @@ -1537,7 +1537,7 @@ QString DebuggerEngine::msgBreakpointTriggered(BreakpointId id, { return id ? tr("Stopped at breakpoint %1 (%2) in thread %3.") - .arg(id).arg(number).arg(threadId) + .arg(id.toString()).arg(number).arg(threadId) : tr("Stopped at internal breakpoint %1 in thread %2.") .arg(number).arg(threadId); } diff --git a/src/plugins/debugger/debuggerplugin.cpp b/src/plugins/debugger/debuggerplugin.cpp index 6347c1939ad..000e4fd0ee6 100644 --- a/src/plugins/debugger/debuggerplugin.cpp +++ b/src/plugins/debugger/debuggerplugin.cpp @@ -608,21 +608,24 @@ public slots: { const QAction *act = qobject_cast(sender()); QTC_ASSERT(act, return); - m_breakHandler->removeBreakpoint(act->data().toInt()); + BreakpointId id = act->data().value(); + m_breakHandler->removeBreakpoint(id); } void breakpointEnableMarginActionTriggered() { const QAction *act = qobject_cast(sender()); QTC_ASSERT(act, return); - breakHandler()->setEnabled(act->data().toInt(), true); + BreakpointId id = act->data().value(); + breakHandler()->setEnabled(id, true); } void breakpointDisableMarginActionTriggered() { const QAction *act = qobject_cast(sender()); QTC_ASSERT(act, return); - breakHandler()->setEnabled(act->data().toInt(), false); + BreakpointId id = act->data().value();; + breakHandler()->setEnabled(id, false); } void updateWatchersHeader(int section, int, int newSize) @@ -869,7 +872,7 @@ public slots: { const QAction *act = qobject_cast(sender()); QTC_ASSERT(act, return); - const BreakpointId id = act->data().toInt(); + const BreakpointId id = act->data().value(); QTC_ASSERT(id > 0, return); BreakWindow::editBreakpoint(id, mainWindow()); } @@ -1660,21 +1663,21 @@ void DebuggerPluginPrivate::requestContextMenu(ITextEditor *editor, if (id) { // Remove existing breakpoint. QAction *act = new QAction(menu); - act->setData(int(id)); - act->setText(tr("Remove Breakpoint %1").arg(id)); + act->setData(QVariant::fromValue(id)); + act->setText(tr("Remove Breakpoint %1").arg(id.toString())); connect(act, SIGNAL(triggered()), SLOT(breakpointRemoveMarginActionTriggered())); menu->addAction(act); // Enable/disable existing breakpoint. act = new QAction(menu); - act->setData(int(id)); + act->setData(QVariant::fromValue(id)); if (breakHandler()->isEnabled(id)) { - act->setText(tr("Disable Breakpoint %1").arg(id)); + act->setText(tr("Disable Breakpoint %1").arg(id.toString())); connect(act, SIGNAL(triggered()), SLOT(breakpointDisableMarginActionTriggered())); } else { - act->setText(tr("Enable Breakpoint %1").arg(id)); + act->setText(tr("Enable Breakpoint %1").arg(id.toString())); connect(act, SIGNAL(triggered()), SLOT(breakpointEnableMarginActionTriggered())); } @@ -1682,9 +1685,9 @@ void DebuggerPluginPrivate::requestContextMenu(ITextEditor *editor, // Edit existing breakpoint. act = new QAction(menu); - act->setText(tr("Edit Breakpoint %1...").arg(id)); + act->setText(tr("Edit Breakpoint %1...").arg(id.toString())); connect(act, SIGNAL(triggered()), SLOT(slotEditBreakpoint())); - act->setData(int(id)); + act->setData(QVariant::fromValue(id)); menu->addAction(act); } else { // Handle non-existing breakpoint. diff --git a/src/plugins/debugger/gdb/gdbengine.cpp b/src/plugins/debugger/gdb/gdbengine.cpp index 221fd66317b..2554124ee57 100644 --- a/src/plugins/debugger/gdb/gdbengine.cpp +++ b/src/plugins/debugger/gdb/gdbengine.cpp @@ -465,23 +465,58 @@ void GdbEngine::handleResponse(const QByteArray &buff) // line="1584",shlib="/../libFoo_debug.dylib",times="0"} const GdbMi bkpt = result.findChild("bkpt"); const int number = bkpt.findChild("number").data().toInt(); - if (!isQmlStepBreakpoint1(number) && isQmlStepBreakpoint2(number)) { - BreakpointId id = breakHandler()->findBreakpointByNumber(number); - updateBreakpointDataFromOutput(id, bkpt); + if (!isQmlStepBreakpoint(number)) { + BreakHandler *handler = breakHandler(); + BreakpointId id = handler->findBreakpointByNumber(number); + BreakpointResponse br = handler->response(id); + updateResponse(br, bkpt); + handler->setResponse(id, br); attemptAdjustBreakpointLocation(id); } } else if (asyncClass == "breakpoint-modified") { // New in FSF gdb since 2011-04-27. - // "{bkpt={number="2",type="breakpoint",disp="keep",enabled="y", - // addr="0x014e0e34",func="Myns::qFatal(char const*, ...)", - // file="global/qglobal.cpp",fullname="/data/dev/...cpp", - // line="2534",times="0",script={"return"}, - // original-location="'Myns::qFatal'"}}" - const GdbMi bkpt = result.findChild("bkpt"); - const int number = bkpt.findChild("number").data().toInt(); - if (!isQmlStepBreakpoint1(number) && isQmlStepBreakpoint2(number)) { - BreakpointId id = breakHandler()->findBreakpointByNumber(number); - updateBreakpointDataFromOutput(id, bkpt); + // "{bkpt={number="3",type="breakpoint",disp="keep", + // enabled="y",addr="",times="1", + // original-location="\\",simple_gdbtest_app.cpp\\":135"}, + // {number="3.1",enabled="y",addr="0x0805ff68", + // func="Vector::Vector(int)", + // file="simple_gdbtest_app.cpp", + // fullname="/data/...line="135"},{number="3.2"...}}" + + // Note the leading comma in original-location. Filter it out. + // We don't need the field anyway. + QByteArray ba = result.toString(); + ba = '[' + ba.mid(6, ba.size() - 7) + ']'; + const int pos1 = ba.indexOf(",original-location"); + const int pos2 = ba.indexOf("\":", pos1 + 2); + const int pos3 = ba.indexOf('"', pos2 + 2); + ba.replace(pos1, pos3 - pos1 + 1, ""); + result = GdbMi(); + result.fromString(ba); + BreakHandler *handler = breakHandler(); + BreakpointId id = BreakpointId(-1); + BreakpointResponse br; + foreach (const GdbMi &bkpt, result.children()) { + const QByteArray nr = bkpt.findChild("number").data(); + if (nr.contains(".")) { + // A sub-breakpoint. + int subNumber = nr.mid(nr.indexOf('.') + 1).toInt(); + BreakpointResponse sub; + updateResponse(sub, bkpt); + sub.number = br.number; + sub.type = br.type; + sub.subNumber = subNumber; + sub.extra.clear(); + handler->appendSubBreakpoint(id, sub); + } else { + // A primary breakpoint. + id = handler->findBreakpointByNumber(nr.toInt()); + br = handler->response(id); + updateResponse(br, bkpt); + } + } + if (!isQmlStepBreakpoint(br.number)) { + handler->setResponse(id, br); attemptAdjustBreakpointLocation(id); } m_hasBreakpointNotifications = true; @@ -666,7 +701,8 @@ void GdbEngine::readGdbStandardOutput() void GdbEngine::interruptInferior() { - QTC_ASSERT(state() == InferiorStopRequested, qDebug() << state(); return); + QTC_ASSERT(state() == InferiorStopRequested, + qDebug() << "INTERRUPT INFERIOR: " << state(); return); if (debuggerCore()->boolSetting(TargetAsync)) { postCommand("-exec-interrupt"); @@ -1252,8 +1288,7 @@ void GdbEngine::handleStopResponse(const GdbMi &data) fullName = QString::fromUtf8(frame.findChild("file").data()); if (bkptno && frame.isValid() - && !isQmlStepBreakpoint1(bkptno) - && !isQmlStepBreakpoint2(bkptno) + && !isQmlStepBreakpoint(bkptno) && !isQFatalBreakpoint(bkptno)) { // Use opportunity to update the breakpoint marker position. BreakHandler *handler = breakHandler(); @@ -1275,8 +1310,7 @@ void GdbEngine::handleStopResponse(const GdbMi &data) // Quickly set the location marker. if (lineNumber && !debuggerCore()->boolSetting(OperateByInstruction) && QFileInfo(fullName).exists() - && !isQmlStepBreakpoint1(bkptno) - && !isQmlStepBreakpoint2(bkptno) + && !isQmlStepBreakpoint(bkptno) && !isQFatalBreakpoint(bkptno)) gotoLocation(Location(fullName, lineNumber)); @@ -1663,6 +1697,11 @@ void GdbEngine::handleShowVersion(const GdbResponse &response) } } +void GdbEngine::handleListFeatures(const GdbResponse &response) +{ + showMessage(_("FEATURES: " + response.toString())); +} + void GdbEngine::handleHasPython(const GdbResponse &response) { if (response.resultClass == GdbResultDone) { @@ -2241,12 +2280,10 @@ void GdbEngine::setTokenBarrier() // ////////////////////////////////////////////////////////////////////// -void GdbEngine::updateBreakpointDataFromOutput(BreakpointId id, const GdbMi &bkpt) +void GdbEngine::updateResponse(BreakpointResponse &response, const GdbMi &bkpt) { QTC_ASSERT(bkpt.isValid(), return); - BreakpointResponse response = breakHandler()->response(id); - response.multiple = false; response.enabled = true; response.pending = false; @@ -2322,8 +2359,6 @@ void GdbEngine::updateBreakpointDataFromOutput(BreakpointId id, const GdbMi &bkp } if (!name.isEmpty()) response.fileName = name; - - breakHandler()->setResponse(id, response); } QString GdbEngine::breakLocation(const QString &file) const @@ -2374,21 +2409,21 @@ QByteArray GdbEngine::breakpointLocation2(BreakpointId id) void GdbEngine::handleWatchInsert(const GdbResponse &response) { - const int id = response.cookie.toInt(); + BreakpointId id = response.cookie.value(); if (response.resultClass == GdbResultDone) { BreakHandler *handler = breakHandler(); - BreakpointResponse bresponse = handler->response(id); + BreakpointResponse br = handler->response(id); // "Hardware watchpoint 2: *0xbfffed40\n" QByteArray ba = response.data.findChild("consolestreamoutput").data(); GdbMi wpt = response.data.findChild("wpt"); if (wpt.isValid()) { // Mac yields: //>32^done,wpt={number="4",exp="*4355182176"} - bresponse.number = wpt.findChild("number").data().toInt(); + br.number = wpt.findChild("number").data().toInt(); QByteArray exp = wpt.findChild("exp").data(); if (exp.startsWith('*')) - bresponse.address = exp.mid(1).toULongLong(0, 0); - handler->setResponse(id, bresponse); + br.address = exp.mid(1).toULongLong(0, 0); + handler->setResponse(id, br); QTC_ASSERT(!handler->needsChange(id), /**/); handler->notifyBreakpointInsertOk(id); } else if (ba.startsWith("Hardware watchpoint ") @@ -2397,10 +2432,10 @@ void GdbEngine::handleWatchInsert(const GdbResponse &response) const int end = ba.indexOf(':'); const int begin = ba.lastIndexOf(' ', end) + 1; const QByteArray address = ba.mid(end + 2).trimmed(); - bresponse.number = ba.mid(begin, end - begin).toInt(); + br.number = ba.mid(begin, end - begin).toInt(); if (address.startsWith('*')) - bresponse.address = address.mid(1).toULongLong(0, 0); - handler->setResponse(id, bresponse); + br.address = address.mid(1).toULongLong(0, 0); + handler->setResponse(id, br); QTC_ASSERT(!handler->needsChange(id), /**/); handler->notifyBreakpointInsertOk(id); } else { @@ -2423,13 +2458,13 @@ void GdbEngine::attemptAdjustBreakpointLocation(BreakpointId id) breakHandler()->setResponse(id, response); postCommand("info line *0x" + QByteArray::number(response.address, 16), NeedsStop | RebuildBreakpointModel, - CB(handleInfoLine), id); + CB(handleInfoLine), QVariant::fromValue(id)); } void GdbEngine::handleCatchInsert(const GdbResponse &response) { BreakHandler *handler = breakHandler(); - BreakpointId id(response.cookie.toInt()); + BreakpointId id = response.cookie.value(); if (response.resultClass == GdbResultDone) { handler->notifyBreakpointInsertOk(id); attemptAdjustBreakpointLocation(id); @@ -2439,21 +2474,23 @@ void GdbEngine::handleCatchInsert(const GdbResponse &response) void GdbEngine::handleBreakInsert1(const GdbResponse &response) { BreakHandler *handler = breakHandler(); - BreakpointId id(response.cookie.toInt()); + BreakpointId id = response.cookie.value(); if (response.resultClass == GdbResultDone) { // Interesting only on Mac? GdbMi bkpt = response.data.findChild("bkpt"); - updateBreakpointDataFromOutput(id, bkpt); + BreakpointResponse br = handler->response(id); + updateResponse(br, bkpt); + handler->setResponse(id, br); if (handler->needsChange(id)) { handler->notifyBreakpointChangeAfterInsertNeeded(id); changeBreakpoint(id); } else { handler->notifyBreakpointInsertOk(id); } - BreakpointResponse bresponse = handler->response(id); + br = handler->response(id); attemptAdjustBreakpointLocation(id); - if (bresponse.multiple && bresponse.addresses.isEmpty()) - postCommand("info break " + QByteArray::number(bresponse.number), + if (br.multiple && br.addresses.isEmpty()) + postCommand("info break " + QByteArray::number(br.number), NeedsStop, CB(handleBreakListMultiple), QVariant(id)); } else if (response.data.findChild("msg").data().contains("Unknown option")) { // Older version of gdb don't know the -a option to set tracepoints @@ -2463,22 +2500,24 @@ void GdbEngine::handleBreakInsert1(const GdbResponse &response) QByteArray cmd = "trace " "\"" + GdbMi::escapeCString(fileName).toLocal8Bit() + "\":" + QByteArray::number(lineNumber); + QVariant vid = QVariant::fromValue(id); postCommand(cmd, NeedsStop | RebuildBreakpointModel, - CB(handleTraceInsert2), id); + CB(handleTraceInsert2), vid); } else { // Some versions of gdb like "GNU gdb (GDB) SUSE (6.8.91.20090930-2.4)" // know how to do pending breakpoints using CLI but not MI. So try // again with MI. QByteArray cmd = "break " + breakpointLocation2(id); + QVariant vid = QVariant::fromValue(id); postCommand(cmd, NeedsStop | RebuildBreakpointModel, - CB(handleBreakInsert2), id); + CB(handleBreakInsert2), vid); } } void GdbEngine::handleBreakInsert2(const GdbResponse &response) { if (response.resultClass == GdbResultDone) { - BreakpointId id(response.cookie.toInt()); + BreakpointId id = response.cookie.value(); attemptAdjustBreakpointLocation(id); breakHandler()->notifyBreakpointInsertOk(id); } else { @@ -2541,6 +2580,7 @@ void GdbEngine::handleBreakList(const GdbMi &table) } } + BreakHandler *handler = breakHandler(); foreach (const GdbMi &bkpt, bkpts) { BreakpointResponse needle; needle.number = bkpt.findChild("number").data().toInt(); @@ -2548,14 +2588,17 @@ void GdbEngine::handleBreakList(const GdbMi &table) continue; if (isQFatalBreakpoint(needle.number)) continue; - BreakpointId id = breakHandler()->findSimilarBreakpoint(needle); - if (id != BreakpointId(-1)) { - updateBreakpointDataFromOutput(id, bkpt); + BreakpointId id = handler->findSimilarBreakpoint(needle); + if (id.isValid()) { + BreakpointResponse response = handler->response(id); + updateResponse(response, bkpt); + handler->setResponse(id, response); attemptAdjustBreakpointLocation(id); - BreakpointResponse response = breakHandler()->response(id); + response = handler->response(id); if (response.multiple && response.addresses.isEmpty()) postCommand("info break " + QByteArray::number(response.number), - NeedsStop, CB(handleBreakListMultiple), QVariant(id)); + NeedsStop, CB(handleBreakListMultiple), + QVariant::fromValue(id)); } else { qDebug() << " NOTHING SUITABLE FOUND"; showMessage(_("CANNOT FIND BP: " + bkpt.toString())); @@ -2568,7 +2611,7 @@ void GdbEngine::handleBreakList(const GdbMi &table) void GdbEngine::handleBreakListMultiple(const GdbResponse &response) { QTC_ASSERT(response.resultClass == GdbResultDone, /**/) - const BreakpointId id = response.cookie.toInt(); + const BreakpointId id = response.cookie.value(); const QString str = QString::fromLocal8Bit( response.data.findChild("consolestreamoutput").data()); extractDataFromInfoBreak(str, id); @@ -2577,7 +2620,7 @@ void GdbEngine::handleBreakListMultiple(const GdbResponse &response) void GdbEngine::handleBreakDisable(const GdbResponse &response) { QTC_ASSERT(response.resultClass == GdbResultDone, /**/) - const BreakpointId id = response.cookie.toInt(); + const BreakpointId id = response.cookie.value(); BreakHandler *handler = breakHandler(); // This should only be the requested state. QTC_ASSERT(!handler->isEnabled(id), /* Prevent later recursion */); @@ -2590,7 +2633,7 @@ void GdbEngine::handleBreakDisable(const GdbResponse &response) void GdbEngine::handleBreakEnable(const GdbResponse &response) { QTC_ASSERT(response.resultClass == GdbResultDone, /**/) - const BreakpointId id = response.cookie.toInt(); + const BreakpointId id = response.cookie.value(); BreakHandler *handler = breakHandler(); // This should only be the requested state. QTC_ASSERT(handler->isEnabled(id), /* Prevent later recursion */); @@ -2603,7 +2646,7 @@ void GdbEngine::handleBreakEnable(const GdbResponse &response) void GdbEngine::handleBreakThreadSpec(const GdbResponse &response) { QTC_ASSERT(response.resultClass == GdbResultDone, /**/) - const BreakpointId id = response.cookie.toInt(); + const BreakpointId id = response.cookie.value(); BreakHandler *handler = breakHandler(); BreakpointResponse br = handler->response(id); br.threadSpec = handler->threadSpec(id); @@ -2626,7 +2669,7 @@ void GdbEngine::handleBreakIgnore(const GdbResponse &response) // gdb 6.3 does not produce any console output QTC_ASSERT(response.resultClass == GdbResultDone, /**/) QString msg = _(response.data.findChild("consolestreamoutput").data()); - BreakpointId id = response.cookie.toInt(); + BreakpointId id = response.cookie.value(); BreakHandler *handler = breakHandler(); BreakpointResponse br = handler->response(id); //if (msg.contains(__("Will stop next time breakpoint"))) @@ -2645,7 +2688,7 @@ void GdbEngine::handleBreakCondition(const GdbResponse &response) { // Can happen at invalid condition strings. //QTC_ASSERT(response.resultClass == GdbResultDone, /**/) - const BreakpointId id = response.cookie.toInt(); + const BreakpointId id = response.cookie.value(); BreakHandler *handler = breakHandler(); // We just assume it was successful. Otherwise we had to parse // the output stream data. @@ -2723,7 +2766,7 @@ void GdbEngine::handleInfoLine(const GdbResponse &response) // at address 0x80526aa <_Z10...+131> and ends at 0x80526b5 // <_Z10testQStackv+142>.\n" QByteArray ba = response.data.findChild("consolestreamoutput").data(); - const BreakpointId id = response.cookie.toInt(); + const BreakpointId id = response.cookie.value(); const int pos = ba.indexOf(' ', 5); if (ba.startsWith("Line ") && pos != -1) { const int line = ba.mid(5, pos - 5).toInt(); @@ -2763,38 +2806,39 @@ void GdbEngine::insertBreakpoint(BreakpointId id) QTC_ASSERT(handler->state(id) == BreakpointInsertRequested, /**/); handler->notifyBreakpointInsertProceeding(id); BreakpointType type = handler->type(id); + QVariant vid = QVariant::fromValue(id); if (type == WatchpointAtAddress) { postCommand("watch " + addressSpec(handler->address(id)), NeedsStop | RebuildBreakpointModel, - CB(handleWatchInsert), id); + CB(handleWatchInsert), vid); return; } if (type == WatchpointAtExpression) { postCommand("watch " + handler->expression(id).toLocal8Bit(), NeedsStop | RebuildBreakpointModel, - CB(handleWatchInsert), id); + CB(handleWatchInsert), vid); return; } if (type == BreakpointAtFork) { postCommand("catch fork", NeedsStop | RebuildBreakpointModel, - CB(handleCatchInsert), id); + CB(handleCatchInsert), vid); postCommand("catch vfork", NeedsStop | RebuildBreakpointModel, - CB(handleCatchInsert), id); + CB(handleCatchInsert), vid); return; } //if (type == BreakpointAtVFork) { // postCommand("catch vfork", NeedsStop | RebuildBreakpointModel, - // CB(handleCatchInsert), id); + // CB(handleCatchInsert), vid); // return; //} if (type == BreakpointAtExec) { postCommand("catch exec", NeedsStop | RebuildBreakpointModel, - CB(handleCatchInsert), id); + CB(handleCatchInsert), vid); return; } if (type == BreakpointAtSysCall) { postCommand("catch syscall", NeedsStop | RebuildBreakpointModel, - CB(handleCatchInsert), id); + CB(handleCatchInsert), vid); return; } @@ -2821,7 +2865,7 @@ void GdbEngine::insertBreakpoint(BreakpointId id) // cmd += "-c " + data->condition + ' '; cmd += breakpointLocation(id); postCommand(cmd, NeedsStop | RebuildBreakpointModel, - CB(handleBreakInsert1), id); + CB(handleBreakInsert1), vid); } void GdbEngine::changeBreakpoint(BreakpointId id) @@ -2838,12 +2882,13 @@ void GdbEngine::changeBreakpoint(BreakpointId id) handler->notifyBreakpointChangeProceeding(id); const BreakpointState state2 = handler->state(id); QTC_ASSERT(state2 == BreakpointChangeProceeding, qDebug() << state2); + QVariant vid = QVariant::fromValue(id); if (data.threadSpec != response.threadSpec) { // The only way to change this seems to be to re-set the bp completely. postCommand("-break-delete " + bpnr, NeedsStop | RebuildBreakpointModel, - CB(handleBreakThreadSpec), id); + CB(handleBreakThreadSpec), vid); return; } if (data.command != response.command) { @@ -2856,31 +2901,31 @@ void GdbEngine::changeBreakpoint(BreakpointId id) } } postCommand(breakCommand, NeedsStop | RebuildBreakpointModel, - CB(handleBreakIgnore), id); + CB(handleBreakIgnore), vid); return; } if (!data.conditionsMatch(response.condition)) { postCommand("condition " + bpnr + ' ' + data.condition, NeedsStop | RebuildBreakpointModel, - CB(handleBreakCondition), id); + CB(handleBreakCondition), vid); return; } if (data.ignoreCount != response.ignoreCount) { postCommand("ignore " + bpnr + ' ' + QByteArray::number(data.ignoreCount), NeedsStop | RebuildBreakpointModel, - CB(handleBreakIgnore), id); + CB(handleBreakIgnore), vid); return; } if (!data.enabled && response.enabled) { postCommand("-break-disable " + bpnr, NeedsStop | RebuildBreakpointModel, - CB(handleBreakDisable), id); + CB(handleBreakDisable), vid); return; } if (data.enabled && !response.enabled) { postCommand("-break-enable " + bpnr, NeedsStop | RebuildBreakpointModel, - CB(handleBreakEnable), id); + CB(handleBreakEnable), vid); return; } handler->notifyBreakpointChangeOk(id); @@ -4475,6 +4520,7 @@ bool GdbEngine::startGdb(const QStringList &args, const QString &settingsIdHint) showMessage(_("GDB STARTED, INITIALIZING IT")); postCommand("show version", CB(handleShowVersion)); + postCommand("-list-features", CB(handleListFeatures)); //postCommand("-enable-timings"); //postCommand("set print static-members off"); // Seemingly doesn't work. @@ -4895,6 +4941,11 @@ void GdbEngine::handleSetQmlStepBreakpoint(const GdbResponse &response) masterEngine()->readyToExecuteQmlStep(); } +bool GdbEngine::isQmlStepBreakpoint(int bpnr) const +{ + return isQmlStepBreakpoint1(bpnr) || isQmlStepBreakpoint2(bpnr); +} + bool GdbEngine::isQmlStepBreakpoint1(int bpnr) const { //qDebug() << "CHECK 1: " << m_qmlBreakpointNumbers[1] << bpnr; diff --git a/src/plugins/debugger/gdb/gdbengine.h b/src/plugins/debugger/gdb/gdbengine.h index d4aa4c07e4b..0201b99226b 100644 --- a/src/plugins/debugger/gdb/gdbengine.h +++ b/src/plugins/debugger/gdb/gdbengine.h @@ -435,6 +435,7 @@ private: ////////// Gdb Output, State & Capability Handling ////////// // Gdb initialization sequence void handleShowVersion(const GdbResponse &response); + void handleListFeatures(const GdbResponse &response); void handleHasPython(const GdbResponse &response); int m_gdbVersion; // 6.8.0 is 60800 @@ -506,7 +507,7 @@ private: ////////// View & Data Stuff ////////// void handleCatchInsert(const GdbResponse &response); void handleInfoLine(const GdbResponse &response); void extractDataFromInfoBreak(const QString &output, BreakpointId); - void updateBreakpointDataFromOutput(BreakpointId id, const GdbMi &bkpt); + void updateResponse(BreakpointResponse &response, const GdbMi &bkpt); QByteArray breakpointLocation(BreakpointId id); // For gdb/MI. QByteArray breakpointLocation2(BreakpointId id); // For gdb/CLI fallback. QString breakLocation(const QString &file) const; @@ -721,6 +722,7 @@ private: ////////// View & Data Stuff ////////// bool m_preparedForQmlBreak; bool setupQmlStep(bool on); void handleSetQmlStepBreakpoint(const GdbResponse &response); + bool isQmlStepBreakpoint(int bpnr) const; bool isQmlStepBreakpoint1(int bpnr) const; bool isQmlStepBreakpoint2(int bpnr) const; bool isQFatalBreakpoint(int bpnr) const; diff --git a/src/plugins/debugger/lldb/ipcenginehost.cpp b/src/plugins/debugger/lldb/ipcenginehost.cpp index e7a50f3efec..5e35d2511e2 100644 --- a/src/plugins/debugger/lldb/ipcenginehost.cpp +++ b/src/plugins/debugger/lldb/ipcenginehost.cpp @@ -506,8 +506,9 @@ void IPCEngineHost::rpcCallback(quint64 f, QByteArray payload) attemptBreakpointSynchronization(); QDataStream s(payload); SET_NATIVE_BYTE_ORDER(s); - BreakpointId id; - s >> id; + quint64 d; + s >> d; + BreakpointId id = BreakpointId::fromInternalId(d); breakHandler()->notifyBreakpointInsertOk(id); } break; @@ -515,8 +516,9 @@ void IPCEngineHost::rpcCallback(quint64 f, QByteArray payload) { QDataStream s(payload); SET_NATIVE_BYTE_ORDER(s); - BreakpointId id; - s >> id; + quint64 d; + s >> d; + BreakpointId id = BreakpointId::fromInternalId(d); breakHandler()->notifyBreakpointInsertFailed(id); } break; @@ -524,8 +526,9 @@ void IPCEngineHost::rpcCallback(quint64 f, QByteArray payload) { QDataStream s(payload); SET_NATIVE_BYTE_ORDER(s); - BreakpointId id; - s >> id; + quint64 d; + s >> d; + BreakpointId id = BreakpointId::fromInternalId(d); breakHandler()->notifyBreakpointRemoveOk(id); } break; @@ -533,8 +536,9 @@ void IPCEngineHost::rpcCallback(quint64 f, QByteArray payload) { QDataStream s(payload); SET_NATIVE_BYTE_ORDER(s); - BreakpointId id; - s >> id; + quint64 d; + s >> d; + BreakpointId id = BreakpointId::fromInternalId(d); breakHandler()->notifyBreakpointRemoveFailed(id); } break; @@ -542,8 +546,9 @@ void IPCEngineHost::rpcCallback(quint64 f, QByteArray payload) { QDataStream s(payload); SET_NATIVE_BYTE_ORDER(s); - BreakpointId id; - s >> id; + quint64 d; + s >> d; + BreakpointId id = BreakpointId::fromInternalId(d); breakHandler()->notifyBreakpointChangeOk(id); } break; @@ -551,8 +556,9 @@ void IPCEngineHost::rpcCallback(quint64 f, QByteArray payload) { QDataStream s(payload); SET_NATIVE_BYTE_ORDER(s); - BreakpointId id; - s >> id; + quint64 d; + s >> d; + BreakpointId id = BreakpointId::fromInternalId(d); breakHandler()->notifyBreakpointChangeFailed(id); } break; @@ -560,9 +566,10 @@ void IPCEngineHost::rpcCallback(quint64 f, QByteArray payload) { QDataStream s(payload); SET_NATIVE_BYTE_ORDER(s); - BreakpointId id; + quint64 dd; BreakpointParameters d; - s >> id >> d; + s >> dd >> d; + BreakpointId id = BreakpointId::fromInternalId(dd); breakHandler()->notifyBreakpointAdjusted(id, d); } break; diff --git a/src/plugins/debugger/watchhandler.cpp b/src/plugins/debugger/watchhandler.cpp index 6f5eb097a97..f23aad883e9 100644 --- a/src/plugins/debugger/watchhandler.cpp +++ b/src/plugins/debugger/watchhandler.cpp @@ -39,7 +39,7 @@ #include "debuggerengine.h" #include "watchutils.h" -#if USE_MODEL_TEST +#if USE_WATCH_MODEL_TEST #include "modeltest.h" #endif @@ -216,8 +216,8 @@ void WatchModel::removeOutdated() foreach (WatchItem *child, m_root->children) removeOutdatedHelper(child); #if DEBUG_MODEL -#if USE_MODEL_TEST - //(void) new ModelTest(this, this); +#if USE_WATCH_MODEL_TEST + (void) new ModelTest(this, this); #endif #endif }