diff --git a/src/plugins/debugger/breakhandler.cpp b/src/plugins/debugger/breakhandler.cpp index 6bfce8ea939c22d731e8f46c93532b27fd81b716..bfcd8cb9defd3ba6a87f8a0b330b807bf0d957f7 100644 --- a/src/plugins/debugger/breakhandler.cpp +++ b/src/plugins/debugger/breakhandler.cpp @@ -267,6 +267,8 @@ void BreakHandler::saveBreakpoints() map.insert(_("disabled"), _("1")); if (data.useFullPath) map.insert(_("usefullpath"), _("1")); + if (data.tracepoint) + map.insert(_("tracepoint"), _("1")); list.append(map); } debuggerCore()->setSessionValue("Breakpoints", list); @@ -310,6 +312,9 @@ void BreakHandler::loadBreakpoints() v = map.value(_("usefullpath")); if (v.isValid()) data.useFullPath = bool(v.toInt()); + v = map.value(_("tracepoint")); + if (v.isValid()) + data.tracepoint = bool(v.toInt()); v = map.value(_("type")); if (v.isValid() && v.toInt() != UnknownType) data.type = BreakpointType(v.toInt()); @@ -582,6 +587,26 @@ void BreakHandler::setEnabled(BreakpointId id, bool on) scheduleSynchronization(); } +bool BreakHandler::isTracepoint(BreakpointId id) const +{ + ConstIterator it = m_storage.find(id); + QTC_ASSERT(it != m_storage.end(), return false); + return it->data.tracepoint; +} + +void BreakHandler::setTracepoint(BreakpointId id, bool on) +{ + Iterator it = m_storage.find(id); + QTC_ASSERT(it != m_storage.end(), return); + if (it->data.tracepoint == on) + return; + it->data.tracepoint = on; + it->destroyMarker(); + it->state = BreakpointChangeRequested; + updateMarker(id); + scheduleSynchronization(); +} + void BreakHandler::setMarkerFileAndLine(BreakpointId id, const QString &fileName, int lineNumber) { diff --git a/src/plugins/debugger/breakhandler.h b/src/plugins/debugger/breakhandler.h index d8395992802f3d1818296a9362f12411a63d1701..d4349057b23f1ed97395560f60def6432a4da877 100644 --- a/src/plugins/debugger/breakhandler.h +++ b/src/plugins/debugger/breakhandler.h @@ -127,6 +127,8 @@ public: void updateLineNumberFromMarker(BreakpointId id, int lineNumber); void setMarkerFileAndLine(BreakpointId id, const QString &fileName, int lineNumber); + bool isTracepoint(BreakpointId id) const; + void setTracepoint(BreakpointId, bool on); DebuggerEngine *engine(BreakpointId id) const; void setEngine(BreakpointId id, DebuggerEngine *engine); const BreakpointResponse &response(BreakpointId id) const; diff --git a/src/plugins/debugger/debuggerstreamops.cpp b/src/plugins/debugger/debuggerstreamops.cpp index 067eab308a19d79668e28cc0ec44da0f7f84c07a..7dff5b22bffef6943f46c004ebe2407ec4692a5a 100644 --- a/src/plugins/debugger/debuggerstreamops.cpp +++ b/src/plugins/debugger/debuggerstreamops.cpp @@ -175,6 +175,7 @@ QDataStream &operator<<(QDataStream &stream, const BreakpointParameters &s) stream << quint64(s.address); stream << s.functionName; stream << s.useFullPath; + stream << s.tracepoint; return stream; } @@ -191,6 +192,7 @@ QDataStream &operator>>(QDataStream &stream, BreakpointParameters &s) stream >> t; s.address = t; stream >> str; s.functionName = str; stream >> b; s.useFullPath = b; + stream >> b; s.tracepoint = b; return stream; } diff --git a/src/plugins/debugger/gdb/gdbengine.cpp b/src/plugins/debugger/gdb/gdbengine.cpp index 27291930639524fb5b670590e039eef2ddffbd23..a26cd9bbc6eddf792240f8a89398c4b0a37b36ed 100644 --- a/src/plugins/debugger/gdb/gdbengine.cpp +++ b/src/plugins/debugger/gdb/gdbengine.cpp @@ -2068,7 +2068,10 @@ void GdbEngine::updateBreakpointDataFromOutput(BreakpointId id, const GdbMi &bkp } else if (child.hasName("thread")) { response.threadSpec = child.data().toInt(); } else if (child.hasName("type")) { - if (!child.data().contains("reakpoint")) // "breakpoint", "hw breakpoint" + // "breakpoint", "hw breakpoint", "tracepoint" + if (child.data().contains("tracepoint")) + response.tracepoint = true; + else if (!child.data().contains("reakpoint")) response.type = Watchpoint; } // This field is not present. Contents needs to be parsed from @@ -2179,12 +2182,12 @@ void GdbEngine::attemptAdjustBreakpointLocation(BreakpointId id) void GdbEngine::handleBreakInsert1(const GdbResponse &response) { + BreakHandler *handler = breakHandler(); BreakpointId id(response.cookie.toInt()); if (response.resultClass == GdbResultDone) { // Interesting only on Mac? GdbMi bkpt = response.data.findChild("bkpt"); updateBreakpointDataFromOutput(id, bkpt); - BreakHandler *handler = breakHandler(); if (handler->needsChange(id)) { handler->notifyBreakpointChangeAfterInsertNeeded(id); changeBreakpoint(id); @@ -2192,6 +2195,16 @@ void GdbEngine::handleBreakInsert1(const GdbResponse &response) handler->notifyBreakpointInsertOk(id); attemptAdjustBreakpointLocation(id); } + } else if (response.data.findChild("msg").data().contains("Unknown option")) { + // Older version of gdb don't know the -a option to set tracepoints + // ^error,msg="mi_cmd_break_insert: Unknown option ``a''" + const QString fileName = handler->fileName(id); + const int lineNumber = handler->lineNumber(id); + QByteArray cmd = "trace " + "\"" + GdbMi::escapeCString(fileName).toLocal8Bit() + "\":" + + QByteArray::number(lineNumber); + postCommand(cmd, NeedsStop | RebuildBreakpointModel, + CB(handleTraceInsert2), id); } 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 @@ -2216,6 +2229,12 @@ void GdbEngine::handleBreakInsert2(const GdbResponse &response) } } +void GdbEngine::handleTraceInsert2(const GdbResponse &response) +{ + if (response.resultClass == GdbResultDone) + reloadBreakListInternal(); +} + void GdbEngine::reloadBreakListInternal() { postCommand("-break-list", @@ -2479,7 +2498,9 @@ void GdbEngine::insertBreakpoint(BreakpointId id) } QByteArray cmd; - if (m_isMacGdb) { + if (handler->isTracepoint(id)) { + cmd = "-break-insert -a -f "; + } else if (m_isMacGdb) { cmd = "-break-insert -l -1 -f "; } else if (m_gdbAdapter->isTrkAdapter()) { cmd = "-break-insert -h -f "; diff --git a/src/plugins/debugger/gdb/gdbengine.h b/src/plugins/debugger/gdb/gdbengine.h index 97239fb4f9d922f6adf1b857ff0fa37edce29166..1dc37f82d0edfa82972937aabdf8e94d4219ba6e 100644 --- a/src/plugins/debugger/gdb/gdbengine.h +++ b/src/plugins/debugger/gdb/gdbengine.h @@ -354,6 +354,7 @@ private: ////////// View & Data Stuff ////////// void handleBreakEnable(const GdbResponse &response); void handleBreakInsert1(const GdbResponse &response); void handleBreakInsert2(const GdbResponse &response); + void handleTraceInsert2(const GdbResponse &response); void handleBreakCondition(const GdbResponse &response); void handleBreakInfo(const GdbResponse &response); void handleBreakThreadSpec(const GdbResponse &response);