mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-06 03:50:02 +02:00
GP-0: Fix timing issue in breakpoint service
This commit is contained in:
parent
0bfb9ae84a
commit
65a7105cbf
4 changed files with 38 additions and 6 deletions
|
@ -231,6 +231,10 @@ public class DebuggerLogicalBreakpointServicePlugin extends Plugin
|
||||||
info.trackTraceBreakpoint(breakpoint, c, false);
|
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) {
|
private void breakpointChanged(TraceBreakpoint breakpoint) {
|
||||||
|
@ -242,6 +246,10 @@ public class DebuggerLogicalBreakpointServicePlugin extends Plugin
|
||||||
info.trackTraceBreakpoint(breakpoint, c, true);
|
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,
|
private void breakpointLifespanChanged(TraceAddressSpace spaceIsNull,
|
||||||
|
@ -266,6 +274,10 @@ public class DebuggerLogicalBreakpointServicePlugin extends Plugin
|
||||||
info.trackTraceBreakpoint(breakpoint, c, false);
|
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);
|
long length, Collection<TraceBreakpointKind> kinds);
|
||||||
|
|
||||||
protected LogicalBreakpointInternal getOrCreateLogicalBreakpointFor(Address address,
|
protected LogicalBreakpointInternal getOrCreateLogicalBreakpointFor(Address address,
|
||||||
TraceBreakpoint breakpoint, AddCollector c) {
|
TraceBreakpoint breakpoint, AddCollector c) throws TrackedTooSoonException {
|
||||||
Set<LogicalBreakpointInternal> set =
|
Set<LogicalBreakpointInternal> set =
|
||||||
breakpointsByAddress.computeIfAbsent(address, a -> new HashSet<>());
|
breakpointsByAddress.computeIfAbsent(address, a -> new HashSet<>());
|
||||||
for (LogicalBreakpointInternal lb : set) {
|
for (LogicalBreakpointInternal lb : set) {
|
||||||
|
@ -543,7 +555,12 @@ public class DebuggerLogicalBreakpointServicePlugin extends Plugin
|
||||||
protected void trackTraceBreakpoints(Collection<TraceBreakpoint> breakpoints,
|
protected void trackTraceBreakpoints(Collection<TraceBreakpoint> breakpoints,
|
||||||
AddCollector collector) {
|
AddCollector collector) {
|
||||||
for (TraceBreakpoint b : breakpoints) {
|
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,
|
protected void trackTraceBreakpoint(TraceBreakpoint breakpoint, AddCollector c,
|
||||||
boolean forceUpdate) {
|
boolean forceUpdate) throws TrackedTooSoonException {
|
||||||
Address traceAddr = breakpoint.getMinAddress();
|
Address traceAddr = breakpoint.getMinAddress();
|
||||||
ProgramLocation progLoc = computeStaticLocation(breakpoint);
|
ProgramLocation progLoc = computeStaticLocation(breakpoint);
|
||||||
LogicalBreakpointInternal lb;
|
LogicalBreakpointInternal lb;
|
||||||
|
|
|
@ -451,6 +451,7 @@ public interface LogicalBreakpointInternal extends LogicalBreakpoint {
|
||||||
/**
|
/**
|
||||||
* Check if this logical breakpoint can subsume the given candidate trace breakpoint
|
* 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
|
* Note that logical breakpoints only include trace breakpoints for traces being actively
|
||||||
* recorded. All statuses regarding trace breakpoints are derived from the target breakpoints,
|
* 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
|
* 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
|
* @param breakpoint the trace breakpoint to check
|
||||||
* @return true if it can be aggregated.
|
* @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);
|
boolean trackBreakpoint(Bookmark bookmark);
|
||||||
|
|
||||||
|
|
|
@ -350,10 +350,18 @@ public class MappedLogicalBreakpoint implements LogicalBreakpointInternal {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean canMerge(TraceBreakpoint breakpoint) {
|
public boolean canMerge(TraceBreakpoint breakpoint) throws TrackedTooSoonException {
|
||||||
TraceBreakpointSet breaks = traceBreaks.get(breakpoint.getTrace());
|
TraceBreakpointSet breaks = traceBreaks.get(breakpoint.getTrace());
|
||||||
if (breaks == null) {
|
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()) {
|
if (length != breakpoint.getLength()) {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
package ghidra.app.plugin.core.debug.service.breakpoint;
|
||||||
|
|
||||||
|
public class TrackedTooSoonException extends Exception {
|
||||||
|
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue