mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-09-28 17:11:11 -09:00
GP-533: New action in Debugger Interpreter to send interrupt
This commit is contained in:
@@ -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>
|
||||
|
||||
@@ -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";
|
||||
|
||||
@@ -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()) {
|
||||
|
||||
Reference in New Issue
Block a user