Merge remote-tracking branch 'origin/GP-3839_Dan_stepSpeed--RBSQ'

This commit is contained in:
Ryan Kurtz 2024-02-15 11:17:47 -05:00
commit 08155a7183
67 changed files with 2698 additions and 955 deletions

View file

@ -62,6 +62,7 @@ import ghidra.util.exception.CancelledException;
import resources.MultiIcon;
public interface DebuggerResources {
String OPTIONS_CATEGORY_DEBUGGER = "Debugger";
String OPTIONS_CATEGORY_WORKFLOW = "Workflow";

View file

@ -19,7 +19,6 @@ import java.awt.Color;
import java.lang.invoke.MethodHandles;
import java.math.BigInteger;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import docking.ActionContext;
import docking.ComponentProvider;
@ -34,13 +33,13 @@ import ghidra.app.plugin.core.debug.gui.colors.MultiSelectionBlendedLayoutBackgr
import ghidra.app.plugin.core.debug.gui.listing.DebuggerTrackedRegisterListingBackgroundColorModel;
import ghidra.app.util.viewer.listingpanel.ListingBackgroundColorModel;
import ghidra.app.util.viewer.listingpanel.ListingPanel;
import ghidra.async.AsyncUtils;
import ghidra.debug.api.action.*;
import ghidra.debug.api.action.LocationTrackingSpec.TrackingSpecConfigFieldCodec;
import ghidra.debug.api.tracemgr.DebuggerCoordinates;
import ghidra.framework.options.SaveState;
import ghidra.framework.plugintool.*;
import ghidra.framework.plugintool.annotation.AutoConfigStateField;
import ghidra.program.model.address.Address;
import ghidra.program.util.ProgramLocation;
import ghidra.trace.model.*;
import ghidra.trace.model.stack.TraceStack;
@ -252,7 +251,7 @@ public class DebuggerTrackLocationTrait {
doTrack();
}
protected CompletableFuture<ProgramLocation> computeTrackedLocation() {
protected ProgramLocation computeTrackedLocation() {
// Change of register values (for current frame)
// Change of stack pc (for current frame)
// Change of current view (if not caused by goTo)
@ -262,16 +261,18 @@ public class DebuggerTrackLocationTrait {
// Change of tracking settings
DebuggerCoordinates cur = current;
if (cur.getView() == null) {
return AsyncUtils.nil();
return null;
}
TraceThread thread = cur.getThread();
if (thread == null || spec == null) {
return AsyncUtils.nil();
return null;
}
// NB: view's snap may be forked for emulation
return tracker.computeTraceAddress(tool, cur).thenApply(address -> {
return address == null ? null : new ProgramLocation(cur.getView(), address);
});
Address address = tracker.computeTraceAddress(tool, cur);
if (address == null) {
return null;
}
return new ProgramLocation(cur.getView(), address);
}
public String computeLabelText() {
@ -282,13 +283,13 @@ public class DebuggerTrackLocationTrait {
}
protected void doTrack() {
computeTrackedLocation().thenAccept(loc -> {
trackedLocation = loc;
try {
trackedLocation = computeTrackedLocation();
locationTracked();
}).exceptionally(ex -> {
}
catch (Throwable ex) {
Msg.error(this, "Error while computing location: " + ex);
return null;
});
}
}
protected void addNewListeners() {

View file

@ -15,12 +15,9 @@
*/
package ghidra.app.plugin.core.debug.gui.action;
import java.util.concurrent.CompletableFuture;
import javax.swing.Icon;
import ghidra.app.plugin.core.debug.gui.DebuggerResources.TrackLocationAction;
import ghidra.async.AsyncUtils;
import ghidra.debug.api.action.*;
import ghidra.debug.api.tracemgr.DebuggerCoordinates;
import ghidra.framework.plugintool.PluginTool;
@ -66,9 +63,8 @@ public enum NoneLocationTrackingSpec implements LocationTrackingSpec, LocationTr
}
@Override
public CompletableFuture<Address> computeTraceAddress(PluginTool tool,
DebuggerCoordinates coordinates) {
return AsyncUtils.nil();
public Address computeTraceAddress(PluginTool tool, DebuggerCoordinates coordinates) {
return null;
}
@Override

View file

@ -15,8 +15,6 @@
*/
package ghidra.app.plugin.core.debug.gui.action;
import java.util.concurrent.CompletableFuture;
import javax.swing.Icon;
import ghidra.app.plugin.core.debug.gui.DebuggerResources.TrackLocationAction;
@ -67,7 +65,8 @@ public enum PCByStackLocationTrackingSpec implements LocationTrackingSpec, Locat
return this;
}
public Address doComputeTraceAddress(PluginTool tool, DebuggerCoordinates coordinates) {
@Override
public Address computeTraceAddress(PluginTool tool, DebuggerCoordinates coordinates) {
Trace trace = coordinates.getTrace();
TraceThread thread = coordinates.getThread();
long snap = coordinates.getSnap();
@ -83,16 +82,10 @@ public enum PCByStackLocationTrackingSpec implements LocationTrackingSpec, Locat
return frame.getProgramCounter(snap);
}
@Override
public CompletableFuture<Address> computeTraceAddress(PluginTool tool,
DebuggerCoordinates coordinates) {
return CompletableFuture.supplyAsync(() -> doComputeTraceAddress(tool, coordinates));
}
@Override
public GoToInput getDefaultGoToInput(PluginTool tool, DebuggerCoordinates coordinates,
ProgramLocation location) {
Address address = doComputeTraceAddress(tool, coordinates);
Address address = computeTraceAddress(tool, coordinates);
if (address == null) {
return NoneLocationTrackingSpec.INSTANCE.getDefaultGoToInput(tool, coordinates,
location);

View file

@ -15,8 +15,6 @@
*/
package ghidra.app.plugin.core.debug.gui.action;
import java.util.concurrent.CompletableFuture;
import javax.swing.Icon;
import ghidra.app.plugin.core.debug.gui.DebuggerResources.TrackLocationAction;
@ -70,17 +68,14 @@ public enum PCLocationTrackingSpec implements LocationTrackingSpec, LocationTrac
}
@Override
public CompletableFuture<Address> computeTraceAddress(PluginTool tool,
DebuggerCoordinates coordinates) {
return CompletableFuture.supplyAsync(() -> {
if (coordinates.getTime().isSnapOnly()) {
Address pc = BY_STACK.doComputeTraceAddress(tool, coordinates);
if (pc != null) {
return pc;
}
public Address computeTraceAddress(PluginTool tool, DebuggerCoordinates coordinates) {
if (coordinates.getTime().isSnapOnly()) {
Address pc = BY_STACK.computeTraceAddress(tool, coordinates);
if (pc != null) {
return pc;
}
return BY_REG.doComputeTraceAddress(tool, coordinates);
});
}
return BY_REG.computeTraceAddress(tool, coordinates);
}
@Override

View file

@ -15,8 +15,6 @@
*/
package ghidra.app.plugin.core.debug.gui.action;
import java.util.concurrent.CompletableFuture;
import ghidra.debug.api.action.*;
import ghidra.debug.api.tracemgr.DebuggerCoordinates;
import ghidra.framework.plugintool.PluginTool;
@ -52,7 +50,8 @@ public interface RegisterLocationTrackingSpec extends LocationTrackingSpec, Loca
return this;
}
default Address doComputeTraceAddress(PluginTool tool, DebuggerCoordinates coordinates) {
@Override
default Address computeTraceAddress(PluginTool tool, DebuggerCoordinates coordinates) {
Trace trace = coordinates.getTrace();
TracePlatform platform = coordinates.getPlatform();
TraceThread thread = coordinates.getThread();
@ -88,12 +87,6 @@ public interface RegisterLocationTrackingSpec extends LocationTrackingSpec, Loca
.getAddress(value.getUnsignedValue().longValue(), true));
}
@Override
default CompletableFuture<Address> computeTraceAddress(PluginTool tool,
DebuggerCoordinates coordinates) {
return CompletableFuture.supplyAsync(() -> doComputeTraceAddress(tool, coordinates));
}
@Override
default GoToInput getDefaultGoToInput(PluginTool tool, DebuggerCoordinates coordinates,
ProgramLocation location) {

View file

@ -16,13 +16,11 @@
package ghidra.app.plugin.core.debug.gui.action;
import java.util.Objects;
import java.util.concurrent.CompletableFuture;
import javax.swing.Icon;
import ghidra.app.plugin.core.debug.gui.DebuggerResources;
import ghidra.app.plugin.core.debug.gui.DebuggerResources.TrackLocationAction;
import ghidra.async.AsyncUtils;
import ghidra.debug.api.action.*;
import ghidra.debug.api.tracemgr.DebuggerCoordinates;
import ghidra.debug.api.watch.WatchRow;
@ -115,28 +113,25 @@ public class WatchLocationTrackingSpec implements LocationTrackingSpec {
class WatchLocationTracker implements LocationTracker {
private AddressSetView reads;
private DebuggerCoordinates current = DebuggerCoordinates.NOWHERE;
private PcodeExecutor<WatchValue> asyncExec = null;
private PcodeExecutor<WatchValue> exec = null;
private PcodeExpression compiled;
@Override
public CompletableFuture<Address> computeTraceAddress(PluginTool tool,
DebuggerCoordinates coordinates) {
if (!Objects.equals(current, coordinates) || asyncExec == null) {
public Address computeTraceAddress(PluginTool tool, DebuggerCoordinates coordinates) {
if (!Objects.equals(current, coordinates) || exec == null) {
current = coordinates;
asyncExec = current.getPlatform() == null ? null
exec = current.getPlatform() == null ? null
: DebuggerPcodeUtils.buildWatchExecutor(tool, coordinates);
}
else {
asyncExec.getState().clear();
exec.getState().clear();
}
if (current.getTrace() == null) {
return AsyncUtils.nil();
return null;
}
return CompletableFuture.supplyAsync(() -> {
compiled = DebuggerPcodeUtils.compileExpression(tool, current, expression);
WatchValue value = compiled.evaluate(asyncExec);
return value == null ? null : value.address();
});
compiled = DebuggerPcodeUtils.compileExpression(tool, current, expression);
WatchValue value = compiled.evaluate(exec);
return value == null ? null : value.address();
}
@Override

View file

@ -20,7 +20,6 @@ import ghidra.app.plugin.core.debug.AbstractDebuggerPlugin;
import ghidra.app.plugin.core.debug.DebuggerPluginPackage;
import ghidra.app.plugin.core.debug.event.*;
import ghidra.app.services.DebuggerLogicalBreakpointService;
import ghidra.app.services.DebuggerModelService;
import ghidra.framework.plugintool.*;
import ghidra.framework.plugintool.util.PluginStatus;

View file

@ -259,48 +259,40 @@ public class DebuggerListingPlugin extends AbstractCodeBrowserPlugin<DebuggerLis
@Override
public void processEvent(PluginEvent event) {
if (event instanceof ProgramLocationPluginEvent) {
if (event instanceof ProgramLocationPluginEvent ev) {
cbProgramLocationEvents.invoke(() -> {
ProgramLocationPluginEvent ev = (ProgramLocationPluginEvent) event;
if (heedLocationEvent(ev)) {
connectedProvider.staticProgramLocationChanged(ev.getLocation());
}
});
}
if (event instanceof ProgramSelectionPluginEvent) {
if (event instanceof ProgramSelectionPluginEvent ev) {
cbProgramSelectionEvents.invoke(() -> {
ProgramSelectionPluginEvent ev = (ProgramSelectionPluginEvent) event;
if (heedSelectionEvent(ev)) {
connectedProvider.staticProgramSelectionChanged(ev.getProgram(),
ev.getSelection());
}
});
}
if (event instanceof ProgramOpenedPluginEvent) {
ProgramOpenedPluginEvent ev = (ProgramOpenedPluginEvent) event;
if (event instanceof ProgramOpenedPluginEvent ev) {
allProviders(p -> p.programOpened(ev.getProgram()));
}
if (event instanceof ProgramClosedPluginEvent) {
ProgramClosedPluginEvent ev = (ProgramClosedPluginEvent) event;
if (event instanceof ProgramClosedPluginEvent ev) {
allProviders(p -> p.programClosed(ev.getProgram()));
}
if (event instanceof ProgramActivatedPluginEvent) {
ProgramActivatedPluginEvent ev = (ProgramActivatedPluginEvent) event;
if (event instanceof ProgramActivatedPluginEvent ev) {
allProviders(p -> p.staticProgramActivated(ev.getActiveProgram()));
}
if (event instanceof TraceActivatedPluginEvent) {
TraceActivatedPluginEvent ev = (TraceActivatedPluginEvent) event;
if (event instanceof TraceActivatedPluginEvent ev) {
current = ev.getActiveCoordinates();
allProviders(p -> p.coordinatesActivated(current));
}
if (event instanceof TraceClosedPluginEvent) {
TraceClosedPluginEvent ev = (TraceClosedPluginEvent) event;
if (event instanceof TraceClosedPluginEvent ev) {
if (current.getTrace() == ev.getTrace()) {
current = DebuggerCoordinates.NOWHERE;
}
allProviders(p -> p.traceClosed(ev.getTrace()));
}
// TODO: Sync selection and highlights?
}
void fireStaticLocationEvent(ProgramLocation staticLoc) {

View file

@ -1159,24 +1159,22 @@ public class DebuggerListingProvider extends CodeViewerProvider {
}
protected void doGoToTracked() {
ProgramLocation loc = trackingTrait.getTrackedLocation();
ProgramLocation trackedStatic = doMarkTrackedLocation();
if (loc == null) {
return;
}
TraceProgramView curView = current.getView();
if (!syncTrait.isAutoSyncCursorWithStaticListing() || trackedStatic == null) {
Swing.runIfSwingOrRunLater(() -> {
Swing.runIfSwingOrRunLater(() -> {
ProgramLocation loc = trackingTrait.getTrackedLocation();
ProgramLocation trackedStatic = doMarkTrackedLocation();
if (loc == null) {
return;
}
TraceProgramView curView = current.getView();
if (!syncTrait.isAutoSyncCursorWithStaticListing() || trackedStatic == null) {
if (curView != current.getView()) {
// Trace changed before Swing scheduled us
return;
}
goToAndUpdateTrackingLabel(curView, loc);
doCheckCurrentModuleMissing();
});
}
else {
Swing.runIfSwingOrRunLater(() -> {
}
else {
if (curView != current.getView()) {
// Trace changed before Swing scheduled us
return;
@ -1184,8 +1182,8 @@ public class DebuggerListingProvider extends CodeViewerProvider {
goToAndUpdateTrackingLabel(curView, loc);
doCheckCurrentModuleMissing();
plugin.fireStaticLocationEvent(trackedStatic);
});
}
}
});
}
protected void doAutoDisassemble(Address start) {

View file

@ -150,13 +150,11 @@ public class DebuggerMemoryBytesPlugin
@Override
public void processEvent(PluginEvent event) {
if (event instanceof TraceActivatedPluginEvent) {
TraceActivatedPluginEvent ev = (TraceActivatedPluginEvent) event;
if (event instanceof TraceActivatedPluginEvent ev) {
current = ev.getActiveCoordinates();
allProviders(p -> p.coordinatesActivated(current));
}
if (event instanceof TraceClosedPluginEvent) {
TraceClosedPluginEvent ev = (TraceClosedPluginEvent) event;
if (event instanceof TraceClosedPluginEvent ev) {
if (current.getTrace() == ev.getTrace()) {
current = DebuggerCoordinates.NOWHERE;
}

View file

@ -66,20 +66,16 @@ public class DebuggerRegionsPlugin extends AbstractDebuggerPlugin {
@Override
public void processEvent(PluginEvent event) {
super.processEvent(event);
if (event instanceof ProgramActivatedPluginEvent) {
ProgramActivatedPluginEvent ev = (ProgramActivatedPluginEvent) event;
if (event instanceof ProgramActivatedPluginEvent ev) {
provider.setProgram(ev.getActiveProgram());
}
else if (event instanceof ProgramLocationPluginEvent) {
ProgramLocationPluginEvent ev = (ProgramLocationPluginEvent) event;
else if (event instanceof ProgramLocationPluginEvent ev) {
provider.setLocation(ev.getLocation());
}
else if (event instanceof ProgramClosedPluginEvent) {
ProgramClosedPluginEvent ev = (ProgramClosedPluginEvent) event;
else if (event instanceof ProgramClosedPluginEvent ev) {
provider.programClosed(ev.getProgram());
}
else if (event instanceof TraceActivatedPluginEvent) {
TraceActivatedPluginEvent ev = (TraceActivatedPluginEvent) event;
else if (event instanceof TraceActivatedPluginEvent ev) {
provider.coordinatesActivated(ev.getActiveCoordinates());
}
}

View file

@ -26,22 +26,21 @@ import ghidra.framework.plugintool.*;
import ghidra.framework.plugintool.util.PluginStatus;
import ghidra.program.model.listing.Program;
@PluginInfo( //
shortDescription = "Displays memory vs time", //
description = "Provides visualiztion/navigation across time/address axes", //
category = PluginCategoryNames.DEBUGGER, //
packageName = DebuggerPluginPackage.NAME, //
status = PluginStatus.RELEASED, //
eventsConsumed = { //
TraceActivatedPluginEvent.class //
}, //
servicesRequired = { //
DebuggerTraceManagerService.class //
}, //
servicesProvided = { //
MemviewService.class //
} //
)
@PluginInfo(
shortDescription = "Displays memory vs time",
description = "Provides visualiztion/navigation across time/address axes",
category = PluginCategoryNames.DEBUGGER,
packageName = DebuggerPluginPackage.NAME,
status = PluginStatus.RELEASED,
eventsConsumed = {
TraceActivatedPluginEvent.class
},
servicesRequired = {
DebuggerTraceManagerService.class
},
servicesProvided = {
MemviewService.class
})
public class DebuggerMemviewPlugin extends AbstractDebuggerPlugin implements MemviewService {
protected MemviewProvider provider;
@ -67,12 +66,12 @@ public class DebuggerMemviewPlugin extends AbstractDebuggerPlugin implements Mem
@Override
public void processEvent(PluginEvent event) {
super.processEvent(event);
if (event instanceof TraceActivatedPluginEvent) {
TraceActivatedPluginEvent ev = (TraceActivatedPluginEvent) event;
if (event instanceof TraceActivatedPluginEvent ev) {
listener.coordinatesActivated(ev.getActiveCoordinates());
}
}
@Override
public MemviewProvider getProvider() {
return provider;
}

View file

@ -65,20 +65,16 @@ public class DebuggerModulesPlugin extends AbstractDebuggerPlugin {
@Override
public void processEvent(PluginEvent event) {
super.processEvent(event);
if (event instanceof ProgramActivatedPluginEvent) {
ProgramActivatedPluginEvent ev = (ProgramActivatedPluginEvent) event;
if (event instanceof ProgramActivatedPluginEvent ev) {
provider.setProgram(ev.getActiveProgram());
}
else if (event instanceof ProgramLocationPluginEvent) {
ProgramLocationPluginEvent ev = (ProgramLocationPluginEvent) event;
else if (event instanceof ProgramLocationPluginEvent ev) {
provider.setLocation(ev.getLocation());
}
else if (event instanceof ProgramClosedPluginEvent) {
ProgramClosedPluginEvent ev = (ProgramClosedPluginEvent) event;
else if (event instanceof ProgramClosedPluginEvent ev) {
provider.programClosed(ev.getProgram());
}
else if (event instanceof TraceActivatedPluginEvent) {
TraceActivatedPluginEvent ev = (TraceActivatedPluginEvent) event;
else if (event instanceof TraceActivatedPluginEvent ev) {
provider.coordinatesActivated(ev.getActiveCoordinates());
}
}

View file

@ -64,12 +64,10 @@ public class DebuggerStaticMappingPlugin extends AbstractDebuggerPlugin {
@Override
public void processEvent(PluginEvent event) {
super.processEvent(event);
if (event instanceof TraceActivatedPluginEvent) {
TraceActivatedPluginEvent ev = (TraceActivatedPluginEvent) event;
if (event instanceof TraceActivatedPluginEvent ev) {
provider.setTrace(ev.getActiveCoordinates().getTrace());
}
if (event instanceof ProgramActivatedPluginEvent) {
ProgramActivatedPluginEvent ev = (ProgramActivatedPluginEvent) event;
if (event instanceof ProgramActivatedPluginEvent ev) {
provider.setProgram(ev.getActiveProgram());
}
}

View file

@ -112,38 +112,32 @@ public class DebuggerObjectsPlugin extends AbstractDebuggerPlugin
provider.traceOpened(ev.getTrace());
}
}
else if (event instanceof TraceActivatedPluginEvent) {
TraceActivatedPluginEvent ev = (TraceActivatedPluginEvent) event;
else if (event instanceof TraceActivatedPluginEvent ev) {
for (DebuggerObjectsProvider provider : providers) {
provider.traceActivated(ev.getActiveCoordinates());
}
}
else if (event instanceof TraceClosedPluginEvent) {
TraceClosedPluginEvent ev = (TraceClosedPluginEvent) event;
else if (event instanceof TraceClosedPluginEvent ev) {
for (DebuggerObjectsProvider provider : providers) {
provider.traceClosed(ev.getTrace());
}
}
else if (event instanceof ModelActivatedPluginEvent) {
ModelActivatedPluginEvent ev = (ModelActivatedPluginEvent) event;
else if (event instanceof ModelActivatedPluginEvent ev) {
for (DebuggerObjectsProvider provider : providers) {
provider.modelActivated(ev.getActiveModel());
}
}
else if (event instanceof ProgramActivatedPluginEvent) {
ProgramActivatedPluginEvent ev = (ProgramActivatedPluginEvent) event;
else if (event instanceof ProgramActivatedPluginEvent ev) {
for (DebuggerObjectsProvider provider : providers) {
provider.setProgram(ev.getActiveProgram());
}
}
else if (event instanceof ProgramOpenedPluginEvent) {
ProgramOpenedPluginEvent ev = (ProgramOpenedPluginEvent) event;
else if (event instanceof ProgramOpenedPluginEvent ev) {
for (DebuggerObjectsProvider provider : providers) {
provider.setProgram(ev.getProgram());
}
}
else if (event instanceof ProgramSelectionPluginEvent) {
ProgramSelectionPluginEvent ev = (ProgramSelectionPluginEvent) event;
else if (event instanceof ProgramSelectionPluginEvent ev) {
for (DebuggerObjectsProvider provider : providers) {
provider.setProgram(ev.getProgram());
}

View file

@ -53,8 +53,7 @@ public class DebuggerPcodeStepperPlugin extends AbstractDebuggerPlugin {
@Override
public void processEvent(PluginEvent event) {
super.processEvent(event);
if (event instanceof TraceActivatedPluginEvent) {
TraceActivatedPluginEvent ev = (TraceActivatedPluginEvent) event;
if (event instanceof TraceActivatedPluginEvent ev) {
provider.coordinatesActivated(ev.getActiveCoordinates());
}
}

View file

@ -29,7 +29,8 @@ import ghidra.app.plugin.PluginCategoryNames;
import ghidra.app.plugin.core.debug.DebuggerPluginPackage;
import ghidra.app.plugin.core.debug.event.*;
import ghidra.app.plugin.core.debug.gui.DebuggerResources;
import ghidra.app.plugin.core.debug.mapping.*;
import ghidra.app.plugin.core.debug.mapping.DebuggerPlatformOffer;
import ghidra.app.plugin.core.debug.mapping.DebuggerPlatformOpinion;
import ghidra.app.services.DebuggerPlatformService;
import ghidra.app.services.DebuggerTraceManagerService;
import ghidra.debug.api.platform.DebuggerPlatformMapper;
@ -307,14 +308,14 @@ public class DebuggerPlatformPlugin extends Plugin {
@Override
public void processEvent(PluginEvent event) {
super.processEvent(event);
if (event instanceof TraceActivatedPluginEvent evt) {
coordinatesActivated(evt.getActiveCoordinates());
if (event instanceof TraceActivatedPluginEvent ev) {
coordinatesActivated(ev.getActiveCoordinates());
}
if (event instanceof TraceClosedPluginEvent evt) {
traceClosed(evt.getTrace());
if (event instanceof TraceClosedPluginEvent ev) {
traceClosed(ev.getTrace());
}
if (event instanceof DebuggerPlatformPluginEvent evt) {
mapperActivated(evt.getTrace(), evt.getMapper());
if (event instanceof DebuggerPlatformPluginEvent ev) {
mapperActivated(ev.getTrace(), ev.getMapper());
}
}

View file

@ -101,12 +101,10 @@ public class DebuggerRegistersPlugin extends AbstractDebuggerPlugin {
@Override
public void processEvent(PluginEvent event) {
super.processEvent(event);
if (event instanceof TraceActivatedPluginEvent) {
TraceActivatedPluginEvent ev = (TraceActivatedPluginEvent) event;
if (event instanceof TraceActivatedPluginEvent ev) {
connectedProvider.coordinatesActivated(ev.getActiveCoordinates());
}
if (event instanceof TraceClosedPluginEvent) {
TraceClosedPluginEvent ev = (TraceClosedPluginEvent) event;
if (event instanceof TraceClosedPluginEvent ev) {
traceClosed(ev.getTrace());
}
}

View file

@ -18,7 +18,8 @@ package ghidra.app.plugin.core.debug.gui.thread;
import ghidra.app.plugin.PluginCategoryNames;
import ghidra.app.plugin.core.debug.AbstractDebuggerPlugin;
import ghidra.app.plugin.core.debug.DebuggerPluginPackage;
import ghidra.app.plugin.core.debug.event.*;
import ghidra.app.plugin.core.debug.event.TraceActivatedPluginEvent;
import ghidra.app.plugin.core.debug.event.TraceOpenedPluginEvent;
import ghidra.app.services.DebuggerTraceManagerService;
import ghidra.framework.plugintool.*;
import ghidra.framework.plugintool.util.PluginStatus;
@ -57,8 +58,7 @@ public class DebuggerThreadsPlugin extends AbstractDebuggerPlugin {
@Override
public void processEvent(PluginEvent event) {
super.processEvent(event);
if (event instanceof TraceActivatedPluginEvent) {
TraceActivatedPluginEvent ev = (TraceActivatedPluginEvent) event;
if (event instanceof TraceActivatedPluginEvent ev) {
provider.coordinatesActivated(ev.getActiveCoordinates());
}
}

View file

@ -21,6 +21,7 @@ import java.util.Collection;
import java.util.Objects;
import java.util.function.BiConsumer;
import java.util.function.Function;
import java.util.stream.Collectors;
import javax.swing.*;
import javax.swing.table.*;
@ -141,7 +142,7 @@ public class DebuggerSnapshotTablePanel extends JPanel {
public Component getTableCellRendererComponent(GTableCellRenderingData data) {
super.getTableCellRendererComponent(data);
SnapshotRow row = (SnapshotRow) data.getRowObject();
if (row != null && row.getSnap() == currentSnap) {
if (row != null && currentSnap != null && currentSnap.longValue() == row.getSnap()) {
setBold();
}
return this;
@ -154,7 +155,7 @@ public class DebuggerSnapshotTablePanel extends JPanel {
protected boolean hideScratch = true;
private Trace currentTrace;
private Long currentSnap;
private volatile Long currentSnap;
protected final SnapshotListener listener = new SnapshotListener();
@ -237,8 +238,11 @@ public class DebuggerSnapshotTablePanel extends JPanel {
Collection<? extends TraceSnapshot> snapshots =
hideScratch ? manager.getSnapshots(0, true, Long.MAX_VALUE, true)
: manager.getAllSnapshots();
snapshotTableModel
.addAll(snapshots.stream().map(s -> new SnapshotRow(currentTrace, s)).toList());
// Use .collect instead of .toList to avoid size/sync issues
// Even though access is synchronized, size may change during iteration
snapshotTableModel.addAll(snapshots.stream()
.map(s -> new SnapshotRow(currentTrace, s))
.collect(Collectors.toList()));
}
protected void deleteScratchSnapshots() {
@ -250,10 +254,11 @@ public class DebuggerSnapshotTablePanel extends JPanel {
return;
}
TraceTimeManager manager = currentTrace.getTimeManager();
snapshotTableModel.addAll(manager.getSnapshots(Long.MIN_VALUE, true, 0, false)
.stream()
Collection<? extends TraceSnapshot> sratch =
manager.getSnapshots(Long.MIN_VALUE, true, 0, false);
snapshotTableModel.addAll(sratch.stream()
.map(s -> new SnapshotRow(currentTrace, s))
.toList());
.collect(Collectors.toList()));
}
public ListSelectionModel getSelectionModel() {
@ -265,8 +270,12 @@ public class DebuggerSnapshotTablePanel extends JPanel {
return row == null ? null : row.getSnap();
}
public void setSelectedSnapshot(Long snap) {
public void setCurrentSnapshot(Long snap) {
currentSnap = snap;
snapshotTableModel.fireTableDataChanged();
}
public void setSelectedSnapshot(Long snap) {
if (snap == null) {
snapshotTable.clearSelection();
return;
@ -283,6 +292,5 @@ public class DebuggerSnapshotTablePanel extends JPanel {
return;
}
snapshotFilterPanel.setSelectedItem(row);
snapshotTableModel.fireTableDataChanged();
}
}

View file

@ -122,8 +122,7 @@ public class DebuggerTimePlugin extends AbstractDebuggerPlugin {
@Override
public void processEvent(PluginEvent event) {
super.processEvent(event);
if (event instanceof TraceActivatedPluginEvent) {
TraceActivatedPluginEvent ev = (TraceActivatedPluginEvent) event;
if (event instanceof TraceActivatedPluginEvent ev) {
provider.coordinatesActivated(ev.getActiveCoordinates());
}
}

View file

@ -209,7 +209,7 @@ public class DebuggerTimeProvider extends ComponentProviderAdapter {
current = coordinates;
mainPanel.setTrace(current.getTrace());
mainPanel.setSelectedSnapshot(current.getSnap());
mainPanel.setCurrentSnapshot(current.getSnap());
}
public void writeConfigState(SaveState saveState) {

View file

@ -1360,23 +1360,23 @@ public class DebuggerLogicalBreakpointServicePlugin extends Plugin
@Override
public void processEvent(PluginEvent event) {
if (event instanceof ProgramOpenedPluginEvent evt) {
programOpened(evt.getProgram());
if (event instanceof ProgramOpenedPluginEvent ev) {
programOpened(ev.getProgram());
}
else if (event instanceof ProgramClosedPluginEvent evt) {
programClosed(evt.getProgram());
else if (event instanceof ProgramClosedPluginEvent ev) {
programClosed(ev.getProgram());
}
else if (event instanceof TraceOpenedPluginEvent evt) {
traceOpened(evt.getTrace());
else if (event instanceof TraceOpenedPluginEvent ev) {
traceOpened(ev.getTrace());
}
else if (event instanceof TraceActivatedPluginEvent evt) {
traceSnapChanged(evt.getActiveCoordinates());
else if (event instanceof TraceActivatedPluginEvent ev) {
traceSnapChanged(ev.getActiveCoordinates());
}
else if (event instanceof TraceInactiveCoordinatesPluginEvent evt) {
traceSnapChanged(evt.getCoordinates());
else if (event instanceof TraceInactiveCoordinatesPluginEvent ev) {
traceSnapChanged(ev.getCoordinates());
}
else if (event instanceof TraceClosedPluginEvent evt) {
traceClosed(evt.getTrace());
else if (event instanceof TraceClosedPluginEvent ev) {
traceClosed(ev.getTrace());
}
}
}

View file

@ -20,7 +20,8 @@ import java.util.*;
import java.util.concurrent.*;
import ghidra.app.plugin.PluginCategoryNames;
import ghidra.app.plugin.core.debug.*;
import ghidra.app.plugin.core.debug.AbstractDebuggerPlugin;
import ghidra.app.plugin.core.debug.DebuggerPluginPackage;
import ghidra.app.plugin.core.debug.event.*;
import ghidra.app.services.*;
import ghidra.app.services.DebuggerTraceManagerService.ActivationCause;
@ -342,14 +343,14 @@ public class DebuggerControlServicePlugin extends AbstractDebuggerPlugin
@Override
public void processEvent(PluginEvent event) {
super.processEvent(event);
if (event instanceof TraceOpenedPluginEvent evt) {
installAllMemoryEditors(evt.getTrace());
if (event instanceof TraceOpenedPluginEvent ev) {
installAllMemoryEditors(ev.getTrace());
}
else if (event instanceof TraceActivatedPluginEvent evt) {
coordinatesActivated(evt.getActiveCoordinates(), evt.getCause());
else if (event instanceof TraceActivatedPluginEvent ev) {
coordinatesActivated(ev.getActiveCoordinates(), ev.getCause());
}
else if (event instanceof TraceClosedPluginEvent evt) {
uninstallAllMemoryEditors(evt.getTrace());
else if (event instanceof TraceClosedPluginEvent ev) {
uninstallAllMemoryEditors(ev.getTrace());
}
}

View file

@ -83,6 +83,24 @@ public class DebuggerStaticMappingServicePlugin extends Plugin
this.mapping = mapping;
}
@Override
public boolean equals(Object o) {
if (!(o instanceof MappingEntry that)) {
return false;
}
// Yes, use identity, since it should be the same trace db records
if (this.mapping != that.mapping) {
return false;
}
if (this.program != that.program) {
return false;
}
if (!Objects.equals(this.staticRange, that.staticRange)) {
return false;
}
return true;
}
public Trace getTrace() {
return mapping.getTrace();
}
@ -232,11 +250,14 @@ public class DebuggerStaticMappingServicePlugin extends Plugin
private void objectRestored() {
synchronized (lock) {
doAffectedByTraceClosed(trace);
var old = Map.copyOf(outbound);
outbound.clear();
loadOutboundEntries(); // Also places/updates corresponding inbound entries
// TODO: What about removed corresponding inbound entries?
doAffectedByTraceOpened(trace);
if (!old.equals(outbound)) {
// TODO: What about removed corresponding inbound entries?
doAffectedByTraceClosed(trace);
doAffectedByTraceOpened(trace);
}
}
}
@ -811,13 +832,13 @@ public class DebuggerStaticMappingServicePlugin extends Plugin
}
protected <T> T noTraceInfo() {
Msg.warn(this, "The given trace is not open in this tool " +
Msg.debug(this, "The given trace is not open in this tool " +
"(or the service hasn't received and processed the open-trace event, yet)");
return null;
}
protected <T> T noProgramInfo() {
Msg.warn(this, "The given program is not open in this tool " +
Msg.debug(this, "The given program is not open in this tool " +
"(or the service hasn't received and processed the open-program event, yet)");
return null;
}

View file

@ -269,7 +269,7 @@ public class DebuggerRegionsProviderTest extends AbstractGhidraHeadedDebuggerTes
waitForPass(() -> assertTableSize(0));
}
@Test
// @Test // Not gonna with write-behind cache
public void testUndoRedo() throws Exception {
createAndOpenTrace();
@ -304,7 +304,7 @@ public class DebuggerRegionsProviderTest extends AbstractGhidraHeadedDebuggerTes
});
}
@Test
// @Test // Not gonna with write-behind cache
public void testAbort() throws Exception {
createAndOpenTrace();
traceManager.activateTrace(tb.trace);

View file

@ -1128,7 +1128,8 @@ public class DebuggerModelProviderTest extends AbstractGhidraHeadedDebuggerTest
}
waitForTasks();
assertEquals(4, modelProvider.attributesTablePanel.tableModel.getModelData().size());
waitForPass(() -> assertEquals(4,
modelProvider.attributesTablePanel.tableModel.getModelData().size()));
}
@Test
@ -1158,6 +1159,7 @@ public class DebuggerModelProviderTest extends AbstractGhidraHeadedDebuggerTest
// TODO: Should I collapse entries that are links to the same object?
// Would use the "Life" column to display span for each included entry.
// Neat, but not sure it's worth it
assertEquals(14, modelProvider.elementsTablePanel.tableModel.getModelData().size());
waitForPass(() -> assertEquals(14,
modelProvider.elementsTablePanel.tableModel.getModelData().size()));
}
}

View file

@ -401,7 +401,7 @@ public class DebuggerModulesProviderTest extends AbstractGhidraHeadedDebuggerTes
});
}
@Test
// @Test // Not gonna with write-behind cache
public void testUndoRedoCausesUpdateInProvider() throws Exception {
createAndOpenTrace();

View file

@ -444,7 +444,7 @@ public class DebuggerThreadsProviderTest extends AbstractGhidraHeadedDebuggerTes
thread1.getObject().getAttribute(0, TraceObjectThread.KEY_COMMENT).getValue()));
}
@Test
// @Test // Not gonna with write-behind cache
public void testUndoRedoCausesUpdateInProvider() throws Exception {
createAndOpenTrace();
addThreads();

View file

@ -15,7 +15,8 @@
*/
package ghidra.app.plugin.core.debug.gui.time;
import static org.junit.Assert.*;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import java.util.Calendar;
import java.util.List;
@ -286,35 +287,7 @@ public class DebuggerTimeProviderTest extends AbstractGhidraHeadedDebuggerTest {
tb.trace.getTimeManager().getSnapshot(0, false).getDescription());
}
@Test
public void testActivateSnapSelectsRow() throws Exception {
createSnaplessTrace();
traceManager.openTrace(tb.trace);
addSnapshots();
waitForDomainObject(tb.trace);
assertProviderEmpty();
traceManager.activateTrace(tb.trace);
waitForSwing();
List<SnapshotRow> data = timeProvider.mainPanel.snapshotTableModel.getModelData();
traceManager.activateSnap(0);
waitForSwing();
assertEquals(data.get(0), timeProvider.mainPanel.snapshotFilterPanel.getSelectedItem());
traceManager.activateSnap(10);
waitForSwing();
assertEquals(data.get(1), timeProvider.mainPanel.snapshotFilterPanel.getSelectedItem());
traceManager.activateSnap(5);
waitForSwing();
assertNull(timeProvider.mainPanel.snapshotFilterPanel.getSelectedItem());
}
// TODO: Test activation bolds the row
@Test
public void testDoubleClickRowActivatesSnap() throws Exception {

View file

@ -47,6 +47,7 @@ import ghidra.trace.model.target.*;
import ghidra.trace.model.thread.*;
import ghidra.trace.model.time.TraceSnapshot;
import ghidra.trace.model.time.TraceTimeManager;
import ghidra.util.StreamUtils;
import ghidra.util.task.TaskMonitor;
public class ObjectBasedTraceRecorderTest extends AbstractGhidraHeadedDebuggerTest {
@ -88,7 +89,7 @@ public class ObjectBasedTraceRecorderTest extends AbstractGhidraHeadedDebuggerTe
protected void dumpObjects() {
System.err.println("All objects:");
for (TraceObject object : objects.getAllObjects()) {
for (TraceObject object : StreamUtils.iter(objects.getAllObjects())) {
System.err.println(" " + object);
}
}
@ -99,7 +100,7 @@ public class ObjectBasedTraceRecorderTest extends AbstractGhidraHeadedDebuggerTe
waitForPass(noExc(() -> {
waitOn(recorder.flushTransactions());
assertEquals(5, objects.getAllObjects().size());
assertEquals(5, objects.getObjectCount());
}));
}