mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-06 03:50:02 +02:00
GP-1288: more visible clues
This commit is contained in:
parent
cd1b5f6592
commit
9c3084ccee
23 changed files with 454 additions and 106 deletions
|
@ -114,6 +114,20 @@ public interface DebugControl extends DebugControlReentrant {
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static enum DebugFilterOrdinals {
|
||||||
|
DEBUG_FILTER_CREATE_THREAD, //
|
||||||
|
DEBUG_FILTER_EXIT_THREAD, //
|
||||||
|
DEBUG_FILTER_CREATE_PROCESS, //
|
||||||
|
DEBUG_FILTER_EXIT_PROCESS, //
|
||||||
|
DEBUG_FILTER_LOAD_MODULE, //
|
||||||
|
DEBUG_FILTER_UNLOAD_MODULE, //
|
||||||
|
DEBUG_FILTER_SYSTEM_ERROR, //
|
||||||
|
DEBUG_FILTER_INITIAL_BREAKPOINT, //
|
||||||
|
DEBUG_FILTER_INITIAL_MODULE_LOAD, //
|
||||||
|
DEBUG_FILTER_DEBUGGEE_OUTPUT, //
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
public static enum DebugFilterExecutionOption {
|
public static enum DebugFilterExecutionOption {
|
||||||
DEBUG_FILTER_BREAK(0, "Break"), //
|
DEBUG_FILTER_BREAK(0, "Break"), //
|
||||||
DEBUG_FILTER_SECOND_CHANCE_BREAK(1, "Second-chance Break"), //
|
DEBUG_FILTER_SECOND_CHANCE_BREAK(1, "Second-chance Break"), //
|
||||||
|
|
|
@ -17,6 +17,8 @@ package agent.dbgeng.manager;
|
||||||
|
|
||||||
public interface DbgEventFilter {
|
public interface DbgEventFilter {
|
||||||
|
|
||||||
|
int getIndex();
|
||||||
|
|
||||||
String getName();
|
String getName();
|
||||||
|
|
||||||
String getCmd();
|
String getCmd();
|
||||||
|
|
|
@ -17,6 +17,7 @@ package agent.dbgeng.manager;
|
||||||
|
|
||||||
import agent.dbgeng.dbgeng.*;
|
import agent.dbgeng.dbgeng.*;
|
||||||
import agent.dbgeng.manager.breakpoint.DbgBreakpointInfo;
|
import agent.dbgeng.manager.breakpoint.DbgBreakpointInfo;
|
||||||
|
import agent.dbgeng.manager.evt.AbstractDbgEvent;
|
||||||
|
|
||||||
public interface DbgEventsListener {
|
public interface DbgEventsListener {
|
||||||
|
|
||||||
|
@ -123,6 +124,14 @@ public interface DbgEventsListener {
|
||||||
*/
|
*/
|
||||||
void threadSelected(DbgThread thread, DbgStackFrame frame, DbgCause cause);
|
void threadSelected(DbgThread thread, DbgStackFrame frame, DbgCause cause);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A system event has occurred (gained focus)
|
||||||
|
*
|
||||||
|
* @param event a handle to the current event
|
||||||
|
* @param cause the cause of this event
|
||||||
|
*/
|
||||||
|
void eventSelected(AbstractDbgEvent<?> event, DbgCause cause);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A module has been loaded by an process
|
* A module has been loaded by an process
|
||||||
*
|
*
|
||||||
|
|
|
@ -17,6 +17,7 @@ package agent.dbgeng.manager;
|
||||||
|
|
||||||
import agent.dbgeng.dbgeng.*;
|
import agent.dbgeng.dbgeng.*;
|
||||||
import agent.dbgeng.manager.breakpoint.DbgBreakpointInfo;
|
import agent.dbgeng.manager.breakpoint.DbgBreakpointInfo;
|
||||||
|
import agent.dbgeng.manager.evt.AbstractDbgEvent;
|
||||||
|
|
||||||
public interface DbgEventsListenerAdapter extends DbgEventsListener {
|
public interface DbgEventsListenerAdapter extends DbgEventsListener {
|
||||||
|
|
||||||
|
@ -82,6 +83,11 @@ public interface DbgEventsListenerAdapter extends DbgEventsListener {
|
||||||
// Extension point
|
// Extension point
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public default void eventSelected(AbstractDbgEvent<?> event, DbgCause cause) {
|
||||||
|
// Extension point
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public default void moduleLoaded(DbgProcess process, DebugModuleInfo info, DbgCause cause) {
|
public default void moduleLoaded(DbgProcess process, DebugModuleInfo info, DbgCause cause) {
|
||||||
// Extension point
|
// Extension point
|
||||||
|
|
|
@ -48,7 +48,8 @@ public class DbgListEventFiltersCommand
|
||||||
String text = control.getEventFilterText(i);
|
String text = control.getEventFilterText(i);
|
||||||
String cmd = control.getEventFilterCommand(i);
|
String cmd = control.getEventFilterCommand(i);
|
||||||
DEBUG_SPECIFIC_FILTER_PARAMETERS p = exc.getParameter(i);
|
DEBUG_SPECIFIC_FILTER_PARAMETERS p = exc.getParameter(i);
|
||||||
DbgEventFilterImpl f = new DbgEventFilterImpl(text, cmd, p.ExecutionOption.intValue(),
|
DbgEventFilterImpl f =
|
||||||
|
new DbgEventFilterImpl(i, text, cmd, p.ExecutionOption.intValue(),
|
||||||
p.ContinueOption.intValue());
|
p.ContinueOption.intValue());
|
||||||
result.add(f);
|
result.add(f);
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,7 +52,7 @@ public class DbgListExceptionFiltersCommand
|
||||||
String text = control.getEventFilterText(nEvents + i);
|
String text = control.getEventFilterText(nEvents + i);
|
||||||
String cmd = control.getEventFilterCommand(nEvents + i);
|
String cmd = control.getEventFilterCommand(nEvents + i);
|
||||||
String cmd2 = control.getExceptionFilterSecondCommand(nEvents + i);
|
String cmd2 = control.getExceptionFilterSecondCommand(nEvents + i);
|
||||||
DbgExceptionFilterImpl filter = new DbgExceptionFilterImpl(text, cmd, cmd2,
|
DbgExceptionFilterImpl filter = new DbgExceptionFilterImpl(i, text, cmd, cmd2,
|
||||||
p.ExecutionOption.intValue(), p.ContinueOption.intValue(),
|
p.ExecutionOption.intValue(), p.ContinueOption.intValue(),
|
||||||
p.ExceptionCode.longValue());
|
p.ExceptionCode.longValue());
|
||||||
result.add(filter);
|
result.add(filter);
|
||||||
|
|
|
@ -0,0 +1,60 @@
|
||||||
|
/* ###
|
||||||
|
* IP: GHIDRA
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package agent.dbgeng.manager.cmd;
|
||||||
|
|
||||||
|
import com.sun.jna.platform.win32.WinDef.ULONG;
|
||||||
|
|
||||||
|
import agent.dbgeng.dbgeng.*;
|
||||||
|
import agent.dbgeng.dbgeng.DebugControl.DebugFilterContinuationOption;
|
||||||
|
import agent.dbgeng.jna.dbgeng.DbgEngNative.DEBUG_EXCEPTION_FILTER_PARAMETERS;
|
||||||
|
import agent.dbgeng.jna.dbgeng.DbgEngNative.DEBUG_SPECIFIC_FILTER_PARAMETERS;
|
||||||
|
import agent.dbgeng.manager.impl.DbgManagerImpl;
|
||||||
|
|
||||||
|
public class DbgToggleContinuationCommand
|
||||||
|
extends AbstractDbgCommand<Void> {
|
||||||
|
|
||||||
|
private int index;
|
||||||
|
private DebugFilterContinuationOption optionCont;
|
||||||
|
|
||||||
|
public DbgToggleContinuationCommand(DbgManagerImpl manager, int index,
|
||||||
|
DebugFilterContinuationOption optionCont) {
|
||||||
|
super(manager);
|
||||||
|
this.index = index;
|
||||||
|
this.optionCont = optionCont;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void invoke() {
|
||||||
|
DebugControl control = manager.getControl();
|
||||||
|
DebugFilterInformation info = control.getNumberEventFilters();
|
||||||
|
int nEvents = info.getNumberEvents();
|
||||||
|
int nExcs = info.getNumberSpecificExceptions();
|
||||||
|
if (index < nEvents) {
|
||||||
|
DebugSpecificFilterInformation exc =
|
||||||
|
control.getSpecificFilterParameters(0, nEvents);
|
||||||
|
DEBUG_SPECIFIC_FILTER_PARAMETERS p = exc.getParameter(index);
|
||||||
|
p.ContinueOption = new ULONG(optionCont.ordinal());
|
||||||
|
control.setSpecificFilterParameters(0, nEvents, exc);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
DebugExceptionFilterInformation exc =
|
||||||
|
control.getExceptionFilterParameters(nEvents, null, nExcs);
|
||||||
|
DEBUG_EXCEPTION_FILTER_PARAMETERS p = exc.getParameter(index);
|
||||||
|
p.ContinueOption = new ULONG(optionCont.ordinal());
|
||||||
|
control.setExceptionFilterParameters(nExcs, exc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,60 @@
|
||||||
|
/* ###
|
||||||
|
* IP: GHIDRA
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package agent.dbgeng.manager.cmd;
|
||||||
|
|
||||||
|
import com.sun.jna.platform.win32.WinDef.ULONG;
|
||||||
|
|
||||||
|
import agent.dbgeng.dbgeng.*;
|
||||||
|
import agent.dbgeng.dbgeng.DebugControl.DebugFilterExecutionOption;
|
||||||
|
import agent.dbgeng.jna.dbgeng.DbgEngNative.DEBUG_EXCEPTION_FILTER_PARAMETERS;
|
||||||
|
import agent.dbgeng.jna.dbgeng.DbgEngNative.DEBUG_SPECIFIC_FILTER_PARAMETERS;
|
||||||
|
import agent.dbgeng.manager.impl.DbgManagerImpl;
|
||||||
|
|
||||||
|
public class DbgToggleExecutionCommand
|
||||||
|
extends AbstractDbgCommand<Void> {
|
||||||
|
|
||||||
|
private int index;
|
||||||
|
private DebugFilterExecutionOption optionCont;
|
||||||
|
|
||||||
|
public DbgToggleExecutionCommand(DbgManagerImpl manager, int index,
|
||||||
|
DebugFilterExecutionOption optionCont) {
|
||||||
|
super(manager);
|
||||||
|
this.index = index;
|
||||||
|
this.optionCont = optionCont;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void invoke() {
|
||||||
|
DebugControl control = manager.getControl();
|
||||||
|
DebugFilterInformation info = control.getNumberEventFilters();
|
||||||
|
int nEvents = info.getNumberEvents();
|
||||||
|
int nExcs = info.getNumberSpecificExceptions();
|
||||||
|
if (index < nEvents) {
|
||||||
|
DebugSpecificFilterInformation exc =
|
||||||
|
control.getSpecificFilterParameters(0, nEvents);
|
||||||
|
DEBUG_SPECIFIC_FILTER_PARAMETERS p = exc.getParameter(index);
|
||||||
|
p.ExecutionOption = new ULONG(optionCont.ordinal());
|
||||||
|
control.setSpecificFilterParameters(0, nEvents, exc);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
DebugExceptionFilterInformation exc =
|
||||||
|
control.getExceptionFilterParameters(nEvents, null, nExcs);
|
||||||
|
DEBUG_EXCEPTION_FILTER_PARAMETERS p = exc.getParameter(index);
|
||||||
|
p.ExecutionOption = new ULONG(optionCont.ordinal());
|
||||||
|
control.setExceptionFilterParameters(nExcs, exc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -18,18 +18,27 @@ package agent.dbgeng.manager.impl;
|
||||||
import agent.dbgeng.manager.DbgEventFilter;
|
import agent.dbgeng.manager.DbgEventFilter;
|
||||||
|
|
||||||
public class DbgEventFilterImpl implements DbgEventFilter {
|
public class DbgEventFilterImpl implements DbgEventFilter {
|
||||||
|
|
||||||
|
protected int index;
|
||||||
protected final String text;
|
protected final String text;
|
||||||
protected final String cmd;
|
protected final String cmd;
|
||||||
protected int executionOption;
|
protected int executionOption;
|
||||||
protected int continueOption;
|
protected int continueOption;
|
||||||
|
|
||||||
public DbgEventFilterImpl(String text, String cmd, int executionOption, int continueOption) {
|
public DbgEventFilterImpl(int index, String text, String cmd, int executionOption,
|
||||||
|
int continueOption) {
|
||||||
|
this.index = index;
|
||||||
this.text = text;
|
this.text = text;
|
||||||
this.cmd = cmd;
|
this.cmd = cmd;
|
||||||
this.setExecutionOption(executionOption);
|
this.setExecutionOption(executionOption);
|
||||||
this.setContinueOption(continueOption);
|
this.setContinueOption(continueOption);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getIndex() {
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return text;
|
return text;
|
||||||
|
|
|
@ -22,9 +22,10 @@ public class DbgExceptionFilterImpl extends DbgEventFilterImpl implements DbgExc
|
||||||
private final String cmd2;
|
private final String cmd2;
|
||||||
private long exceptionCode;
|
private long exceptionCode;
|
||||||
|
|
||||||
public DbgExceptionFilterImpl(String text, String cmd, String cmd2, int executionOption,
|
public DbgExceptionFilterImpl(int index, String text, String cmd, String cmd2,
|
||||||
|
int executionOption,
|
||||||
int continueOption, long exceptionCode) {
|
int continueOption, long exceptionCode) {
|
||||||
super(text, cmd, executionOption, continueOption);
|
super(index, text, cmd, executionOption, continueOption);
|
||||||
this.cmd2 = cmd2;
|
this.cmd2 = cmd2;
|
||||||
this.exceptionCode = exceptionCode;
|
this.exceptionCode = exceptionCode;
|
||||||
}
|
}
|
||||||
|
|
|
@ -685,6 +685,7 @@ public class DbgManagerImpl implements DbgManager {
|
||||||
*/
|
*/
|
||||||
protected DebugStatus processException(DbgExceptionEvent evt, Void v) {
|
protected DebugStatus processException(DbgExceptionEvent evt, Void v) {
|
||||||
DebugThreadId eventId = updateState();
|
DebugThreadId eventId = updateState();
|
||||||
|
getEventListeners().fire.eventSelected(evt, evt.getCause());
|
||||||
getEventListeners().fire.threadSelected(eventThread, null, evt.getCause());
|
getEventListeners().fire.threadSelected(eventThread, null, evt.getCause());
|
||||||
|
|
||||||
DebugExceptionRecord64 info = evt.getInfo();
|
DebugExceptionRecord64 info = evt.getInfo();
|
||||||
|
@ -710,6 +711,7 @@ public class DbgManagerImpl implements DbgManager {
|
||||||
DbgProcessImpl process = getCurrentProcess();
|
DbgProcessImpl process = getCurrentProcess();
|
||||||
int tid = so.getCurrentThreadSystemId();
|
int tid = so.getCurrentThreadSystemId();
|
||||||
DbgThreadImpl thread = getThreadComputeIfAbsent(eventId, process, tid);
|
DbgThreadImpl thread = getThreadComputeIfAbsent(eventId, process, tid);
|
||||||
|
getEventListeners().fire.eventSelected(evt, evt.getCause());
|
||||||
getEventListeners().fire.threadCreated(thread, DbgCause.Causes.UNCLAIMED);
|
getEventListeners().fire.threadCreated(thread, DbgCause.Causes.UNCLAIMED);
|
||||||
getEventListeners().fire.threadSelected(thread, null, evt.getCause());
|
getEventListeners().fire.threadSelected(thread, null, evt.getCause());
|
||||||
|
|
||||||
|
@ -735,6 +737,7 @@ public class DbgManagerImpl implements DbgManager {
|
||||||
thread.remove();
|
thread.remove();
|
||||||
}
|
}
|
||||||
process.threadExited(eventId);
|
process.threadExited(eventId);
|
||||||
|
getEventListeners().fire.eventSelected(evt, evt.getCause());
|
||||||
getEventListeners().fire.threadExited(eventId, process, evt.getCause());
|
getEventListeners().fire.threadExited(eventId, process, evt.getCause());
|
||||||
|
|
||||||
String key = Integer.toHexString(eventId.id);
|
String key = Integer.toHexString(eventId.id);
|
||||||
|
@ -783,6 +786,7 @@ public class DbgManagerImpl implements DbgManager {
|
||||||
//so.setCurrentProcessId(id);
|
//so.setCurrentProcessId(id);
|
||||||
int pid = so.getCurrentProcessSystemId();
|
int pid = so.getCurrentProcessSystemId();
|
||||||
DbgProcessImpl proc = getProcessComputeIfAbsent(id, pid);
|
DbgProcessImpl proc = getProcessComputeIfAbsent(id, pid);
|
||||||
|
getEventListeners().fire.eventSelected(evt, evt.getCause());
|
||||||
getEventListeners().fire.processAdded(proc, evt.getCause());
|
getEventListeners().fire.processAdded(proc, evt.getCause());
|
||||||
getEventListeners().fire.processSelected(proc, evt.getCause());
|
getEventListeners().fire.processSelected(proc, evt.getCause());
|
||||||
|
|
||||||
|
@ -815,8 +819,9 @@ public class DbgManagerImpl implements DbgManager {
|
||||||
DbgThreadImpl thread = getCurrentThread();
|
DbgThreadImpl thread = getCurrentThread();
|
||||||
DbgProcessImpl process = getCurrentProcess();
|
DbgProcessImpl process = getCurrentProcess();
|
||||||
process.setExitCode(Long.valueOf(evt.getInfo()));
|
process.setExitCode(Long.valueOf(evt.getInfo()));
|
||||||
getEventListeners().fire.threadExited(eventId, process, evt.getCause());
|
|
||||||
|
|
||||||
|
getEventListeners().fire.eventSelected(evt, evt.getCause());
|
||||||
|
getEventListeners().fire.threadExited(eventId, process, evt.getCause());
|
||||||
getEventListeners().fire.processExited(process, evt.getCause());
|
getEventListeners().fire.processExited(process, evt.getCause());
|
||||||
|
|
||||||
for (DebugBreakpoint bpt : getBreakpoints()) {
|
for (DebugBreakpoint bpt : getBreakpoints()) {
|
||||||
|
@ -867,6 +872,7 @@ public class DbgManagerImpl implements DbgManager {
|
||||||
DbgProcessImpl process = getCurrentProcess();
|
DbgProcessImpl process = getCurrentProcess();
|
||||||
DebugModuleInfo info = evt.getInfo();
|
DebugModuleInfo info = evt.getInfo();
|
||||||
process.moduleLoaded(info);
|
process.moduleLoaded(info);
|
||||||
|
getEventListeners().fire.eventSelected(evt, evt.getCause());
|
||||||
getEventListeners().fire.moduleLoaded(process, info, evt.getCause());
|
getEventListeners().fire.moduleLoaded(process, info, evt.getCause());
|
||||||
|
|
||||||
String key = info.getModuleName();
|
String key = info.getModuleName();
|
||||||
|
@ -888,6 +894,7 @@ public class DbgManagerImpl implements DbgManager {
|
||||||
DbgProcessImpl process = getCurrentProcess();
|
DbgProcessImpl process = getCurrentProcess();
|
||||||
DebugModuleInfo info = evt.getInfo();
|
DebugModuleInfo info = evt.getInfo();
|
||||||
process.moduleUnloaded(info);
|
process.moduleUnloaded(info);
|
||||||
|
getEventListeners().fire.eventSelected(evt, evt.getCause());
|
||||||
getEventListeners().fire.moduleUnloaded(process, info, evt.getCause());
|
getEventListeners().fire.moduleUnloaded(process, info, evt.getCause());
|
||||||
|
|
||||||
String key = info.getModuleName();
|
String key = info.getModuleName();
|
||||||
|
|
|
@ -42,4 +42,6 @@ public abstract class AbstractDbgModel extends AbstractDebuggerObjectModel {
|
||||||
|
|
||||||
public abstract TargetObject getModelObject(Object object);
|
public abstract TargetObject getModelObject(Object object);
|
||||||
|
|
||||||
|
public abstract void deleteModelObject(Object object);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,15 +15,18 @@
|
||||||
*/
|
*/
|
||||||
package agent.dbgeng.model.iface2;
|
package agent.dbgeng.model.iface2;
|
||||||
|
|
||||||
import agent.dbgeng.manager.DbgEventFilter;
|
import agent.dbgeng.manager.*;
|
||||||
|
import agent.dbgeng.manager.evt.AbstractDbgEvent;
|
||||||
|
import agent.dbgeng.model.iface1.DbgModelSelectableObject;
|
||||||
|
|
||||||
public interface DbgModelTargetEvent extends DbgModelTargetObject {
|
public interface DbgModelTargetEvent extends DbgModelSelectableObject, DbgEventsListenerAdapter //
|
||||||
|
{
|
||||||
@Override
|
|
||||||
public default String getDisplay() {
|
|
||||||
return getName();
|
|
||||||
}
|
|
||||||
|
|
||||||
public DbgEventFilter getFilter();
|
public DbgEventFilter getFilter();
|
||||||
|
|
||||||
|
public int getEventIndex();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
void eventSelected(AbstractDbgEvent<?> event, DbgCause cause);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,9 +19,4 @@ import ghidra.dbg.target.TargetTogglable;
|
||||||
|
|
||||||
public interface DbgModelTargetEventOption extends DbgModelTargetObject, TargetTogglable {
|
public interface DbgModelTargetEventOption extends DbgModelTargetObject, TargetTogglable {
|
||||||
|
|
||||||
@Override
|
|
||||||
public default String getDisplay() {
|
|
||||||
return getName();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,12 +17,7 @@ package agent.dbgeng.model.iface2;
|
||||||
|
|
||||||
import agent.dbgeng.manager.DbgExceptionFilter;
|
import agent.dbgeng.manager.DbgExceptionFilter;
|
||||||
|
|
||||||
public interface DbgModelTargetException extends DbgModelTargetObject {
|
public interface DbgModelTargetException extends DbgModelTargetEvent {
|
||||||
|
|
||||||
@Override
|
|
||||||
public default String getDisplay() {
|
|
||||||
return getName();
|
|
||||||
}
|
|
||||||
|
|
||||||
public DbgExceptionFilter getFilter();
|
public DbgExceptionFilter getFilter();
|
||||||
|
|
||||||
|
|
|
@ -164,6 +164,7 @@ public class DbgModelImpl extends AbstractDbgModel implements DebuggerObjectMode
|
||||||
return objectMap.get(object);
|
return objectMap.get(object);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void deleteModelObject(Object object) {
|
public void deleteModelObject(Object object) {
|
||||||
objectMap.remove(object);
|
objectMap.remove(object);
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,75 +20,66 @@ import java.util.Map;
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
|
||||||
import agent.dbgeng.dbgeng.DebugControl.DebugFilterContinuationOption;
|
import agent.dbgeng.dbgeng.DebugControl.DebugFilterContinuationOption;
|
||||||
import agent.dbgeng.dbgeng.DebugControl.DebugFilterExecutionOption;
|
import agent.dbgeng.manager.cmd.DbgToggleContinuationCommand;
|
||||||
|
import agent.dbgeng.manager.impl.DbgManagerImpl;
|
||||||
import agent.dbgeng.model.iface2.*;
|
import agent.dbgeng.model.iface2.*;
|
||||||
import ghidra.dbg.target.schema.*;
|
import ghidra.dbg.target.schema.*;
|
||||||
import ghidra.dbg.util.PathUtils;
|
|
||||||
|
|
||||||
@TargetObjectSchemaInfo(
|
@TargetObjectSchemaInfo(
|
||||||
name = "Event",
|
name = "ContinuationFilter",
|
||||||
elements = {
|
elements = {
|
||||||
@TargetElementType(type = Void.class) },
|
@TargetElementType(type = Void.class) },
|
||||||
attributes = {
|
attributes = {
|
||||||
@TargetAttributeType(type = Object.class) })
|
@TargetAttributeType(type = Object.class) })
|
||||||
public class DbgModelTargetEventOptionImpl extends DbgModelTargetObjectImpl
|
public class DbgModelTargetContinuationOptionImpl extends DbgModelTargetObjectImpl
|
||||||
implements DbgModelTargetEventOption {
|
implements DbgModelTargetEventOption {
|
||||||
|
|
||||||
protected static String keyFilter(DebugFilterExecutionOption option) {
|
private DbgModelTargetEvent event;
|
||||||
return PathUtils.makeKey(option.description);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected static String keyFilter(DebugFilterContinuationOption option) {
|
|
||||||
return PathUtils.makeKey(option.description);
|
|
||||||
}
|
|
||||||
|
|
||||||
private DebugFilterExecutionOption optionEx;
|
|
||||||
private DebugFilterContinuationOption optionCont;
|
private DebugFilterContinuationOption optionCont;
|
||||||
|
|
||||||
public DbgModelTargetEventOptionImpl(DbgModelTargetEvent event,
|
public DbgModelTargetContinuationOptionImpl(DbgModelTargetEvent event,
|
||||||
DebugFilterExecutionOption option) {
|
DebugFilterContinuationOption option) {
|
||||||
super(event.getModel(), event, keyFilter(option), "EventFilter");
|
super(event.getModel(), event, "Continue", "ContinuationFilter");
|
||||||
this.getModel().addModelObject(option, this);
|
this.getModel().addModelObject(option, this);
|
||||||
this.optionEx = option;
|
this.event = event;
|
||||||
|
this.optionCont = option;
|
||||||
|
setAttributes();
|
||||||
}
|
}
|
||||||
|
|
||||||
public DbgModelTargetEventOptionImpl(DbgModelTargetEvent event,
|
public DbgModelTargetContinuationOptionImpl(DbgModelTargetException exc,
|
||||||
DebugFilterContinuationOption option) {
|
DebugFilterContinuationOption option) {
|
||||||
super(event.getModel(), event, keyFilter(option), "EventFilter");
|
super(exc.getModel(), exc, "Continue", "ContinuationFilter");
|
||||||
this.getModel().addModelObject(option, this);
|
this.event = exc;
|
||||||
this.optionCont = option;
|
|
||||||
}
|
|
||||||
|
|
||||||
public DbgModelTargetEventOptionImpl(DbgModelTargetException exc,
|
|
||||||
DebugFilterExecutionOption option) {
|
|
||||||
super(exc.getModel(), exc, keyFilter(option), "EventFilter");
|
|
||||||
this.getModel().addModelObject(option, this);
|
|
||||||
this.optionEx = option;
|
|
||||||
}
|
|
||||||
|
|
||||||
public DbgModelTargetEventOptionImpl(DbgModelTargetException exc,
|
|
||||||
DebugFilterContinuationOption option) {
|
|
||||||
super(exc.getModel(), exc, keyFilter(option), "EventFilter");
|
|
||||||
this.getModel().addModelObject(option, this);
|
this.getModel().addModelObject(option, this);
|
||||||
this.optionCont = option;
|
this.optionCont = option;
|
||||||
|
setAttributes();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CompletableFuture<Void> disable() {
|
public CompletableFuture<Void> disable() {
|
||||||
// TODO Auto-generated method stub
|
DbgManagerImpl manager = getManager();
|
||||||
return null;
|
optionCont = DebugFilterContinuationOption.DEBUG_FILTER_GO_NOT_HANDLED;
|
||||||
|
setAttributes();
|
||||||
|
return manager.execute(
|
||||||
|
new DbgToggleContinuationCommand(manager, event.getEventIndex(), optionCont));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CompletableFuture<Void> enable() {
|
public CompletableFuture<Void> enable() {
|
||||||
// TODO Auto-generated method stub
|
DbgManagerImpl manager = getManager();
|
||||||
return null;
|
optionCont = DebugFilterContinuationOption.DEBUG_FILTER_GO_HANDLED;
|
||||||
|
setAttributes();
|
||||||
|
return manager.execute(
|
||||||
|
new DbgToggleContinuationCommand(manager, event.getEventIndex(), optionCont));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setAttributes() {
|
public void setAttributes() {
|
||||||
changeAttributes(List.of(), List.of(), Map.of( //
|
changeAttributes(List.of(), List.of(), Map.of( //
|
||||||
DISPLAY_ATTRIBUTE_NAME, getName() //
|
DISPLAY_ATTRIBUTE_NAME, getName() + " : " + optionCont.description, //
|
||||||
), "Initialized");
|
VALUE_ATTRIBUTE_NAME, optionCont, //
|
||||||
|
ENABLED_ATTRIBUTE_NAME,
|
||||||
|
optionCont.equals(DebugFilterContinuationOption.DEBUG_FILTER_GO_HANDLED)),
|
||||||
|
"Refreshed");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -18,9 +18,10 @@ package agent.dbgeng.model.impl;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import agent.dbgeng.dbgeng.DebugControl.DebugFilterContinuationOption;
|
import agent.dbgeng.dbgeng.DebugControl.*;
|
||||||
import agent.dbgeng.dbgeng.DebugControl.DebugFilterExecutionOption;
|
import agent.dbgeng.manager.DbgCause;
|
||||||
import agent.dbgeng.manager.DbgEventFilter;
|
import agent.dbgeng.manager.DbgEventFilter;
|
||||||
|
import agent.dbgeng.manager.evt.*;
|
||||||
import agent.dbgeng.model.iface2.*;
|
import agent.dbgeng.model.iface2.*;
|
||||||
import ghidra.dbg.target.schema.*;
|
import ghidra.dbg.target.schema.*;
|
||||||
import ghidra.dbg.util.PathUtils;
|
import ghidra.dbg.util.PathUtils;
|
||||||
|
@ -55,8 +56,8 @@ public class DbgModelTargetEventImpl extends DbgModelTargetObjectImpl
|
||||||
DebugFilterExecutionOption.getByNumber(filter.getExecutionOption());
|
DebugFilterExecutionOption.getByNumber(filter.getExecutionOption());
|
||||||
DebugFilterContinuationOption cont =
|
DebugFilterContinuationOption cont =
|
||||||
DebugFilterContinuationOption.getByNumber(filter.getContinueOption());
|
DebugFilterContinuationOption.getByNumber(filter.getContinueOption());
|
||||||
execOption = new DbgModelTargetEventOptionImpl(this, exec);
|
execOption = new DbgModelTargetExecutionOptionImpl(this, exec);
|
||||||
contOption = new DbgModelTargetEventOptionImpl(this, cont);
|
contOption = new DbgModelTargetContinuationOptionImpl(this, cont);
|
||||||
|
|
||||||
changeAttributes(List.of(), List.of(), Map.of( //
|
changeAttributes(List.of(), List.of(), Map.of( //
|
||||||
DISPLAY_ATTRIBUTE_NAME, getIndex(), //
|
DISPLAY_ATTRIBUTE_NAME, getIndex(), //
|
||||||
|
@ -64,6 +65,8 @@ public class DbgModelTargetEventImpl extends DbgModelTargetObjectImpl
|
||||||
"Execute", execOption, //
|
"Execute", execOption, //
|
||||||
"Continue", contOption //
|
"Continue", contOption //
|
||||||
), "Initialized");
|
), "Initialized");
|
||||||
|
|
||||||
|
getManager().addEventsListener(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -71,4 +74,44 @@ public class DbgModelTargetEventImpl extends DbgModelTargetObjectImpl
|
||||||
return filter;
|
return filter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getEventIndex() {
|
||||||
|
return filter.getIndex();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void eventSelected(AbstractDbgEvent<?> event, DbgCause cause) {
|
||||||
|
changeAttributes(List.of(), List.of(), Map.of( //
|
||||||
|
MODIFIED_ATTRIBUTE_NAME, false), "Refreshed");
|
||||||
|
if (event instanceof DbgThreadCreatedEvent &&
|
||||||
|
getEventIndex() == DebugFilterOrdinals.DEBUG_FILTER_CREATE_THREAD.ordinal()) {
|
||||||
|
changeAttributes(List.of(), List.of(), Map.of( //
|
||||||
|
MODIFIED_ATTRIBUTE_NAME, true), "Refreshed");
|
||||||
|
}
|
||||||
|
if (event instanceof DbgThreadExitedEvent &&
|
||||||
|
getEventIndex() == DebugFilterOrdinals.DEBUG_FILTER_EXIT_THREAD.ordinal()) {
|
||||||
|
changeAttributes(List.of(), List.of(), Map.of( //
|
||||||
|
MODIFIED_ATTRIBUTE_NAME, true), "Refreshed");
|
||||||
|
}
|
||||||
|
if (event instanceof DbgProcessCreatedEvent &&
|
||||||
|
getEventIndex() == DebugFilterOrdinals.DEBUG_FILTER_CREATE_PROCESS.ordinal()) {
|
||||||
|
changeAttributes(List.of(), List.of(), Map.of( //
|
||||||
|
MODIFIED_ATTRIBUTE_NAME, true), "Refreshed");
|
||||||
|
}
|
||||||
|
if (event instanceof DbgProcessExitedEvent &&
|
||||||
|
getEventIndex() == DebugFilterOrdinals.DEBUG_FILTER_EXIT_PROCESS.ordinal()) {
|
||||||
|
changeAttributes(List.of(), List.of(), Map.of( //
|
||||||
|
MODIFIED_ATTRIBUTE_NAME, true), "Refreshed");
|
||||||
|
}
|
||||||
|
if (event instanceof DbgModuleLoadedEvent &&
|
||||||
|
getEventIndex() == DebugFilterOrdinals.DEBUG_FILTER_LOAD_MODULE.ordinal()) {
|
||||||
|
changeAttributes(List.of(), List.of(), Map.of( //
|
||||||
|
MODIFIED_ATTRIBUTE_NAME, true), "Refreshed");
|
||||||
|
}
|
||||||
|
if (event instanceof DbgModuleUnloadedEvent &&
|
||||||
|
getEventIndex() == DebugFilterOrdinals.DEBUG_FILTER_UNLOAD_MODULE.ordinal()) {
|
||||||
|
changeAttributes(List.of(), List.of(), Map.of( //
|
||||||
|
MODIFIED_ATTRIBUTE_NAME, true), "Refreshed");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,8 +20,14 @@ import java.util.Map;
|
||||||
|
|
||||||
import agent.dbgeng.dbgeng.DebugControl.DebugFilterContinuationOption;
|
import agent.dbgeng.dbgeng.DebugControl.DebugFilterContinuationOption;
|
||||||
import agent.dbgeng.dbgeng.DebugControl.DebugFilterExecutionOption;
|
import agent.dbgeng.dbgeng.DebugControl.DebugFilterExecutionOption;
|
||||||
|
import agent.dbgeng.dbgeng.DebugExceptionRecord64;
|
||||||
|
import agent.dbgeng.manager.DbgCause;
|
||||||
import agent.dbgeng.manager.DbgExceptionFilter;
|
import agent.dbgeng.manager.DbgExceptionFilter;
|
||||||
|
import agent.dbgeng.manager.evt.AbstractDbgEvent;
|
||||||
|
import agent.dbgeng.manager.evt.DbgExceptionEvent;
|
||||||
|
import agent.dbgeng.model.iface1.DbgModelTargetFocusScope;
|
||||||
import agent.dbgeng.model.iface2.*;
|
import agent.dbgeng.model.iface2.*;
|
||||||
|
import ghidra.dbg.target.TargetFocusScope;
|
||||||
import ghidra.dbg.target.schema.*;
|
import ghidra.dbg.target.schema.*;
|
||||||
import ghidra.dbg.util.PathUtils;
|
import ghidra.dbg.util.PathUtils;
|
||||||
|
|
||||||
|
@ -56,8 +62,8 @@ public class DbgModelTargetExceptionImpl extends DbgModelTargetObjectImpl
|
||||||
DebugFilterExecutionOption.getByNumber(filter.getExecutionOption());
|
DebugFilterExecutionOption.getByNumber(filter.getExecutionOption());
|
||||||
DebugFilterContinuationOption cont =
|
DebugFilterContinuationOption cont =
|
||||||
DebugFilterContinuationOption.getByNumber(filter.getContinueOption());
|
DebugFilterContinuationOption.getByNumber(filter.getContinueOption());
|
||||||
execOption = new DbgModelTargetEventOptionImpl(this, exec);
|
execOption = new DbgModelTargetExecutionOptionImpl(this, exec);
|
||||||
contOption = new DbgModelTargetEventOptionImpl(this, cont);
|
contOption = new DbgModelTargetContinuationOptionImpl(this, cont);
|
||||||
|
|
||||||
changeAttributes(List.of(), List.of(), Map.of( //
|
changeAttributes(List.of(), List.of(), Map.of( //
|
||||||
DISPLAY_ATTRIBUTE_NAME, getIndex(), //
|
DISPLAY_ATTRIBUTE_NAME, getIndex(), //
|
||||||
|
@ -67,6 +73,8 @@ public class DbgModelTargetExceptionImpl extends DbgModelTargetObjectImpl
|
||||||
"Continue", contOption, //
|
"Continue", contOption, //
|
||||||
"Exception", filter.getExceptionCode() //
|
"Exception", filter.getExceptionCode() //
|
||||||
), "Initialized");
|
), "Initialized");
|
||||||
|
|
||||||
|
getManager().addEventsListener(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -74,4 +82,23 @@ public class DbgModelTargetExceptionImpl extends DbgModelTargetObjectImpl
|
||||||
return filter;
|
return filter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getEventIndex() {
|
||||||
|
return filter.getIndex();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void eventSelected(AbstractDbgEvent<?> event, DbgCause cause) {
|
||||||
|
changeAttributes(List.of(), List.of(), Map.of( //
|
||||||
|
MODIFIED_ATTRIBUTE_NAME, false), "Refreshed");
|
||||||
|
if (event instanceof DbgExceptionEvent) {
|
||||||
|
DebugExceptionRecord64 info = (DebugExceptionRecord64) event.getInfo();
|
||||||
|
if (info.code == Long.parseLong(filter.getExceptionCode(), 16)) {
|
||||||
|
((DbgModelTargetFocusScope) searchForSuitable(TargetFocusScope.class))
|
||||||
|
.setFocus(this);
|
||||||
|
changeAttributes(List.of(), List.of(), Map.of( //
|
||||||
|
MODIFIED_ATTRIBUTE_NAME, true), "Refreshed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,81 @@
|
||||||
|
/* ###
|
||||||
|
* IP: GHIDRA
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package agent.dbgeng.model.impl;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
|
||||||
|
import agent.dbgeng.dbgeng.DebugControl.DebugFilterExecutionOption;
|
||||||
|
import agent.dbgeng.manager.cmd.DbgToggleExecutionCommand;
|
||||||
|
import agent.dbgeng.manager.impl.DbgManagerImpl;
|
||||||
|
import agent.dbgeng.model.iface2.*;
|
||||||
|
import ghidra.dbg.target.schema.*;
|
||||||
|
|
||||||
|
@TargetObjectSchemaInfo(
|
||||||
|
name = "ExecutionFilter",
|
||||||
|
elements = {
|
||||||
|
@TargetElementType(type = Void.class) },
|
||||||
|
attributes = {
|
||||||
|
@TargetAttributeType(type = Object.class) })
|
||||||
|
public class DbgModelTargetExecutionOptionImpl extends DbgModelTargetObjectImpl
|
||||||
|
implements DbgModelTargetEventOption {
|
||||||
|
|
||||||
|
private DbgModelTargetEvent event;
|
||||||
|
private DebugFilterExecutionOption optionExc;
|
||||||
|
|
||||||
|
public DbgModelTargetExecutionOptionImpl(DbgModelTargetEvent event,
|
||||||
|
DebugFilterExecutionOption option) {
|
||||||
|
super(event.getModel(), event, "Execute", "ExecutionFilter");
|
||||||
|
this.event = event;
|
||||||
|
this.getModel().addModelObject(option, this);
|
||||||
|
this.optionExc = option;
|
||||||
|
setAttributes();
|
||||||
|
}
|
||||||
|
|
||||||
|
public DbgModelTargetExecutionOptionImpl(DbgModelTargetException exc,
|
||||||
|
DebugFilterExecutionOption option) {
|
||||||
|
super(exc.getModel(), exc, "Execute", "ExecutionFilter");
|
||||||
|
this.event = exc;
|
||||||
|
this.getModel().addModelObject(option, this);
|
||||||
|
this.optionExc = option;
|
||||||
|
setAttributes();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CompletableFuture<Void> disable() {
|
||||||
|
return enable();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CompletableFuture<Void> enable() {
|
||||||
|
DbgManagerImpl manager = getManager();
|
||||||
|
int ordinal = (optionExc.ordinal() + 1) % (DebugFilterExecutionOption.values().length - 1);
|
||||||
|
optionExc = DebugFilterExecutionOption.getByNumber(ordinal);
|
||||||
|
setAttributes();
|
||||||
|
return manager.execute(
|
||||||
|
new DbgToggleExecutionCommand(manager, event.getEventIndex(), optionExc));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAttributes() {
|
||||||
|
changeAttributes(List.of(), List.of(), Map.of( //
|
||||||
|
DISPLAY_ATTRIBUTE_NAME, getName() + " : " + optionExc.description, //
|
||||||
|
VALUE_ATTRIBUTE_NAME, optionExc, //
|
||||||
|
ENABLED_ATTRIBUTE_NAME,
|
||||||
|
optionExc.equals(DebugFilterExecutionOption.DEBUG_FILTER_BREAK)), "Refreshed");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -182,6 +182,11 @@ public class DbgModel2Impl extends AbstractDbgModel
|
||||||
return objectMap.get(object);
|
return objectMap.get(object);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void deleteModelObject(Object object) {
|
||||||
|
objectMap.remove(object);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T> CompletableFuture<T> gateFuture(CompletableFuture<T> future) {
|
public <T> CompletableFuture<T> gateFuture(CompletableFuture<T> future) {
|
||||||
return super.gateFuture(future).exceptionally(ex -> {
|
return super.gateFuture(future).exceptionally(ex -> {
|
||||||
|
|
|
@ -1210,6 +1210,22 @@ public interface DebuggerResources {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
abstract class AbstractToggleAction extends DockingAction {
|
||||||
|
public static final String NAME = "Toggle";
|
||||||
|
public static final Icon ICON = ICON_BREAKPOINT_MIXED_ED_MARKER;
|
||||||
|
public static final String HELP_ANCHOR = "toggle_option";
|
||||||
|
|
||||||
|
public static HelpLocation help(Plugin owner) {
|
||||||
|
return new HelpLocation(owner.getName(), HELP_ANCHOR);
|
||||||
|
}
|
||||||
|
|
||||||
|
public AbstractToggleAction(Plugin owner) {
|
||||||
|
super(NAME, owner.getName());
|
||||||
|
setDescription("Enable or disable an option");
|
||||||
|
setHelpLocation(new HelpLocation(owner.getName(), HELP_ANCHOR));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
interface MapIdenticallyAction {
|
interface MapIdenticallyAction {
|
||||||
String NAME = "Map Identically";
|
String NAME = "Map Identically";
|
||||||
String DESCRIPTION =
|
String DESCRIPTION =
|
||||||
|
|
|
@ -1221,6 +1221,20 @@ public class DebuggerObjectsProvider extends ComponentProviderAdapter
|
||||||
|
|
||||||
groupTargetIndex++;
|
groupTargetIndex++;
|
||||||
|
|
||||||
|
new ActionBuilder("Toggle", plugin.getName())
|
||||||
|
.keyBinding("T")
|
||||||
|
.toolBarGroup(DebuggerResources.GROUP_CONTROL, "X" + groupTargetIndex)
|
||||||
|
.popupMenuPath("&Toggle")
|
||||||
|
.popupMenuGroup(DebuggerResources.GROUP_CONTROL, "X" + groupTargetIndex)
|
||||||
|
.helpLocation(AbstractToggleAction.help(plugin))
|
||||||
|
.enabledWhen(ctx -> isInstance(ctx, TargetTogglable.class))
|
||||||
|
.popupWhen(ctx -> isInstance(ctx, TargetResumable.class))
|
||||||
|
.onAction(ctx -> performToggle(ctx))
|
||||||
|
.enabled(false)
|
||||||
|
.buildAndInstallLocal(this);
|
||||||
|
|
||||||
|
groupTargetIndex++;
|
||||||
|
|
||||||
displayAsTreeAction = new DisplayAsTreeAction(tool, plugin.getName(), this);
|
displayAsTreeAction = new DisplayAsTreeAction(tool, plugin.getName(), this);
|
||||||
displayAsTableAction = new DisplayAsTableAction(tool, plugin.getName(), this);
|
displayAsTableAction = new DisplayAsTableAction(tool, plugin.getName(), this);
|
||||||
displayAsGraphAction = new DisplayAsGraphAction(tool, plugin.getName(), this);
|
displayAsGraphAction = new DisplayAsGraphAction(tool, plugin.getName(), this);
|
||||||
|
@ -1486,6 +1500,12 @@ public class DebuggerObjectsProvider extends ComponentProviderAdapter
|
||||||
}, "Couldn't set breakpoint");
|
}, "Couldn't set breakpoint");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void performToggle(ActionContext context) {
|
||||||
|
performAction(context, false, TargetTogglable.class, t -> {
|
||||||
|
return t.toggle(!t.isEnabled());
|
||||||
|
}, "Couldn't toggle");
|
||||||
|
}
|
||||||
|
|
||||||
public void initiateConsole(ActionContext context) {
|
public void initiateConsole(ActionContext context) {
|
||||||
performAction(context, false, TargetInterpreter.class, interpreter -> {
|
performAction(context, false, TargetInterpreter.class, interpreter -> {
|
||||||
getPlugin().showConsole(interpreter);
|
getPlugin().showConsole(interpreter);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue