mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-05 19:42:36 +02:00
GP-2062: Add Skip Instruction button for emulator
This commit is contained in:
parent
00dbd26511
commit
4736a3c924
20 changed files with 961 additions and 614 deletions
|
@ -125,6 +125,18 @@
|
|||
the next tick, using emulation. Note that emulation does not affect the target. Furthermore,
|
||||
emulation may halt early if it encounters certain instructions or causes an exception.</P>
|
||||
|
||||
<H3><A name="emu_trace_skip_tick_forward"></A><IMG alt="" src="images/skipover.png">Emulate
|
||||
Trace Skip Tick Forward</H3>
|
||||
|
||||
<P>This action is available when a thread is selected. It steps the current thread forward by
|
||||
skipping the next instruction, using emulation. Note that emulation does not affect the target.
|
||||
Furthermore, emulation may halt early if it encounters certain instructions or causes an
|
||||
exception. This action may be used skip subroutines; <B>however</B>, the stack may require
|
||||
additional patching, e.g., to clean up stack parameters, depending on the calling convention.
|
||||
This action <EM>does not</EM> perform those patches automatically. It only advances the program
|
||||
counter. You may use <A href="#goto_time">Go To Time</A> to append the require stack patch,
|
||||
e.g., <CODE>t0-{RSP=RSP+8}</CODE>.</P>
|
||||
|
||||
<H3><A name="seek_trace_present"></A><IMG alt="" src="images/continue.png">Seek Trace to
|
||||
Present</H3>
|
||||
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 20 KiB |
Binary file not shown.
After Width: | Height: | Size: 320 B |
|
@ -87,6 +87,7 @@ public interface DebuggerResources {
|
|||
|
||||
ImageIcon ICON_STEP_INTO = ResourceManager.loadImage("images/stepinto.png");
|
||||
ImageIcon ICON_STEP_OVER = ResourceManager.loadImage("images/stepover.png");
|
||||
ImageIcon ICON_SKIP_OVER = ResourceManager.loadImage("images/skipover.png");
|
||||
ImageIcon ICON_STEP_FINISH = ResourceManager.loadImage("images/stepout.png");
|
||||
ImageIcon ICON_STEP_BACK = ResourceManager.loadImage("images/stepback.png");
|
||||
// TODO: Draw new icons?
|
||||
|
@ -1641,81 +1642,12 @@ public interface DebuggerResources {
|
|||
}
|
||||
}
|
||||
|
||||
interface StepSnapForwardAction {
|
||||
String NAME = "Step Trace Snap Forward";
|
||||
String DESCRIPTION = "Navigate the recording forward one snap";
|
||||
Icon ICON = ICON_SNAP_FORWARD;
|
||||
String GROUP = GROUP_CONTROL;
|
||||
String HELP_ANCHOR = "step_trace_snap_forward";
|
||||
|
||||
static ActionBuilder builder(Plugin owner) {
|
||||
String ownerName = owner.getName();
|
||||
return new ActionBuilder(NAME, ownerName)
|
||||
.description(DESCRIPTION)
|
||||
.toolBarIcon(ICON)
|
||||
.toolBarGroup(GROUP, "4")
|
||||
.helpLocation(new HelpLocation(ownerName, HELP_ANCHOR));
|
||||
}
|
||||
}
|
||||
|
||||
abstract class AbstractStepSnapForwardAction extends DockingAction {
|
||||
public static final String NAME = StepSnapForwardAction.NAME;
|
||||
public static final Icon ICON = StepSnapForwardAction.ICON;
|
||||
public static final String HELP_ANCHOR = StepSnapForwardAction.HELP_ANCHOR;
|
||||
|
||||
public AbstractStepSnapForwardAction(Plugin owner) {
|
||||
super(NAME, owner.getName());
|
||||
setDescription(StepSnapForwardAction.DESCRIPTION);
|
||||
setHelpLocation(new HelpLocation(owner.getName(), HELP_ANCHOR));
|
||||
}
|
||||
}
|
||||
|
||||
abstract class AbstractEmulateTickForwardAction extends DockingAction {
|
||||
public static final String NAME = "Emulate Trace Tick Forward";
|
||||
public static final Icon ICON = ICON_STEP_INTO;
|
||||
public static final String HELP_ANCHOR = "emu_trace_tick_forward";
|
||||
|
||||
public AbstractEmulateTickForwardAction(Plugin owner) {
|
||||
super(NAME, owner.getName());
|
||||
setDescription("Emulate the recording forward one tick");
|
||||
setHelpLocation(new HelpLocation(owner.getName(), HELP_ANCHOR));
|
||||
}
|
||||
}
|
||||
|
||||
interface EmulatePcodeForwardAction {
|
||||
String NAME = "Emulate Trace p-code Forward";
|
||||
String DESCRIPTION = "Navigate the recording forward one p-code tick";
|
||||
Icon ICON = ICON_STEP_INTO;
|
||||
String GROUP = GROUP_CONTROL;
|
||||
String HELP_ANCHOR = "emu_trace_pcode_forward";
|
||||
|
||||
static ActionBuilder builder(Plugin owner) {
|
||||
String ownerName = owner.getName();
|
||||
return new ActionBuilder(NAME, ownerName)
|
||||
.description(DESCRIPTION)
|
||||
.toolBarIcon(ICON)
|
||||
.toolBarGroup(GROUP)
|
||||
.helpLocation(new HelpLocation(ownerName, HELP_ANCHOR));
|
||||
}
|
||||
}
|
||||
|
||||
abstract class AbstractEmulateTickBackwardAction extends DockingAction {
|
||||
public static final String NAME = "Emulate Trace Tick Backward";
|
||||
public static final Icon ICON = ICON_STEP_BACK;
|
||||
public static final String HELP_ANCHOR = "emu_trace_tick_backward";
|
||||
|
||||
public AbstractEmulateTickBackwardAction(Plugin owner) {
|
||||
super(NAME, owner.getName());
|
||||
setDescription("Emulate the recording backward one tick");
|
||||
setHelpLocation(new HelpLocation(owner.getName(), HELP_ANCHOR));
|
||||
}
|
||||
}
|
||||
|
||||
interface StepSnapBackwardAction {
|
||||
String NAME = "Step Trace Snap Backward";
|
||||
String DESCRIPTION = "Navigate the recording backward one snap";
|
||||
Icon ICON = ICON_SNAP_BACKWARD;
|
||||
String GROUP = GROUP_CONTROL;
|
||||
String ORDER = "1";
|
||||
String HELP_ANCHOR = "step_trace_snap_backward";
|
||||
|
||||
static ActionBuilder builder(Plugin owner) {
|
||||
|
@ -1723,20 +1655,80 @@ public interface DebuggerResources {
|
|||
return new ActionBuilder(NAME, ownerName)
|
||||
.description(DESCRIPTION)
|
||||
.toolBarIcon(ICON)
|
||||
.toolBarGroup(GROUP, "1")
|
||||
.toolBarGroup(GROUP, ORDER)
|
||||
.helpLocation(new HelpLocation(ownerName, HELP_ANCHOR));
|
||||
}
|
||||
}
|
||||
|
||||
abstract class AbstractStepSnapBackwardAction extends DockingAction {
|
||||
public static final String NAME = StepSnapBackwardAction.NAME;
|
||||
public static final Icon ICON = StepSnapBackwardAction.ICON;;
|
||||
public static final String HELP_ANCHOR = StepSnapBackwardAction.HELP_ANCHOR;
|
||||
interface StepSnapForwardAction {
|
||||
String NAME = "Step Trace Snap Forward";
|
||||
String DESCRIPTION = "Navigate the recording forward one snap";
|
||||
Icon ICON = ICON_SNAP_FORWARD;
|
||||
String GROUP = GROUP_CONTROL;
|
||||
String ORDER = "5";
|
||||
String HELP_ANCHOR = "step_trace_snap_forward";
|
||||
|
||||
public AbstractStepSnapBackwardAction(Plugin owner) {
|
||||
super(NAME, owner.getName());
|
||||
setDescription(StepSnapBackwardAction.DESCRIPTION);
|
||||
setHelpLocation(new HelpLocation(owner.getName(), HELP_ANCHOR));
|
||||
static ActionBuilder builder(Plugin owner) {
|
||||
String ownerName = owner.getName();
|
||||
return new ActionBuilder(NAME, ownerName)
|
||||
.description(DESCRIPTION)
|
||||
.toolBarIcon(ICON)
|
||||
.toolBarGroup(GROUP, ORDER)
|
||||
.helpLocation(new HelpLocation(ownerName, HELP_ANCHOR));
|
||||
}
|
||||
}
|
||||
|
||||
interface EmulateTickBackwardAction {
|
||||
String NAME = "Emulate Trace Tick Backward";
|
||||
String DESCRIPTION = "Emulate the recording backward one tick";
|
||||
Icon ICON = ICON_STEP_BACK;
|
||||
String GROUP = GROUP_CONTROL;
|
||||
String ORDER = "2";
|
||||
String HELP_ANCHOR = "emu_trace_tick_backward";
|
||||
|
||||
static ActionBuilder builder(Plugin owner) {
|
||||
String ownerName = owner.getName();
|
||||
return new ActionBuilder(NAME, ownerName)
|
||||
.description(DESCRIPTION)
|
||||
.toolBarIcon(ICON)
|
||||
.toolBarGroup(GROUP, ORDER)
|
||||
.helpLocation(new HelpLocation(ownerName, HELP_ANCHOR));
|
||||
}
|
||||
}
|
||||
|
||||
interface EmulateTickForwardAction {
|
||||
String NAME = "Emulate Trace Tick Forward";
|
||||
String DESCRIPTION = "Emulate the recording forward one instruction";
|
||||
Icon ICON = ICON_STEP_INTO;
|
||||
String GROUP = GROUP_CONTROL;
|
||||
String ORDER = "3";
|
||||
String HELP_ANCHOR = "emu_trace_tick_forward";
|
||||
|
||||
static ActionBuilder builder(Plugin owner) {
|
||||
String ownerName = owner.getName();
|
||||
return new ActionBuilder(NAME, ownerName)
|
||||
.description(DESCRIPTION)
|
||||
.toolBarIcon(ICON)
|
||||
.toolBarGroup(GROUP, ORDER)
|
||||
.helpLocation(new HelpLocation(ownerName, HELP_ANCHOR));
|
||||
}
|
||||
}
|
||||
|
||||
interface EmulateSkipTickForwardAction {
|
||||
String NAME = "Emulate Trace Skip Tick Forward";
|
||||
String DESCRIPTION = "Emulate the recording forward by skipping one instruction";
|
||||
Icon ICON = ICON_SKIP_OVER;
|
||||
String GROUP = GROUP_CONTROL;
|
||||
String ORDER = "4";
|
||||
String HELP_ANCHOR = "emu_trace_skip_tick_forward";
|
||||
|
||||
static ActionBuilder builder(Plugin owner) {
|
||||
String ownerName = owner.getName();
|
||||
return new ActionBuilder(NAME, ownerName)
|
||||
.description(DESCRIPTION)
|
||||
.toolBarIcon(ICON)
|
||||
.toolBarGroup(GROUP, ORDER)
|
||||
.helpLocation(new HelpLocation(ownerName, HELP_ANCHOR));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1745,8 +1737,45 @@ public interface DebuggerResources {
|
|||
String DESCRIPTION = "Navigate the recording backward one p-code tick";
|
||||
Icon ICON = ICON_STEP_BACK;
|
||||
String GROUP = GROUP_CONTROL;
|
||||
String ORDER = "2";
|
||||
String HELP_ANCHOR = "emu_trace_pcode_backward";
|
||||
|
||||
static ActionBuilder builder(Plugin owner) {
|
||||
String ownerName = owner.getName();
|
||||
return new ActionBuilder(NAME, ownerName)
|
||||
.description(DESCRIPTION)
|
||||
.toolBarIcon(ICON)
|
||||
.toolBarGroup(GROUP, ORDER)
|
||||
.helpLocation(new HelpLocation(ownerName, HELP_ANCHOR));
|
||||
}
|
||||
}
|
||||
|
||||
interface EmulatePcodeForwardAction {
|
||||
String NAME = "Emulate Trace p-code Forward";
|
||||
String DESCRIPTION = "Emulate the recording forward one p-code tick";
|
||||
Icon ICON = ICON_STEP_INTO;
|
||||
String GROUP = GROUP_CONTROL;
|
||||
String ORDER = "3";
|
||||
String HELP_ANCHOR = "emu_trace_pcode_forward";
|
||||
|
||||
static ActionBuilder builder(Plugin owner) {
|
||||
String ownerName = owner.getName();
|
||||
return new ActionBuilder(NAME, ownerName)
|
||||
.description(DESCRIPTION)
|
||||
.toolBarIcon(ICON)
|
||||
.toolBarGroup(GROUP, ORDER)
|
||||
.helpLocation(new HelpLocation(ownerName, HELP_ANCHOR));
|
||||
}
|
||||
}
|
||||
|
||||
interface EmulateSkipPcodeForwardAction {
|
||||
String NAME = "Emulate Trace Skip P-code Forward";
|
||||
String DESCRIPTION = "Emulate the recording forward by skipping one p-code op";
|
||||
Icon ICON = ICON_SKIP_OVER;
|
||||
String GROUP = GROUP_CONTROL;
|
||||
String ORDER = "4";
|
||||
String HELP_ANCHOR = "emu_trace_skip_pcode_forward";
|
||||
|
||||
static ActionBuilder builder(Plugin owner) {
|
||||
String ownerName = owner.getName();
|
||||
return new ActionBuilder(NAME, ownerName)
|
||||
|
@ -1757,15 +1786,20 @@ public interface DebuggerResources {
|
|||
}
|
||||
}
|
||||
|
||||
abstract class AbstractSeekTracePresentAction extends ToggleDockingAction {
|
||||
public static final String NAME = "Seek Trace Present";
|
||||
public static final Icon ICON = ICON_SEEK_PRESENT;
|
||||
public static final String HELP_ANCHOR = "seek_trace_present";
|
||||
interface SeekTracePresentAction {
|
||||
String NAME = "Seek Trace Present";
|
||||
String DESCRIPTION = "Track the tool to the latest snap";
|
||||
Icon ICON = ICON_SEEK_PRESENT;
|
||||
String GROUP = "zz";
|
||||
String HELP_ANCHOR = "seek_trace_present";
|
||||
|
||||
public AbstractSeekTracePresentAction(Plugin owner) {
|
||||
super(NAME, owner.getName());
|
||||
setDescription("Track the tool to the latest snap");
|
||||
setHelpLocation(new HelpLocation(owner.getName(), HELP_ANCHOR));
|
||||
static ToggleActionBuilder builder(Plugin owner) {
|
||||
String ownerName = owner.getName();
|
||||
return new ToggleActionBuilder(NAME, ownerName)
|
||||
.description(DESCRIPTION)
|
||||
.toolBarIcon(ICON)
|
||||
.toolBarGroup(GROUP)
|
||||
.helpLocation(new HelpLocation(ownerName, HELP_ANCHOR));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -87,172 +87,6 @@ public class DebuggerThreadsProvider extends ComponentProviderAdapter {
|
|||
return true;
|
||||
}
|
||||
|
||||
protected class StepSnapBackwardAction extends AbstractStepSnapBackwardAction {
|
||||
public static final String GROUP = DebuggerResources.GROUP_CONTROL;
|
||||
|
||||
public StepSnapBackwardAction() {
|
||||
super(plugin);
|
||||
setToolBarData(new ToolBarData(ICON, GROUP, "1"));
|
||||
addLocalAction(this);
|
||||
setEnabled(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionContext context) {
|
||||
if (current.getTime().isSnapOnly()) {
|
||||
traceManager.activateSnap(current.getSnap() - 1);
|
||||
}
|
||||
else {
|
||||
traceManager.activateSnap(current.getSnap());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnabledForContext(ActionContext context) {
|
||||
if (current.getTrace() == null) {
|
||||
return false;
|
||||
}
|
||||
if (!current.getTime().isSnapOnly()) {
|
||||
return true;
|
||||
}
|
||||
if (current.getSnap() <= 0) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
protected class EmulateTickBackwardAction extends AbstractEmulateTickBackwardAction {
|
||||
public static final String GROUP = DebuggerResources.GROUP_CONTROL;
|
||||
|
||||
public EmulateTickBackwardAction() {
|
||||
super(plugin);
|
||||
setToolBarData(new ToolBarData(ICON, GROUP, "2"));
|
||||
addLocalAction(this);
|
||||
setEnabled(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionContext context) {
|
||||
if (current.getTrace() == null) {
|
||||
return;
|
||||
}
|
||||
TraceSchedule time = current.getTime().steppedBackward(current.getTrace(), 1);
|
||||
if (time == null) {
|
||||
return;
|
||||
}
|
||||
traceManager.activateTime(time);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnabledForContext(ActionContext context) {
|
||||
if (emulationService == null) {
|
||||
return false;
|
||||
}
|
||||
if (current.getTrace() == null) {
|
||||
return false;
|
||||
}
|
||||
if (current.getTime().steppedBackward(current.getTrace(), 1) == null) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
protected class EmulateTickForwardAction extends AbstractEmulateTickForwardAction {
|
||||
public static final String GROUP = DebuggerResources.GROUP_CONTROL;
|
||||
|
||||
public EmulateTickForwardAction() {
|
||||
super(plugin);
|
||||
setToolBarData(new ToolBarData(ICON, GROUP, "3"));
|
||||
addLocalAction(this);
|
||||
setEnabled(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionContext context) {
|
||||
if (current.getThread() == null) {
|
||||
return;
|
||||
}
|
||||
TraceSchedule time = current.getTime().steppedForward(current.getThread(), 1);
|
||||
traceManager.activateTime(time);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnabledForContext(ActionContext context) {
|
||||
if (emulationService == null) {
|
||||
return false;
|
||||
}
|
||||
if (current.getThread() == null) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
protected class StepSnapForwardAction extends AbstractStepSnapForwardAction {
|
||||
public static final String GROUP = DebuggerResources.GROUP_CONTROL;
|
||||
|
||||
public StepSnapForwardAction() {
|
||||
super(plugin);
|
||||
setToolBarData(new ToolBarData(ICON, GROUP, "4"));
|
||||
addLocalAction(this);
|
||||
setEnabled(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionContext context) {
|
||||
traceManager.activateSnap(current.getSnap() + 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnabledForContext(ActionContext context) {
|
||||
Trace curTrace = current.getTrace();
|
||||
if (curTrace == null) {
|
||||
return false;
|
||||
}
|
||||
Long maxSnap = curTrace.getTimeManager().getMaxSnap();
|
||||
if (maxSnap == null || current.getSnap() >= maxSnap) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
protected class SeekTracePresentAction extends AbstractSeekTracePresentAction
|
||||
implements BooleanChangeAdapter {
|
||||
public static final String GROUP = "zz";
|
||||
|
||||
public SeekTracePresentAction() {
|
||||
super(plugin);
|
||||
setToolBarData(new ToolBarData(ICON, GROUP));
|
||||
addLocalAction(this);
|
||||
setSelected(traceManager == null ? false : traceManager.isAutoActivatePresent());
|
||||
traceManager.addAutoActivatePresentChangeListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnabledForContext(ActionContext context) {
|
||||
return traceManager != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionContext context) {
|
||||
if (traceManager == null) {
|
||||
return;
|
||||
}
|
||||
traceManager.setAutoActivatePresent(isSelected());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void changed(Boolean value) {
|
||||
if (isSelected() == value) {
|
||||
return;
|
||||
}
|
||||
setSelected(value);
|
||||
}
|
||||
}
|
||||
|
||||
protected static class ThreadTableModel
|
||||
extends RowWrappedEnumeratedColumnTableModel< //
|
||||
ThreadTableColumns, ObjectKey, ThreadRow, TraceThread> {
|
||||
|
@ -321,9 +155,9 @@ public class DebuggerThreadsProvider extends ComponentProviderAdapter {
|
|||
|
||||
private final DebuggerThreadsPlugin plugin;
|
||||
|
||||
// @AutoServiceConsumed by method
|
||||
// @AutoServiceConsumed by method
|
||||
private DebuggerModelService modelService;
|
||||
@AutoServiceConsumed // NB, also by method
|
||||
// @AutoServiceConsumed by method
|
||||
private DebuggerTraceManagerService traceManager;
|
||||
@AutoServiceConsumed // NB, also by method
|
||||
private DebuggerEmulationService emulationService;
|
||||
|
@ -337,6 +171,10 @@ public class DebuggerThreadsProvider extends ComponentProviderAdapter {
|
|||
private final ThreadsListener threadsListener = new ThreadsListener();
|
||||
private final CollectionChangeListener<TraceRecorder> recordersListener =
|
||||
new RecordersChangeListener();
|
||||
private final BooleanChangeAdapter activatePresentChangeListener =
|
||||
this::changedAutoActivatePresent;
|
||||
private final BooleanChangeAdapter synchronizeFocusChangeListener =
|
||||
this::changedSynchronizeFocus;
|
||||
/* package access for testing */
|
||||
final RangeTableCellRenderer<Long> rangeRenderer = new RangeTableCellRenderer<>();
|
||||
final RangeCursorTableHeaderRenderer<Long> headerRenderer =
|
||||
|
@ -354,11 +192,12 @@ public class DebuggerThreadsProvider extends ComponentProviderAdapter {
|
|||
private ActionContext myActionContext;
|
||||
|
||||
DockingAction actionSaveTrace;
|
||||
StepSnapBackwardAction actionStepSnapBackward;
|
||||
EmulateTickBackwardAction actionEmulateTickBackward;
|
||||
EmulateTickForwardAction actionEmulateTickForward;
|
||||
StepSnapForwardAction actionStepSnapForward;
|
||||
SeekTracePresentAction actionSeekTracePresent;
|
||||
DockingAction actionStepSnapBackward;
|
||||
DockingAction actionEmulateTickBackward;
|
||||
DockingAction actionEmulateTickForward;
|
||||
DockingAction actionEmulateTickSkipForward;
|
||||
DockingAction actionStepSnapForward;
|
||||
ToggleDockingAction actionSeekTracePresent;
|
||||
ToggleDockingAction actionSyncFocus;
|
||||
DockingAction actionGoToTime;
|
||||
|
||||
|
@ -410,9 +249,21 @@ public class DebuggerThreadsProvider extends ComponentProviderAdapter {
|
|||
|
||||
@AutoServiceConsumed
|
||||
public void setTraceManager(DebuggerTraceManagerService traceManager) {
|
||||
if (traceManager != null && actionSeekTracePresent != null) {
|
||||
actionSeekTracePresent.setSelected(traceManager.isAutoActivatePresent());
|
||||
actionSyncFocus.setSelected(traceManager.isSynchronizeFocus());
|
||||
if (this.traceManager != null) {
|
||||
this.traceManager
|
||||
.removeAutoActivatePresentChangeListener(activatePresentChangeListener);
|
||||
this.traceManager.removeSynchronizeFocusChangeListener(synchronizeFocusChangeListener);
|
||||
}
|
||||
this.traceManager = traceManager;
|
||||
if (traceManager != null) {
|
||||
traceManager.addAutoActivatePresentChangeListener(activatePresentChangeListener);
|
||||
traceManager.addSynchronizeFocusChangeListener(synchronizeFocusChangeListener);
|
||||
if (actionSeekTracePresent != null) {
|
||||
actionSeekTracePresent.setSelected(traceManager.isAutoActivatePresent());
|
||||
}
|
||||
if (actionSyncFocus != null) {
|
||||
actionSyncFocus.setSelected(traceManager.isSynchronizeFocus());
|
||||
}
|
||||
}
|
||||
contextChanged();
|
||||
}
|
||||
|
@ -633,11 +484,34 @@ public class DebuggerThreadsProvider extends ComponentProviderAdapter {
|
|||
|
||||
protected void createActions() {
|
||||
// TODO: Make other actions use builder?
|
||||
actionStepSnapBackward = new StepSnapBackwardAction();
|
||||
actionEmulateTickBackward = new EmulateTickBackwardAction();
|
||||
actionEmulateTickForward = new EmulateTickForwardAction();
|
||||
actionStepSnapForward = new StepSnapForwardAction();
|
||||
actionSeekTracePresent = new SeekTracePresentAction();
|
||||
actionStepSnapBackward = StepSnapBackwardAction.builder(plugin)
|
||||
.enabledWhen(this::isStepSnapBackwardEnabled)
|
||||
.enabled(false)
|
||||
.onAction(this::activatedStepSnapBackward)
|
||||
.buildAndInstallLocal(this);
|
||||
actionEmulateTickBackward = EmulateTickBackwardAction.builder(plugin)
|
||||
.enabledWhen(this::isEmulateTickBackwardEnabled)
|
||||
.onAction(this::activatedEmulateTickBackward)
|
||||
.buildAndInstallLocal(this);
|
||||
actionEmulateTickForward = EmulateTickForwardAction.builder(plugin)
|
||||
.enabledWhen(this::isEmulateTickForwardEnabled)
|
||||
.onAction(this::activatedEmulateTickForward)
|
||||
.buildAndInstallLocal(this);
|
||||
actionEmulateTickSkipForward = EmulateSkipTickForwardAction.builder(plugin)
|
||||
.enabledWhen(this::isEmulateSkipTickForwardEnabled)
|
||||
.onAction(this::activatedEmulateSkipTickForward)
|
||||
.buildAndInstallLocal(this);
|
||||
actionStepSnapForward = StepSnapForwardAction.builder(plugin)
|
||||
.enabledWhen(this::isStepSnapForwardEnabled)
|
||||
.enabled(false)
|
||||
.onAction(this::activatedStepSnapForward)
|
||||
.buildAndInstallLocal(this);
|
||||
actionSeekTracePresent = SeekTracePresentAction.builder(plugin)
|
||||
.enabledWhen(this::isSeekTracePresentEnabled)
|
||||
.onAction(this::toggledSeekTracePresent)
|
||||
.selected(traceManager == null ? false : traceManager.isAutoActivatePresent())
|
||||
.buildAndInstallLocal(this);
|
||||
|
||||
actionSyncFocus = SynchronizeFocusAction.builder(plugin)
|
||||
.selected(traceManager != null && traceManager.isSynchronizeFocus())
|
||||
.enabledWhen(c -> traceManager != null)
|
||||
|
@ -672,6 +546,129 @@ public class DebuggerThreadsProvider extends ComponentProviderAdapter {
|
|||
.buildAndInstallLocal(this);
|
||||
}
|
||||
|
||||
private boolean isStepSnapBackwardEnabled(ActionContext context) {
|
||||
if (current.getTrace() == null) {
|
||||
return false;
|
||||
}
|
||||
if (!current.getTime().isSnapOnly()) {
|
||||
return true;
|
||||
}
|
||||
if (current.getSnap() <= 0) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private void activatedStepSnapBackward(ActionContext context) {
|
||||
if (current.getTime().isSnapOnly()) {
|
||||
traceManager.activateSnap(current.getSnap() - 1);
|
||||
}
|
||||
else {
|
||||
traceManager.activateSnap(current.getSnap());
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isEmulateTickBackwardEnabled(ActionContext context) {
|
||||
if (emulationService == null) {
|
||||
return false;
|
||||
}
|
||||
if (current.getTrace() == null) {
|
||||
return false;
|
||||
}
|
||||
if (current.getTime().steppedBackward(current.getTrace(), 1) == null) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private void activatedEmulateTickBackward(ActionContext context) {
|
||||
if (current.getTrace() == null) {
|
||||
return;
|
||||
}
|
||||
TraceSchedule time = current.getTime().steppedBackward(current.getTrace(), 1);
|
||||
if (time == null) {
|
||||
return;
|
||||
}
|
||||
traceManager.activateTime(time);
|
||||
}
|
||||
|
||||
private boolean isEmulateTickForwardEnabled(ActionContext context) {
|
||||
if (emulationService == null) {
|
||||
return false;
|
||||
}
|
||||
if (current.getThread() == null) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private void activatedEmulateTickForward(ActionContext context) {
|
||||
if (current.getThread() == null) {
|
||||
return;
|
||||
}
|
||||
TraceSchedule time = current.getTime().steppedForward(current.getThread(), 1);
|
||||
traceManager.activateTime(time);
|
||||
}
|
||||
|
||||
private boolean isEmulateSkipTickForwardEnabled(ActionContext context) {
|
||||
if (emulationService == null) {
|
||||
return false;
|
||||
}
|
||||
if (current.getThread() == null) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private void activatedEmulateSkipTickForward(ActionContext context) {
|
||||
if (current.getThread() == null) {
|
||||
return;
|
||||
}
|
||||
TraceSchedule time = current.getTime().skippedForward(current.getThread(), 1);
|
||||
traceManager.activateTime(time);
|
||||
}
|
||||
|
||||
private boolean isStepSnapForwardEnabled(ActionContext context) {
|
||||
Trace curTrace = current.getTrace();
|
||||
if (curTrace == null) {
|
||||
return false;
|
||||
}
|
||||
Long maxSnap = curTrace.getTimeManager().getMaxSnap();
|
||||
if (maxSnap == null || current.getSnap() >= maxSnap) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private void activatedStepSnapForward(ActionContext contetxt) {
|
||||
traceManager.activateSnap(current.getSnap() + 1);
|
||||
}
|
||||
|
||||
private boolean isSeekTracePresentEnabled(ActionContext context) {
|
||||
return traceManager != null;
|
||||
}
|
||||
|
||||
private void toggledSeekTracePresent(ActionContext context) {
|
||||
if (traceManager == null) {
|
||||
return;
|
||||
}
|
||||
traceManager.setAutoActivatePresent(actionSeekTracePresent.isSelected());
|
||||
}
|
||||
|
||||
private void changedAutoActivatePresent(boolean value) {
|
||||
if (actionSeekTracePresent == null || actionSeekTracePresent.isSelected()) {
|
||||
return;
|
||||
}
|
||||
actionSeekTracePresent.setSelected(value);
|
||||
}
|
||||
|
||||
private void changedSynchronizeFocus(boolean value) {
|
||||
if (actionSyncFocus == null || actionSyncFocus.isSelected()) {
|
||||
return;
|
||||
}
|
||||
actionSyncFocus.setSelected(value);
|
||||
}
|
||||
|
||||
private void toggleSyncFocus(boolean enabled) {
|
||||
if (traceManager == null) {
|
||||
return;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue