GP-0: Fix timing issue in breakpoint service

This commit is contained in:
Dan 2022-03-31 15:35:46 -04:00
parent 0bfb9ae84a
commit 65a7105cbf
4 changed files with 38 additions and 6 deletions

View file

@ -231,6 +231,10 @@ public class DebuggerLogicalBreakpointServicePlugin extends Plugin
info.trackTraceBreakpoint(breakpoint, c, false);
}
}
catch (TrackedTooSoonException e) {
Msg.info(this, "Ignoring " + breakpoint +
" added until service has finished loading its trace");
}
}
private void breakpointChanged(TraceBreakpoint breakpoint) {
@ -242,6 +246,10 @@ public class DebuggerLogicalBreakpointServicePlugin extends Plugin
info.trackTraceBreakpoint(breakpoint, c, true);
}
}
catch (TrackedTooSoonException e) {
Msg.info(this, "Ignoring " + breakpoint +
" changed until service has finished loading its trace");
}
}
private void breakpointLifespanChanged(TraceAddressSpace spaceIsNull,
@ -266,6 +274,10 @@ public class DebuggerLogicalBreakpointServicePlugin extends Plugin
info.trackTraceBreakpoint(breakpoint, c, false);
}
}
catch (TrackedTooSoonException e) {
Msg.info(this, "Ignoring " + breakpoint +
" span changed until service has finished loading its trace");
}
}
}
@ -362,7 +374,7 @@ public class DebuggerLogicalBreakpointServicePlugin extends Plugin
long length, Collection<TraceBreakpointKind> kinds);
protected LogicalBreakpointInternal getOrCreateLogicalBreakpointFor(Address address,
TraceBreakpoint breakpoint, AddCollector c) {
TraceBreakpoint breakpoint, AddCollector c) throws TrackedTooSoonException {
Set<LogicalBreakpointInternal> set =
breakpointsByAddress.computeIfAbsent(address, a -> new HashSet<>());
for (LogicalBreakpointInternal lb : set) {
@ -543,7 +555,12 @@ public class DebuggerLogicalBreakpointServicePlugin extends Plugin
protected void trackTraceBreakpoints(Collection<TraceBreakpoint> breakpoints,
AddCollector collector) {
for (TraceBreakpoint b : breakpoints) {
trackTraceBreakpoint(b, collector, false);
try {
trackTraceBreakpoint(b, collector, false);
}
catch (TrackedTooSoonException e) {
throw new AssertionError(e);
}
}
}
@ -562,7 +579,7 @@ public class DebuggerLogicalBreakpointServicePlugin extends Plugin
}
protected void trackTraceBreakpoint(TraceBreakpoint breakpoint, AddCollector c,
boolean forceUpdate) {
boolean forceUpdate) throws TrackedTooSoonException {
Address traceAddr = breakpoint.getMinAddress();
ProgramLocation progLoc = computeStaticLocation(breakpoint);
LogicalBreakpointInternal lb;

View file

@ -451,6 +451,7 @@ public interface LogicalBreakpointInternal extends LogicalBreakpoint {
/**
* Check if this logical breakpoint can subsume the given candidate trace breakpoint
*
* <p>
* Note that logical breakpoints only include trace breakpoints for traces being actively
* recorded. All statuses regarding trace breakpoints are derived from the target breakpoints,
* i.e., they show the present status, regardless of the view's current time. A separate
@ -458,8 +459,9 @@ public interface LogicalBreakpointInternal extends LogicalBreakpoint {
*
* @param breakpoint the trace breakpoint to check
* @return true if it can be aggregated.
* @throws TrackedTooSoonException if the containing trace is still being added to the manager
*/
boolean canMerge(TraceBreakpoint breakpoint);
boolean canMerge(TraceBreakpoint breakpoint) throws TrackedTooSoonException;
boolean trackBreakpoint(Bookmark bookmark);

View file

@ -350,10 +350,18 @@ public class MappedLogicalBreakpoint implements LogicalBreakpointInternal {
}
@Override
public boolean canMerge(TraceBreakpoint breakpoint) {
public boolean canMerge(TraceBreakpoint breakpoint) throws TrackedTooSoonException {
TraceBreakpointSet breaks = traceBreaks.get(breakpoint.getTrace());
if (breaks == null) {
throw new AssertionError();
/**
* This happens when the trace is first added to the manager, between the listener being
* installed and the current breakpoints being loaded. We received a breakpoint-changed
* event for a trace that hasn't been loaded, so we don't see its break set in this
* logical breakpoint. The solution is "easy": Just punt, and it'll get generated later.
* It's not enough to return false, because that will generate another logical
* breakpoint, which may actually duplicate this one.
*/
throw new TrackedTooSoonException();
}
if (length != breakpoint.getLength()) {
return false;

View file

@ -0,0 +1,5 @@
package ghidra.app.plugin.core.debug.service.breakpoint;
public class TrackedTooSoonException extends Exception {
}