GP-533: New action in Debugger Interpreter to send interrupt

This commit is contained in:
Ryan Kurtz
2021-05-05 11:06:10 -04:00
committed by Dan
parent a2b7fbfef2
commit 70996c9896
3 changed files with 42 additions and 2 deletions

View File

@@ -42,5 +42,9 @@
immediately upon the associated target interpreter becoming invalid, i.e., the connection was
closed. Pinning an interpreter keeps it open, but in a disabled state, so that the buffer can
be examined after invalidation.</P>
<H3><A name="interrupt"></A>Interrupt</H3>
<P>This action is always available. It interrupts the current target's execution.</P>
</BODY>
</HTML>

View File

@@ -645,6 +645,22 @@ public interface DebuggerResources {
.helpLocation(new HelpLocation(ownerName, HELP_ANCHOR));
}
}
interface InterpreterInterruptAction {
String NAME = "Interpreter Interrupt";
String DESCRIPTION = "Send an interrupt through this Interpreter";
Icon ICON = ICON_TERMINATE;
String HELP_ANCHOR = "interrupt";
public static ActionBuilder builder(Plugin owner) {
String ownerName = owner.getName();
return new ActionBuilder(ownerName, NAME)
.description(DESCRIPTION)
.toolBarIcon(ICON)
.keyBinding("CTRL I")
.helpLocation(new HelpLocation(ownerName, HELP_ANCHOR));
}
}
abstract class AbstractRecordAction extends DockingAction {
public static final String NAME = "Record";

View File

@@ -25,16 +25,18 @@ import java.util.concurrent.atomic.AtomicBoolean;
import javax.swing.ImageIcon;
import docking.ActionContext;
import docking.action.DockingAction;
import docking.action.ToggleDockingAction;
import ghidra.app.plugin.core.console.CodeCompletion;
import ghidra.app.plugin.core.debug.gui.DebuggerResources;
import ghidra.app.plugin.core.debug.gui.DebuggerResources.InterpreterInterruptAction;
import ghidra.app.plugin.core.debug.gui.DebuggerResources.PinInterpreterAction;
import ghidra.app.plugin.core.interpreter.InterpreterComponentProvider;
import ghidra.app.plugin.core.interpreter.InterpreterConsole;
import ghidra.dbg.AnnotatedDebuggerAttributeListener;
import ghidra.dbg.DebugModelConventions;
import ghidra.dbg.target.*;
import ghidra.dbg.target.TargetConsole.Channel;
import ghidra.dbg.target.TargetInterpreter;
import ghidra.dbg.target.TargetObject;
import ghidra.util.Msg;
import ghidra.util.Swing;
@@ -191,6 +193,11 @@ public abstract class AbstractDebuggerWrappedConsoleConnection<T extends TargetO
.selected(pinned)
.build();
guiConsole.addAction(actionPin);
DockingAction interruptAction = InterpreterInterruptAction.builder(plugin)
.onAction(this::sendInterrupt)
.build();
guiConsole.addAction(interruptAction);
}
public void setStdOut(OutputStream stdOut) {
@@ -215,6 +222,19 @@ public abstract class AbstractDebuggerWrappedConsoleConnection<T extends TargetO
pinned = actionPin.isSelected();
}
private void sendInterrupt(ActionContext ignore) {
CompletableFuture<TargetInterruptible> futureInterruptible =
DebugModelConventions.suitable(TargetInterruptible.class, targetConsole);
if (futureInterruptible != null) {
futureInterruptible.thenCompose(i -> i.interrupt())
.thenRun(() -> guiConsole.getOutWriter().println("Interrupt sent"))
.exceptionally(exc -> {
guiConsole.getErrWriter().println("Failed to send Interrupt");
return null;
});
}
}
protected void run() {
try {
while (running.get()) {