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 { 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"), //

View file

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

View file

@ -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
* *

View file

@ -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

View file

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

View file

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

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; 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;

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

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); 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 -> {

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

View file

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