Debugger: Improve lldb breakpoint handling

Inform QC about changed breakpoints on the LLDB side.

Fixes: QTCREATORBUG-21997
Change-Id: Icec25725f92d8a0b47f7dab2971c0c5eb5b23757
Reviewed-by: hjk <hjk@qt.io>
This commit is contained in:
Christian Stenger
2019-03-01 14:58:57 +01:00
parent 4a3d6f4694
commit 31e549a7dc
3 changed files with 52 additions and 0 deletions

View File

@@ -957,6 +957,12 @@ class Dumper(DumperBase):
return return
self.report('pid="%s"' % self.process.GetProcessID()) self.report('pid="%s"' % self.process.GetProcessID())
self.reportState('enginerunandinferiorrunok') 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): def loop(self):
event = lldb.SBEvent() event = lldb.SBEvent()
@@ -1116,6 +1122,11 @@ class Dumper(DumperBase):
# logview pane feature. # logview pane feature.
self.report('token(\"%s\")' % args["token"]) self.report('token(\"%s\")' % args["token"])
def reportBreakpointUpdate(self, bp):
self.report('breakpointmodified={%s}' % self.describeBreakpoint(bp))
def readRawMemory(self, address, size): def readRawMemory(self, address, size):
if size == 0: if size == 0:
return bytes() return bytes()
@@ -1288,7 +1299,20 @@ class Dumper(DumperBase):
self.process.Kill() self.process.Kill()
self.reportResult('', args) 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): def handleEvent(self, event):
if lldb.SBBreakpoint.EventIsBreakpointEvent(event):
self.handleBreakpointEvent(event)
return
out = lldb.SBStream() out = lldb.SBStream()
event.GetDescription(out) event.GetDescription(out)
#warn("EVENT: %s" % event) #warn("EVENT: %s" % event)

View File

@@ -395,6 +395,8 @@ void LldbEngine::handleResponse(const QString &response)
handleOutputNotification(item); handleOutputNotification(item);
else if (name == "pid") else if (name == "pid")
notifyInferiorPid(item.toProcessHandle()); notifyInferiorPid(item.toProcessHandle());
else if (name == "breakpointmodified")
handleInterpreterBreakpointModified(item);
} }
} }
@@ -607,6 +609,31 @@ void LldbEngine::handleOutputNotification(const GdbMi &output)
showMessage(data, ch); 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) void LldbEngine::loadSymbols(const QString &moduleName)
{ {
Q_UNUSED(moduleName) Q_UNUSED(moduleName)

View File

@@ -120,6 +120,7 @@ private:
void handleStateNotification(const GdbMi &item); void handleStateNotification(const GdbMi &item);
void handleLocationNotification(const GdbMi &location); void handleLocationNotification(const GdbMi &location);
void handleOutputNotification(const GdbMi &output); void handleOutputNotification(const GdbMi &output);
void handleInterpreterBreakpointModified(const GdbMi &item);
void handleResponse(const QString &data); void handleResponse(const QString &data);
void updateAll() override; void updateAll() override;