GP-1288: more visible clues

This commit is contained in:
d-millar 2021-09-22 22:05:28 +00:00
parent cd1b5f6592
commit 9c3084ccee
23 changed files with 454 additions and 106 deletions

View File

@ -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 {
DEBUG_FILTER_BREAK(0, "Break"), //
DEBUG_FILTER_SECOND_CHANCE_BREAK(1, "Second-chance Break"), //

View File

@ -17,6 +17,8 @@ package agent.dbgeng.manager;
public interface DbgEventFilter {
int getIndex();
String getName();
String getCmd();

View File

@ -17,6 +17,7 @@ package agent.dbgeng.manager;
import agent.dbgeng.dbgeng.*;
import agent.dbgeng.manager.breakpoint.DbgBreakpointInfo;
import agent.dbgeng.manager.evt.AbstractDbgEvent;
public interface DbgEventsListener {
@ -123,6 +124,14 @@ public interface DbgEventsListener {
*/
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
*

View File

@ -17,6 +17,7 @@ package agent.dbgeng.manager;
import agent.dbgeng.dbgeng.*;
import agent.dbgeng.manager.breakpoint.DbgBreakpointInfo;
import agent.dbgeng.manager.evt.AbstractDbgEvent;
public interface DbgEventsListenerAdapter extends DbgEventsListener {
@ -82,6 +83,11 @@ public interface DbgEventsListenerAdapter extends DbgEventsListener {
// Extension point
}
@Override
public default void eventSelected(AbstractDbgEvent<?> event, DbgCause cause) {
// Extension point
}
@Override
public default void moduleLoaded(DbgProcess process, DebugModuleInfo info, DbgCause cause) {
// Extension point

View File

@ -48,8 +48,9 @@ public class DbgListEventFiltersCommand
String text = control.getEventFilterText(i);
String cmd = control.getEventFilterCommand(i);
DEBUG_SPECIFIC_FILTER_PARAMETERS p = exc.getParameter(i);
DbgEventFilterImpl f = new DbgEventFilterImpl(text, cmd, p.ExecutionOption.intValue(),
p.ContinueOption.intValue());
DbgEventFilterImpl f =
new DbgEventFilterImpl(i, text, cmd, p.ExecutionOption.intValue(),
p.ContinueOption.intValue());
result.add(f);
}
}

View File

@ -52,7 +52,7 @@ public class DbgListExceptionFiltersCommand
String text = control.getEventFilterText(nEvents + i);
String cmd = control.getEventFilterCommand(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.ExceptionCode.longValue());
result.add(filter);

View File

@ -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);
}
}
}

View File

@ -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);
}
}
}

View File

@ -18,18 +18,27 @@ package agent.dbgeng.manager.impl;
import agent.dbgeng.manager.DbgEventFilter;
public class DbgEventFilterImpl implements DbgEventFilter {
protected int index;
protected final String text;
protected final String cmd;
protected int executionOption;
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.cmd = cmd;
this.setExecutionOption(executionOption);
this.setContinueOption(continueOption);
}
@Override
public int getIndex() {
return index;
}
@Override
public String getName() {
return text;

View File

@ -22,9 +22,10 @@ public class DbgExceptionFilterImpl extends DbgEventFilterImpl implements DbgExc
private final String cmd2;
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) {
super(text, cmd, executionOption, continueOption);
super(index, text, cmd, executionOption, continueOption);
this.cmd2 = cmd2;
this.exceptionCode = exceptionCode;
}

View File

@ -685,6 +685,7 @@ public class DbgManagerImpl implements DbgManager {
*/
protected DebugStatus processException(DbgExceptionEvent evt, Void v) {
DebugThreadId eventId = updateState();
getEventListeners().fire.eventSelected(evt, evt.getCause());
getEventListeners().fire.threadSelected(eventThread, null, evt.getCause());
DebugExceptionRecord64 info = evt.getInfo();
@ -710,6 +711,7 @@ public class DbgManagerImpl implements DbgManager {
DbgProcessImpl process = getCurrentProcess();
int tid = so.getCurrentThreadSystemId();
DbgThreadImpl thread = getThreadComputeIfAbsent(eventId, process, tid);
getEventListeners().fire.eventSelected(evt, evt.getCause());
getEventListeners().fire.threadCreated(thread, DbgCause.Causes.UNCLAIMED);
getEventListeners().fire.threadSelected(thread, null, evt.getCause());
@ -735,6 +737,7 @@ public class DbgManagerImpl implements DbgManager {
thread.remove();
}
process.threadExited(eventId);
getEventListeners().fire.eventSelected(evt, evt.getCause());
getEventListeners().fire.threadExited(eventId, process, evt.getCause());
String key = Integer.toHexString(eventId.id);
@ -783,6 +786,7 @@ public class DbgManagerImpl implements DbgManager {
//so.setCurrentProcessId(id);
int pid = so.getCurrentProcessSystemId();
DbgProcessImpl proc = getProcessComputeIfAbsent(id, pid);
getEventListeners().fire.eventSelected(evt, evt.getCause());
getEventListeners().fire.processAdded(proc, evt.getCause());
getEventListeners().fire.processSelected(proc, evt.getCause());
@ -815,8 +819,9 @@ public class DbgManagerImpl implements DbgManager {
DbgThreadImpl thread = getCurrentThread();
DbgProcessImpl process = getCurrentProcess();
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());
for (DebugBreakpoint bpt : getBreakpoints()) {
@ -867,6 +872,7 @@ public class DbgManagerImpl implements DbgManager {
DbgProcessImpl process = getCurrentProcess();
DebugModuleInfo info = evt.getInfo();
process.moduleLoaded(info);
getEventListeners().fire.eventSelected(evt, evt.getCause());
getEventListeners().fire.moduleLoaded(process, info, evt.getCause());
String key = info.getModuleName();
@ -888,6 +894,7 @@ public class DbgManagerImpl implements DbgManager {
DbgProcessImpl process = getCurrentProcess();
DebugModuleInfo info = evt.getInfo();
process.moduleUnloaded(info);
getEventListeners().fire.eventSelected(evt, evt.getCause());
getEventListeners().fire.moduleUnloaded(process, info, evt.getCause());
String key = info.getModuleName();

View File

@ -42,4 +42,6 @@ public abstract class AbstractDbgModel extends AbstractDebuggerObjectModel {
public abstract TargetObject getModelObject(Object object);
public abstract void deleteModelObject(Object object);
}

View File

@ -15,15 +15,18 @@
*/
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 {
@Override
public default String getDisplay() {
return getName();
}
public interface DbgModelTargetEvent extends DbgModelSelectableObject, DbgEventsListenerAdapter //
{
public DbgEventFilter getFilter();
public int getEventIndex();
@Override
void eventSelected(AbstractDbgEvent<?> event, DbgCause cause);
}

View File

@ -19,9 +19,4 @@ import ghidra.dbg.target.TargetTogglable;
public interface DbgModelTargetEventOption extends DbgModelTargetObject, TargetTogglable {
@Override
public default String getDisplay() {
return getName();
}
}

View File

@ -17,12 +17,7 @@ package agent.dbgeng.model.iface2;
import agent.dbgeng.manager.DbgExceptionFilter;
public interface DbgModelTargetException extends DbgModelTargetObject {
@Override
public default String getDisplay() {
return getName();
}
public interface DbgModelTargetException extends DbgModelTargetEvent {
public DbgExceptionFilter getFilter();

View File

@ -164,6 +164,7 @@ public class DbgModelImpl extends AbstractDbgModel implements DebuggerObjectMode
return objectMap.get(object);
}
@Override
public void deleteModelObject(Object object) {
objectMap.remove(object);
}

View File

@ -20,75 +20,66 @@ import java.util.Map;
import java.util.concurrent.CompletableFuture;
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 ghidra.dbg.target.schema.*;
import ghidra.dbg.util.PathUtils;
@TargetObjectSchemaInfo(
name = "Event",
name = "ContinuationFilter",
elements = {
@TargetElementType(type = Void.class) },
attributes = {
@TargetAttributeType(type = Object.class) })
public class DbgModelTargetEventOptionImpl extends DbgModelTargetObjectImpl
public class DbgModelTargetContinuationOptionImpl extends DbgModelTargetObjectImpl
implements DbgModelTargetEventOption {
protected static String keyFilter(DebugFilterExecutionOption option) {
return PathUtils.makeKey(option.description);
}
protected static String keyFilter(DebugFilterContinuationOption option) {
return PathUtils.makeKey(option.description);
}
private DebugFilterExecutionOption optionEx;
private DbgModelTargetEvent event;
private DebugFilterContinuationOption optionCont;
public DbgModelTargetEventOptionImpl(DbgModelTargetEvent event,
DebugFilterExecutionOption option) {
super(event.getModel(), event, keyFilter(option), "EventFilter");
public DbgModelTargetContinuationOptionImpl(DbgModelTargetEvent event,
DebugFilterContinuationOption option) {
super(event.getModel(), event, "Continue", "ContinuationFilter");
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) {
super(event.getModel(), event, keyFilter(option), "EventFilter");
this.getModel().addModelObject(option, this);
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");
super(exc.getModel(), exc, "Continue", "ContinuationFilter");
this.event = exc;
this.getModel().addModelObject(option, this);
this.optionCont = option;
setAttributes();
}
@Override
public CompletableFuture<Void> disable() {
// TODO Auto-generated method stub
return null;
DbgManagerImpl manager = getManager();
optionCont = DebugFilterContinuationOption.DEBUG_FILTER_GO_NOT_HANDLED;
setAttributes();
return manager.execute(
new DbgToggleContinuationCommand(manager, event.getEventIndex(), optionCont));
}
@Override
public CompletableFuture<Void> enable() {
// TODO Auto-generated method stub
return null;
DbgManagerImpl manager = getManager();
optionCont = DebugFilterContinuationOption.DEBUG_FILTER_GO_HANDLED;
setAttributes();
return manager.execute(
new DbgToggleContinuationCommand(manager, event.getEventIndex(), optionCont));
}
public void setAttributes() {
changeAttributes(List.of(), List.of(), Map.of( //
DISPLAY_ATTRIBUTE_NAME, getName() //
), "Initialized");
DISPLAY_ATTRIBUTE_NAME, getName() + " : " + optionCont.description, //
VALUE_ATTRIBUTE_NAME, optionCont, //
ENABLED_ATTRIBUTE_NAME,
optionCont.equals(DebugFilterContinuationOption.DEBUG_FILTER_GO_HANDLED)),
"Refreshed");
}
}

View File

@ -18,9 +18,10 @@ package agent.dbgeng.model.impl;
import java.util.List;
import java.util.Map;
import agent.dbgeng.dbgeng.DebugControl.DebugFilterContinuationOption;
import agent.dbgeng.dbgeng.DebugControl.DebugFilterExecutionOption;
import agent.dbgeng.dbgeng.DebugControl.*;
import agent.dbgeng.manager.DbgCause;
import agent.dbgeng.manager.DbgEventFilter;
import agent.dbgeng.manager.evt.*;
import agent.dbgeng.model.iface2.*;
import ghidra.dbg.target.schema.*;
import ghidra.dbg.util.PathUtils;
@ -55,8 +56,8 @@ public class DbgModelTargetEventImpl extends DbgModelTargetObjectImpl
DebugFilterExecutionOption.getByNumber(filter.getExecutionOption());
DebugFilterContinuationOption cont =
DebugFilterContinuationOption.getByNumber(filter.getContinueOption());
execOption = new DbgModelTargetEventOptionImpl(this, exec);
contOption = new DbgModelTargetEventOptionImpl(this, cont);
execOption = new DbgModelTargetExecutionOptionImpl(this, exec);
contOption = new DbgModelTargetContinuationOptionImpl(this, cont);
changeAttributes(List.of(), List.of(), Map.of( //
DISPLAY_ATTRIBUTE_NAME, getIndex(), //
@ -64,6 +65,8 @@ public class DbgModelTargetEventImpl extends DbgModelTargetObjectImpl
"Execute", execOption, //
"Continue", contOption //
), "Initialized");
getManager().addEventsListener(this);
}
@Override
@ -71,4 +74,44 @@ public class DbgModelTargetEventImpl extends DbgModelTargetObjectImpl
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");
}
}
}

View File

@ -20,8 +20,14 @@ import java.util.Map;
import agent.dbgeng.dbgeng.DebugControl.DebugFilterContinuationOption;
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.evt.AbstractDbgEvent;
import agent.dbgeng.manager.evt.DbgExceptionEvent;
import agent.dbgeng.model.iface1.DbgModelTargetFocusScope;
import agent.dbgeng.model.iface2.*;
import ghidra.dbg.target.TargetFocusScope;
import ghidra.dbg.target.schema.*;
import ghidra.dbg.util.PathUtils;
@ -56,8 +62,8 @@ public class DbgModelTargetExceptionImpl extends DbgModelTargetObjectImpl
DebugFilterExecutionOption.getByNumber(filter.getExecutionOption());
DebugFilterContinuationOption cont =
DebugFilterContinuationOption.getByNumber(filter.getContinueOption());
execOption = new DbgModelTargetEventOptionImpl(this, exec);
contOption = new DbgModelTargetEventOptionImpl(this, cont);
execOption = new DbgModelTargetExecutionOptionImpl(this, exec);
contOption = new DbgModelTargetContinuationOptionImpl(this, cont);
changeAttributes(List.of(), List.of(), Map.of( //
DISPLAY_ATTRIBUTE_NAME, getIndex(), //
@ -67,6 +73,8 @@ public class DbgModelTargetExceptionImpl extends DbgModelTargetObjectImpl
"Continue", contOption, //
"Exception", filter.getExceptionCode() //
), "Initialized");
getManager().addEventsListener(this);
}
@Override
@ -74,4 +82,23 @@ public class DbgModelTargetExceptionImpl extends DbgModelTargetObjectImpl
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");
}
}
}
}

View File

@ -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");
}
}

View File

@ -182,6 +182,11 @@ public class DbgModel2Impl extends AbstractDbgModel
return objectMap.get(object);
}
@Override
public void deleteModelObject(Object object) {
objectMap.remove(object);
}
@Override
public <T> CompletableFuture<T> gateFuture(CompletableFuture<T> future) {
return super.gateFuture(future).exceptionally(ex -> {

View File

@ -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 {
String NAME = "Map Identically";
String DESCRIPTION =

View File

@ -1148,43 +1148,43 @@ public class DebuggerObjectsProvider extends ComponentProviderAdapter
groupTargetIndex++;
new ActionBuilder("Finish", plugin.getName())
.keyBinding("F12")
.toolBarGroup(DebuggerResources.GROUP_CONTROL, "C" + groupTargetIndex)
.toolBarIcon(AbstractStepFinishAction.ICON)
.popupMenuPath("&Finish")
.popupMenuGroup(DebuggerResources.GROUP_CONTROL, "C" + groupTargetIndex)
.popupMenuIcon(AbstractStepFinishAction.ICON)
.helpLocation(AbstractStepFinishAction.help(plugin))
//.withContext(ObjectActionContext.class)
.enabledWhen(ctx ->
isInstance(ctx, TargetSteppable.class) && isStopped(ctx))
.popupWhen(ctx ->
isInstance(ctx, TargetSteppable.class) && isStopped(ctx))
.onAction(ctx -> performStepFinish(ctx))
.enabled(false)
.buildAndInstallLocal(this);
.keyBinding("F12")
.toolBarGroup(DebuggerResources.GROUP_CONTROL, "C" + groupTargetIndex)
.toolBarIcon(AbstractStepFinishAction.ICON)
.popupMenuPath("&Finish")
.popupMenuGroup(DebuggerResources.GROUP_CONTROL, "C" + groupTargetIndex)
.popupMenuIcon(AbstractStepFinishAction.ICON)
.helpLocation(AbstractStepFinishAction.help(plugin))
//.withContext(ObjectActionContext.class)
.enabledWhen(ctx ->
isInstance(ctx, TargetSteppable.class) && isStopped(ctx))
.popupWhen(ctx ->
isInstance(ctx, TargetSteppable.class) && isStopped(ctx))
.onAction(ctx -> performStepFinish(ctx))
.enabled(false)
.buildAndInstallLocal(this);
groupTargetIndex++;
new ActionBuilder("Step Last", plugin.getName())
.keyBinding("ALT F8")
.toolBarGroup(DebuggerResources.GROUP_CONTROL, "C" + groupTargetIndex)
.toolBarIcon(AbstractStepLastAction.ICON)
.popupMenuPath("&Step Last")
.popupMenuGroup(DebuggerResources.GROUP_CONTROL, "C" + groupTargetIndex)
.popupMenuIcon(AbstractStepLastAction.ICON)
.helpLocation(AbstractStepLastAction.help(plugin))
//.withContext(ObjectActionContext.class)
.enabledWhen(ctx ->
isInstance(ctx, TargetSteppable.class) && isStopped(ctx))
.popupWhen(ctx ->
isInstance(ctx, TargetSteppable.class) && isStopped(ctx))
.onAction(ctx -> performStepLast(ctx))
.enabled(false)
.buildAndInstallLocal(this);
groupTargetIndex++;
groupTargetIndex++;
new ActionBuilder("Step Last", plugin.getName())
.keyBinding("ALT F8")
.toolBarGroup(DebuggerResources.GROUP_CONTROL, "C" + groupTargetIndex)
.toolBarIcon(AbstractStepLastAction.ICON)
.popupMenuPath("&Step Last")
.popupMenuGroup(DebuggerResources.GROUP_CONTROL, "C" + groupTargetIndex)
.popupMenuIcon(AbstractStepLastAction.ICON)
.helpLocation(AbstractStepLastAction.help(plugin))
//.withContext(ObjectActionContext.class)
.enabledWhen(ctx ->
isInstance(ctx, TargetSteppable.class) && isStopped(ctx))
.popupWhen(ctx ->
isInstance(ctx, TargetSteppable.class) && isStopped(ctx))
.onAction(ctx -> performStepLast(ctx))
.enabled(false)
.buildAndInstallLocal(this);
groupTargetIndex++;
actionAddBreakpoint = new ActionBuilder("Add Breakpoint", plugin.getName())
.keyBinding("F3")
.toolBarGroup(DebuggerResources.GROUP_CONTROL, "C" + groupTargetIndex)
@ -1221,6 +1221,20 @@ public class DebuggerObjectsProvider extends ComponentProviderAdapter
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);
displayAsTableAction = new DisplayAsTableAction(tool, plugin.getName(), this);
displayAsGraphAction = new DisplayAsGraphAction(tool, plugin.getName(), this);
@ -1486,6 +1500,12 @@ public class DebuggerObjectsProvider extends ComponentProviderAdapter
}, "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) {
performAction(context, false, TargetInterpreter.class, interpreter -> {
getPlugin().showConsole(interpreter);