diff --git a/share/qtcreator/debugger/lldbbridge.py b/share/qtcreator/debugger/lldbbridge.py index a961569cd03..cf19c1eac83 100644 --- a/share/qtcreator/debugger/lldbbridge.py +++ b/share/qtcreator/debugger/lldbbridge.py @@ -957,6 +957,12 @@ class Dumper(DumperBase): return self.report('pid="%s"' % self.process.GetProcessID()) self.reportState('enginerunandinferiorrunok') + if self.target is not None: + broadcaster = self.target.GetBroadcaster() + listener = self.debugger.GetListener() + broadcaster.AddListener(listener, lldb.SBTarget.eBroadcastBitBreakpointChanged) + listener.StartListeningForEvents(broadcaster, lldb.SBTarget.eBroadcastBitBreakpointChanged) + def loop(self): event = lldb.SBEvent() @@ -1116,6 +1122,11 @@ class Dumper(DumperBase): # logview pane feature. self.report('token(\"%s\")' % args["token"]) + + def reportBreakpointUpdate(self, bp): + self.report('breakpointmodified={%s}' % self.describeBreakpoint(bp)) + + def readRawMemory(self, address, size): if size == 0: return bytes() @@ -1288,7 +1299,20 @@ class Dumper(DumperBase): self.process.Kill() self.reportResult('', args) + + def handleBreakpointEvent(self, event): + eventType = lldb.SBBreakpoint.GetBreakpointEventTypeFromEvent(event) + # handle only the resolved locations for now.. + if eventType & lldb.eBreakpointEventTypeLocationsResolved: + bp = lldb.SBBreakpoint.GetBreakpointFromEvent(event) + if bp is not None: + self.reportBreakpointUpdate(bp) + + def handleEvent(self, event): + if lldb.SBBreakpoint.EventIsBreakpointEvent(event): + self.handleBreakpointEvent(event) + return out = lldb.SBStream() event.GetDescription(out) #warn("EVENT: %s" % event) diff --git a/src/plugins/debugger/lldb/lldbengine.cpp b/src/plugins/debugger/lldb/lldbengine.cpp index 0dee8826a7f..f91240bb939 100644 --- a/src/plugins/debugger/lldb/lldbengine.cpp +++ b/src/plugins/debugger/lldb/lldbengine.cpp @@ -395,6 +395,8 @@ void LldbEngine::handleResponse(const QString &response) handleOutputNotification(item); else if (name == "pid") notifyInferiorPid(item.toProcessHandle()); + else if (name == "breakpointmodified") + handleInterpreterBreakpointModified(item); } } @@ -607,6 +609,31 @@ void LldbEngine::handleOutputNotification(const GdbMi &output) showMessage(data, ch); } +void LldbEngine::handleInterpreterBreakpointModified(const GdbMi &bpItem) +{ + QTC_ASSERT(bpItem.childCount(), return); + QString id = bpItem.childAt(0).m_data; + + Breakpoint bp = breakHandler()->findBreakpointByResponseId(id); + if (!bp) // FIXME adapt whole bp handling and turn into soft assert + return; + + // this function got triggered by a lldb internal breakpoint event + // avoid asserts regarding unexpected state transitions + switch (bp->state()) { + case BreakpointInsertionRequested: // was a pending bp + bp->gotoState(BreakpointInsertionProceeding, BreakpointInsertionRequested); + break; + case BreakpointInserted: // was an inserted, gets updated now + bp->gotoState(BreakpointUpdateRequested, BreakpointInserted); + notifyBreakpointChangeProceeding(bp); + break; + default: + break; + } + updateBreakpointData(bp, bpItem, false); +} + void LldbEngine::loadSymbols(const QString &moduleName) { Q_UNUSED(moduleName) diff --git a/src/plugins/debugger/lldb/lldbengine.h b/src/plugins/debugger/lldb/lldbengine.h index f06798dd392..6c5b3c2c21c 100644 --- a/src/plugins/debugger/lldb/lldbengine.h +++ b/src/plugins/debugger/lldb/lldbengine.h @@ -120,6 +120,7 @@ private: void handleStateNotification(const GdbMi &item); void handleLocationNotification(const GdbMi &location); void handleOutputNotification(const GdbMi &output); + void handleInterpreterBreakpointModified(const GdbMi &item); void handleResponse(const QString &data); void updateAll() override;