diff --git a/src/plugins/debugger/breakhandler.cpp b/src/plugins/debugger/breakhandler.cpp index 81109826f48..994f86f925b 100644 --- a/src/plugins/debugger/breakhandler.cpp +++ b/src/plugins/debugger/breakhandler.cpp @@ -1249,17 +1249,27 @@ QString BreakHandler::BreakpointItem::toToolTip() const formatAddress(str, data.address); str << ""; formatAddress(str, response.address); + str << ""; + if (response.multiple) { + str << "" << tr("Multiple Addresses:") + << ""; + foreach (quint64 address, response.addresses) { + formatAddress(str, data.address); + str << " "; + } + str << ""; + } if (!data.command.isEmpty() || !response.command.isEmpty()) { - str << "" - << "" << tr("Command:") + str << "" << tr("Command:") << "" << data.command - << "" << response.command<< ""; + << "" << response.command + << ""; } if (!data.condition.isEmpty() || !response.condition.isEmpty()) { - str << "" - << "" << tr("Condition:") + str << "" << tr("Condition:") << "" << data.condition - << "" << response.condition << ""; + << "" << response.condition + << ""; } if (data.ignoreCount || response.ignoreCount) { str << "" << tr("Ignore Count:") << ""; @@ -1268,10 +1278,10 @@ QString BreakHandler::BreakpointItem::toToolTip() const str << ""; if (response.ignoreCount) str << response.ignoreCount; + str << ""; } if (data.threadSpec >= 0 || response.threadSpec >= 0) { - str << "" - << "" << tr("Thread Specification:") + str << "" << tr("Thread Specification:") << ""; if (data.threadSpec >= 0) str << data.threadSpec; diff --git a/src/plugins/debugger/breakpoint.h b/src/plugins/debugger/breakpoint.h index 92af630ea99..a6513b81a3f 100644 --- a/src/plugins/debugger/breakpoint.h +++ b/src/plugins/debugger/breakpoint.h @@ -131,7 +131,8 @@ public: QString fullName; //!< Full file name acknowledged by the debugger engine. bool multiple; //!< Happens in constructors/gdb. QByteArray extra; //!< gdb: , - int correctedLineNumber; + QList addresses;//!< Extra addresses for templated code. + int correctedLineNumber; //!< Line number as seen by gdb. }; typedef QList BreakpointIds; diff --git a/src/plugins/debugger/gdb/gdbengine.cpp b/src/plugins/debugger/gdb/gdbengine.cpp index 2b04903d9f6..de42119ad5d 100644 --- a/src/plugins/debugger/gdb/gdbengine.cpp +++ b/src/plugins/debugger/gdb/gdbengine.cpp @@ -475,6 +475,9 @@ void GdbEngine::handleResponse(const QByteArray &buff) if (!isQmlStepBreakpoint1(number) && isQmlStepBreakpoint2(number)) { BreakpointId id = breakHandler()->findBreakpointByNumber(number); updateBreakpointDataFromOutput(id, bkpt); + BreakpointResponse response = breakHandler()->response(id); + if (response.correctedLineNumber == 0) + attemptAdjustBreakpointLocation(id); } } else { qDebug() << "IGNORED ASYNC OUTPUT" @@ -2155,8 +2158,11 @@ void GdbEngine::updateBreakpointDataFromOutput(BreakpointId id, const GdbMi &bkp } else if (child.hasName("func")) { response.functionName = _(child.data()); } else if (child.hasName("addr")) { - // happens in constructors. In this case there are - // _two_ fields named "addr" in the response. On Linux that is... + // happens in constructors, inline functions, and + // at other places like 'foreach' lines. In this case there are + // fields named "addr" in the response and/or the address + // is called . + //qDebug() << "ADDR: " << child.data() << (child.data() == ""); if (child.data().startsWith("0x")) { response.address = child.data().mid(2).toULongLong(0, 16); } else { @@ -2404,6 +2410,12 @@ void GdbEngine::handleBreakList(const GdbMi &table) BreakpointId id = breakHandler()->findSimilarBreakpoint(needle); if (id != BreakpointId(-1)) { updateBreakpointDataFromOutput(id, bkpt); + BreakpointResponse response = breakHandler()->response(id); + if (response.correctedLineNumber == 0) + attemptAdjustBreakpointLocation(id); + if (response.multiple && response.addresses.isEmpty()) + postCommand("info break " + QByteArray::number(response.number), + NeedsStop, CB(handleBreakListMultiple), QVariant(id)); } else { qDebug() << " NOTHING SUITABLE FOUND"; showMessage(_("CANNOT FIND BP: " + bkpt.toString())); @@ -2413,6 +2425,16 @@ void GdbEngine::handleBreakList(const GdbMi &table) m_breakListOutdated = false; } +void GdbEngine::handleBreakListMultiple(const GdbResponse &response) +{ + QTC_ASSERT(response.resultClass == GdbResultDone, /**/) + const BreakpointId id = response.cookie.toInt(); + BreakHandler *handler = breakHandler(); + BreakpointResponse br = handler->response(id); + br.addresses.append(0); + handler->setResponse(id, br); +} + void GdbEngine::handleBreakDisable(const GdbResponse &response) { QTC_ASSERT(response.resultClass == GdbResultDone, /**/) diff --git a/src/plugins/debugger/gdb/gdbengine.h b/src/plugins/debugger/gdb/gdbengine.h index 999a32bc873..e1f031ce92a 100644 --- a/src/plugins/debugger/gdb/gdbengine.h +++ b/src/plugins/debugger/gdb/gdbengine.h @@ -359,6 +359,7 @@ private: ////////// View & Data Stuff ////////// // void handleBreakList(const GdbResponse &response); void handleBreakList(const GdbMi &table); + void handleBreakListMultiple(const GdbResponse &response); void handleBreakIgnore(const GdbResponse &response); void handleBreakDisable(const GdbResponse &response); void handleBreakEnable(const GdbResponse &response);