GP-648: Dbgmodel speed-up, and focus issues.

This commit is contained in:
d-millar 2021-01-29 21:53:35 +00:00 committed by Dan
parent f5ec74f2c3
commit 2ed29f5693
53 changed files with 650 additions and 473 deletions

View file

@ -27,8 +27,8 @@ import agent.dbgmodel.dbgmodel.UnknownEx;
import agent.dbgmodel.dbgmodel.datamodel.DataModelManager1;
import agent.dbgmodel.dbgmodel.debughost.DebugHostContext;
import agent.dbgmodel.dbgmodel.debughost.DebugHostType1;
import agent.dbgmodel.jna.dbgmodel.IUnknownEx;
import agent.dbgmodel.jna.dbgmodel.DbgModelNative.*;
import agent.dbgmodel.jna.dbgmodel.IUnknownEx;
import agent.dbgmodel.jna.dbgmodel.main.IModelObject;
/**
@ -130,6 +130,8 @@ public interface ModelObject extends UnknownEx {
ModelMethod getMethod(String name);
String getOriginalKey();
String getSearchKey();
void setSearchKey(String key);

View file

@ -82,7 +82,7 @@ public class HDMAUtil {
public Map<String, ModelObject> getAttributes(List<String> path) {
ModelObject target = getTerminalModelObject(path);
if (target == null) {
System.err.println("(A) Null target for path=" + path);
//System.err.println("(A) Null target for path=" + path);
return new HashMap<String, ModelObject>();
}
ModelObjectKind kind = target.getKind();
@ -102,7 +102,7 @@ public class HDMAUtil {
public List<ModelObject> getElements(List<String> path) {
ModelObject target = getTerminalModelObject(path);
if (target == null) {
System.err.println("(C) Null target for path=" + path);
//System.err.println("(C) Null target for path=" + path);
return new ArrayList<ModelObject>();
}
ModelObjectKind kind = target.getKind();
@ -127,9 +127,11 @@ public class HDMAUtil {
public ModelObject getTerminalModelObject(List<String> path) {
//System.err.println(path);
ModelObject target = getRootNamespace();
boolean found;
for (String str : path) {
//System.err.println(":" + str);
String indexStr = null;
found = false;
if (str.endsWith(")")) {
target = evaluatePredicate(target, str);
if (target.getKind().equals(ModelObjectKind.OBJECT_ERROR)) {
@ -143,11 +145,13 @@ public class HDMAUtil {
Map<String, ModelObject> keyMap = target.getKeyValueMap();
if (keyMap.containsKey(str)) {
target = keyMap.get(str);
found = true;
}
else {
Map<String, ModelObject> rawMap = target.getRawValueMap();
if (rawMap.containsKey(str)) {
target = rawMap.get(str);
found = true;
}
}
if (indexStr != null) {
@ -155,9 +159,13 @@ public class HDMAUtil {
for (ModelObject child : children) {
if (indexStr.equals(child.getSearchKey())) {
target = child;
found = true;
}
}
}
if (found == false) {
return null;
}
}
return target;
}

View file

@ -898,6 +898,19 @@ public class ModelObjectImpl implements ModelObjectInternal {
@Override
public String getSearchKey() {
if (key == null) {
throw new RuntimeException("null key for " + this);
}
Map<String, ModelObject> map = getKeyValueMap();
if (map.containsKey("BaseAddress")) {
String valueString = map.get("BaseAddress").getValueString();
return valueString;
}
return key;
}
@Override
public String getOriginalKey() {
if (key == null) {
throw new RuntimeException("null key for " + this);
}

View file

@ -23,8 +23,7 @@ import agent.dbgeng.model.iface2.DbgModelTargetObject;
import agent.dbgmodel.dbgmodel.main.ModelObject;
import agent.dbgmodel.gadp.impl.WrappedDbgModel;
import agent.dbgmodel.manager.DbgManager2Impl;
import agent.dbgmodel.model.impl.DbgModel2TargetObjectImpl;
import agent.dbgmodel.model.impl.DelegateDbgModel2TargetObject;
import agent.dbgmodel.model.impl.*;
import ghidra.dbg.util.PathUtils.TargetObjectKeyComparator;
public class DbgListAttributesCommand extends AbstractDbgCommand<Map<String, ?>> {
@ -54,20 +53,19 @@ public class DbgListAttributesCommand extends AbstractDbgCommand<Map<String, ?>>
Map<String, ModelObject> map = access.getAttributes(path);
Map<String, ?> existingAttributes = targetObject.getCachedAttributes();
for (String key : map.keySet()) {
DbgModelTargetObject proxyAttribute;
DbgModel2TargetProxy proxyAttribute;
ModelObject obj = map.get(key);
Object object = existingAttributes.get(key);
String atKey = obj.getSearchKey();
Object object = existingAttributes.get(atKey);
if (object != null && (object instanceof DbgModelTargetObject)) {
proxyAttribute = (DbgModelTargetObject) object;
DelegateDbgModel2TargetObject delegate =
DelegateDbgModel2TargetObject.getDelegate(proxyAttribute);
proxyAttribute = (DbgModel2TargetProxy) object;
DelegateDbgModel2TargetObject delegate = proxyAttribute.getDelegate();
delegate.setModelObject(obj);
updatedAttributes.put(key, proxyAttribute);
}
else {
String atKey = obj.getSearchKey();
proxyAttribute = DelegateDbgModel2TargetObject.makeProxy(targetObject.getModel(),
targetObject, atKey, obj);
proxyAttribute = (DbgModel2TargetProxy) DelegateDbgModel2TargetObject
.makeProxy(targetObject.getModel(), targetObject, atKey, obj);
updatedAttributes.put(key, proxyAttribute);
}
}

View file

@ -19,14 +19,13 @@ import java.util.*;
import agent.dbgeng.manager.cmd.AbstractDbgCommand;
import agent.dbgeng.manager.cmd.DbgPendingCommand;
import agent.dbgeng.model.iface2.DbgModelTargetObject;
import agent.dbgmodel.dbgmodel.main.ModelObject;
import agent.dbgmodel.gadp.impl.WrappedDbgModel;
import agent.dbgmodel.manager.DbgManager2Impl;
import agent.dbgmodel.model.impl.DbgModel2TargetObjectImpl;
import agent.dbgmodel.model.impl.DelegateDbgModel2TargetObject;
import agent.dbgmodel.model.impl.*;
import ghidra.dbg.attributes.TargetObjectRef;
import ghidra.dbg.target.TargetObject;
import ghidra.dbg.util.PathUtils;
public class DbgListElementsCommand extends AbstractDbgCommand<List<TargetObject>> {
@ -51,23 +50,27 @@ public class DbgListElementsCommand extends AbstractDbgCommand<List<TargetObject
@Override
public void invoke() {
updatedElements = new ArrayList<>();
List<ModelObject> list = access.getElements(path);
Map<String, ? extends TargetObjectRef> existingElements = targetObject.getCachedElements();
for (ModelObject obj : list) {
DbgModelTargetObject proxyElement;
if (existingElements.containsKey(obj.getSearchKey())) {
proxyElement = (DbgModelTargetObject) existingElements.get(obj.getSearchKey());
DelegateDbgModel2TargetObject delegate =
DelegateDbgModel2TargetObject.getDelegate(proxyElement);
delegate.setModelObject(obj);
synchronized (access) {
updatedElements = new ArrayList<>();
List<ModelObject> list = access.getElements(path);
Map<String, ? extends TargetObjectRef> existingElements =
targetObject.getCachedElements();
for (ModelObject obj : list) {
DbgModel2TargetProxy proxyElement;
String searchKey = obj.getSearchKey();
String elKey = PathUtils.makeKey(searchKey);
if (existingElements.containsKey(searchKey)) {
proxyElement = (DbgModel2TargetProxy) existingElements.get(searchKey);
DelegateDbgModel2TargetObject delegate = proxyElement.getDelegate();
delegate.setModelObject(obj);
}
else {
proxyElement = (DbgModel2TargetProxy) DelegateDbgModel2TargetObject
.makeProxy(targetObject.getModel(), targetObject, elKey, obj);
}
updatedElements.add(proxyElement);
}
else {
String elKey = DbgModel2TargetObjectImpl.keyObject(obj);
proxyElement = DelegateDbgModel2TargetObject.makeProxy(targetObject.getModel(),
targetObject, elKey, obj);
}
updatedElements.add(proxyElement);
}
}
}

View file

@ -22,12 +22,11 @@ import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.atomic.AtomicReference;
import agent.dbgeng.dbgeng.*;
import agent.dbgeng.dbgeng.DebugClient;
import agent.dbgeng.manager.DbgCause.Causes;
import agent.dbgeng.manager.DbgState;
import agent.dbgeng.manager.impl.*;
import agent.dbgeng.manager.impl.DbgManagerImpl;
import agent.dbgmodel.dbgmodel.DbgModel;
import agent.dbgmodel.dbgmodel.main.ModelObject;
import agent.dbgmodel.gadp.impl.DbgModelClientThreadExecutor;
import agent.dbgmodel.gadp.impl.WrappedDbgModel;
import agent.dbgmodel.jna.cmd.*;
@ -108,6 +107,7 @@ public class DbgManager2Impl extends DbgManagerImpl {
return execute(new DbgGetRegisterMapCommand(this, path));
}
/*
@Override
public DbgSessionImpl getCurrentSession() {
ModelObject currentSession = dbgmodel.getUtil().getCurrentSession();
@ -117,7 +117,7 @@ public class DbgManager2Impl extends DbgManagerImpl {
curSession = getSessionComputeIfAbsent(sid);
return curSession;
}
@Override
public DbgProcessImpl getCurrentProcess() {
synchronized (processes) {
@ -125,7 +125,7 @@ public class DbgManager2Impl extends DbgManagerImpl {
return processes.get(id);
}
}
@Override
public DbgThreadImpl getCurrentThread() {
synchronized (threads) {
@ -133,5 +133,6 @@ public class DbgManager2Impl extends DbgManagerImpl {
return threads.get(id);
}
}
*/
}

View file

@ -27,7 +27,6 @@ import agent.dbgmodel.manager.DbgManager2Impl;
import ghidra.dbg.target.TargetObject;
import ghidra.dbg.target.schema.TargetObjectSchema;
import ghidra.dbg.target.schema.XmlSchemaContext;
import ghidra.framework.Application;
import ghidra.program.model.address.*;
public class DbgModel2Impl extends AbstractDbgModel {

View file

@ -25,7 +25,7 @@ import agent.dbgeng.manager.breakpoint.DbgBreakpointInfo;
import agent.dbgeng.model.AbstractDbgModel;
import agent.dbgeng.model.iface1.DbgModelSelectableObject;
import agent.dbgeng.model.iface2.*;
import agent.dbgeng.model.impl.DbgModelTargetMemoryContainerImpl;
import agent.dbgeng.model.impl.*;
import agent.dbgmodel.dbgmodel.main.ModelObject;
import agent.dbgmodel.jna.dbgmodel.DbgModelNative.ModelObjectKind;
import agent.dbgmodel.jna.dbgmodel.DbgModelNative.TypeKind;
@ -37,6 +37,7 @@ import ghidra.dbg.target.TargetBreakpointContainer.TargetBreakpointKindSet;
import ghidra.dbg.target.TargetBreakpointSpec.TargetBreakpointKind;
import ghidra.dbg.target.TargetExecutionStateful.TargetExecutionState;
import ghidra.dbg.target.schema.TargetObjectSchema;
import ghidra.dbg.util.CollectionUtils.Delta;
import ghidra.dbg.util.PathUtils;
import ghidra.dbg.util.PathUtils.TargetObjectKeyComparator;
import ghidra.util.Msg;
@ -58,6 +59,8 @@ public class DbgModel2TargetObjectImpl extends DefaultTargetObject<TargetObject,
protected String DBG_PROMPT = "(kd2)"; // Used by DbgModelTargetEnvironment
protected boolean fireAttributesChanged = false;
protected static String indexObject(ModelObject obj) {
return obj.getSearchKey();
}
@ -101,51 +104,49 @@ public class DbgModel2TargetObjectImpl extends DefaultTargetObject<TargetObject,
@Override
public CompletableFuture<Void> requestElements(boolean refresh) {
List<TargetObject> nlist = new ArrayList<>();
return requestNativeElements().thenCompose(list -> {
for (TargetObject element : elements.values()) {
if (!list.contains(element)) {
if (element instanceof DbgStateListener) {
getManager().removeStateListener((DbgStateListener) element);
}
if (element instanceof DbgEventsListener) {
getManager().removeEventsListener((DbgEventsListener) element);
synchronized (elements) {
List<TargetObject> nlist = new ArrayList<>();
return requestNativeElements().thenCompose(list -> {
for (TargetObject element : elements.values()) {
if (!list.contains(element)) {
if (element instanceof DbgStateListener) {
getManager().removeStateListener((DbgStateListener) element);
}
if (element instanceof DbgEventsListener) {
getManager().removeEventsListener((DbgEventsListener) element);
}
}
}
}
nlist.addAll(list);
int order = 0;
for (TargetObject targetObject : nlist) {
DbgModelTargetObject to = (DbgModelTargetObject) targetObject;
to.changeAttributes(List.of(), Map.of( //
ORDER_ATTRIBUTE_NAME, order++ //
), "Initialized");
}
return processModelObjectElements(nlist);
}).thenAccept(__ -> {
setElements(nlist, Map.of(), "Refreshed");
});
nlist.addAll(list);
return processModelObjectElements(nlist);
}).thenAccept(__ -> {
setElements(nlist, Map.of(), "Refreshed");
});
}
}
@Override
public CompletableFuture<Void> requestAttributes(boolean refresh) {
fireAttributesChanged = true;
Map<String, Object> nmap = new HashMap<>();
return requestNativeAttributes().thenCompose(map -> {
if (map != null) {
Collection<?> values = map.values();
for (Object attribute : attributes.values()) {
if (!values.contains(attribute)) {
if (attribute instanceof DbgStateListener) {
getManager().removeStateListener((DbgStateListener) attribute);
}
if (attribute instanceof DbgEventsListener) {
getManager().removeEventsListener((DbgEventsListener) attribute);
synchronized (attributes) {
if (map != null) {
Collection<?> values = map.values();
for (Object attribute : attributes.values()) {
if (!values.contains(attribute)) {
if (attribute instanceof DbgStateListener) {
getManager().removeStateListener((DbgStateListener) attribute);
}
if (attribute instanceof DbgEventsListener) {
getManager().removeEventsListener((DbgEventsListener) attribute);
}
}
}
nmap.putAll(map);
}
nmap.putAll(map);
return addModelObjectAttributes(nmap);
}
return addModelObjectAttributes(nmap);
}).thenAccept(__ -> {
setAttributes(List.of(), nmap, "Refreshed");
});
@ -161,9 +162,8 @@ public class DbgModel2TargetObjectImpl extends DefaultTargetObject<TargetObject,
private CompletableFuture<Void> processElement(TargetObject targetObject) {
if (targetObject instanceof DbgModelTargetObject) {
DbgModelTargetObject proxy = (DbgModelTargetObject) targetObject;
DelegateDbgModel2TargetObject delegate =
DelegateDbgModel2TargetObject.getDelegate(proxy);
DbgModel2TargetProxy proxy = (DbgModel2TargetProxy) targetObject;
DelegateDbgModel2TargetObject delegate = proxy.getDelegate();
if (proxy instanceof TargetStackFrame || //
proxy instanceof TargetModule || //
proxy instanceof TargetBreakpointSpec) {
@ -193,10 +193,12 @@ public class DbgModel2TargetObjectImpl extends DefaultTargetObject<TargetObject,
if (value != null && !value.equals("")) {
attrs.put(VALUE_ATTRIBUTE_NAME, value);
if (!kind.equals(ModelObjectKind.OBJECT_PROPERTY_ACCESSOR)) {
String oldval = (String) attributes.get(DISPLAY_ATTRIBUTE_NAME);
String newval = getName() + " : " + value;
attrs.put(DISPLAY_ATTRIBUTE_NAME, newval);
setModified(attrs, !newval.equals(oldval));
synchronized (attributes) {
String oldval = (String) attributes.get(DISPLAY_ATTRIBUTE_NAME);
String newval = getName() + " : " + value;
attrs.put(DISPLAY_ATTRIBUTE_NAME, newval);
setModified(attrs, !newval.equals(oldval));
}
}
if (tk == null) {
Object val = modelObject.getIntrinsicValue();
@ -208,11 +210,23 @@ public class DbgModel2TargetObjectImpl extends DefaultTargetObject<TargetObject,
if (this instanceof DelegateDbgModel2TargetObject) {
DelegateDbgModel2TargetObject delegate = (DelegateDbgModel2TargetObject) this;
TargetObject proxy = delegate.getProxy();
if (proxy instanceof TargetAccessConditioned) {
attrs.put(TargetAccessConditioned.ACCESSIBLE_ATTRIBUTE_NAME,
accessibility == TargetAccessibility.ACCESSIBLE);
}
if (proxy instanceof TargetExecutionStateful) {
TargetExecutionStateful<?> stateful = (TargetExecutionStateful<?>) proxy;
TargetExecutionState state = stateful.getExecutionState();
attrs.put(TargetExecutionStateful.STATE_ATTRIBUTE_NAME, state);
}
if (proxy instanceof TargetAttacher) {
attrs.put(TargetAttacher.SUPPORTED_ATTACH_KINDS_ATTRIBUTE_NAME,
DbgModelTargetProcessImpl.SUPPORTED_KINDS);
}
if (proxy instanceof TargetSteppable) {
attrs.put(TargetSteppable.SUPPORTED_STEP_KINDS_ATTRIBUTE_NAME,
DbgModelTargetThreadImpl.SUPPORTED_KINDS);
}
if (proxy instanceof TargetInterpreter) {
attrs.put(TargetInterpreter.PROMPT_ATTRIBUTE_NAME, DBG_PROMPT);
}
@ -230,6 +244,8 @@ public class DbgModel2TargetObjectImpl extends DefaultTargetObject<TargetObject,
attrs.put(TargetEnvironment.OS_ATTRIBUTE_NAME, "Windows");
}
if (proxy instanceof TargetModule) {
//attrs.put(TargetObject.ORDER_ATTRIBUTE_NAME,
// Integer.decode(modelObject.getOriginalKey()));
DbgModelTargetModule module = (DbgModelTargetModule) proxy;
return module.init(attrs);
}
@ -272,28 +288,32 @@ public class DbgModel2TargetObjectImpl extends DefaultTargetObject<TargetObject,
@Override
public CompletableFuture<?> fetchChild(final String key) {
if (key.startsWith("[") && key.endsWith("]")) {
String trimKey = key.substring(1, key.length() - 1);
if (elements.containsKey(trimKey)) {
return CompletableFuture.completedFuture(elements.get(trimKey));
synchronized (elements) {
if (key.startsWith("[") && key.endsWith("]")) {
String trimKey = key.substring(1, key.length() - 1);
if (elements.containsKey(trimKey)) {
return CompletableFuture.completedFuture(elements.get(trimKey));
}
return requestElements(true).thenApply(__ -> getCachedElements().get(trimKey));
}
return requestElements(true).thenApply(__ -> getCachedElements().get(trimKey));
}
if (attributes.containsKey(key)) {
return CompletableFuture.completedFuture(attributes.get(key));
synchronized (attributes) {
if (attributes.containsKey(key)) {
return CompletableFuture.completedFuture(attributes.get(key));
}
if (key.endsWith(")")) {
DbgManager2Impl manager2 = (DbgManager2Impl) getManager();
List<String> pathX = PathUtils.extend(List.of("Debugger"), path);
pathX = PathUtils.extend(pathX, key);
return manager2.applyMethods(pathX, this).thenApply(obj -> {
changeAttributes(List.of(), List.of(), Map.of( //
key, obj //
), "Initialized");
return obj;
});
}
return requestAttributes(true).thenApply(__ -> getCachedAttribute(key));
}
if (key.endsWith(")")) {
DbgManager2Impl manager2 = (DbgManager2Impl) getManager();
List<String> pathX = PathUtils.extend(List.of("Debugger"), path);
pathX = PathUtils.extend(pathX, key);
return manager2.applyMethods(pathX, this).thenApply(obj -> {
changeAttributes(List.of(), List.of(), Map.of( //
key, obj //
), "Initialized");
return obj;
});
}
return requestAttributes(true).thenApply(__ -> getCachedAttribute(key));
}
//@Override
@ -378,9 +398,55 @@ public class DbgModel2TargetObjectImpl extends DefaultTargetObject<TargetObject,
@Override
public void resetModified() {
changeAttributes(List.of(), List.of(), Map.of( //
MODIFIED_ATTRIBUTE_NAME, false //
), "Refreshed");
if (getCachedAttribute(MODIFIED_ATTRIBUTE_NAME) != null) {
changeAttributes(List.of(), List.of(), Map.of( //
MODIFIED_ATTRIBUTE_NAME, false //
), "Refreshed");
}
}
// NB: We're overriding these to prevent events being added as newly added elements
// initialize and pull the attributes needed for their display
@Override
public Delta<?, ?> setAttributes(Map<String, ?> attributes, String reason) {
Delta<?, ?> delta;
synchronized (this.attributes) {
delta = Delta.computeAndSet(this.attributes, attributes, Delta.EQUAL);
}
TargetObjectSchema schemax = getSchema();
if (schemax != null) {
schemax.validateAttributeDelta(getPath(), delta, enforcesStrictSchema());
}
doInvalidateAttributes(delta.removed, reason);
if (parent == null && !delta.isEmpty()) {
listeners.fire.attributesChanged(getProxy(), delta.getKeysRemoved(), delta.added);
return delta;
}
if (fireAttributesChanged && !delta.isEmpty()) {
listeners.fire.attributesChanged(getProxy(), delta.getKeysRemoved(), delta.added);
}
return delta;
}
@Override
public Delta<?, ?> changeAttributes(List<String> remove, Map<String, ?> add, String reason) {
Delta<?, ?> delta;
synchronized (attributes) {
delta = Delta.apply(this.attributes, remove, add, Delta.EQUAL);
}
TargetObjectSchema schemax = getSchema();
if (schemax != null) {
schemax.validateAttributeDelta(getPath(), delta, enforcesStrictSchema());
}
doInvalidateAttributes(delta.removed, reason);
if (fireAttributesChanged && !delta.isEmpty()) {
listeners.fire.attributesChanged(getProxy(), delta.getKeysRemoved(), delta.added);
}
return delta;
}
@Override
protected boolean enforcesStrictSchema() {
return false;
}
}

View file

@ -0,0 +1,24 @@
/* ###
* 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.dbgmodel.model.impl;
import agent.dbgeng.model.iface2.DbgModelTargetObject;
public interface DbgModel2TargetProxy extends DbgModelTargetObject {
public DelegateDbgModel2TargetObject getDelegate();
}

View file

@ -26,6 +26,7 @@ import agent.dbgeng.model.iface1.DbgModelSelectableObject;
import agent.dbgeng.model.iface1.DbgModelTargetExecutionStateful;
import agent.dbgeng.model.iface2.*;
import agent.dbgeng.model.impl.DbgModelTargetConnectorContainerImpl;
import agent.dbgmodel.dbgmodel.main.ModelObject;
import agent.dbgmodel.manager.DbgManager2Impl;
import ghidra.async.AsyncUtils;
import ghidra.async.TypeSpec;
@ -59,7 +60,9 @@ public class DbgModel2TargetRootImpl extends DbgModel2DefaultTargetModelRoot
connectors, //
systemMarker //
), Map.of( //
ACCESSIBLE_ATTRIBUTE_NAME, true, //
DISPLAY_ATTRIBUTE_NAME, "Debugger", //
FOCUS_ATTRIBUTE_NAME, this, //
TargetMethod.PARAMETERS_ATTRIBUTE_NAME, defaultConnector.getParameters() //
// ARCH_ATTRIBUTE_NAME, "x86_64", //
// DEBUGGER_ATTRIBUTE_NAME, "dbgeng", //
@ -82,7 +85,9 @@ public class DbgModel2TargetRootImpl extends DbgModel2DefaultTargetModelRoot
connectors, //
systemMarker //
), Map.of( //
ACCESSIBLE_ATTRIBUTE_NAME, true, //
DISPLAY_ATTRIBUTE_NAME, "Debugger", //
FOCUS_ATTRIBUTE_NAME, this, //
TargetMethod.PARAMETERS_ATTRIBUTE_NAME, defaultConnector.getParameters() //
// ARCH_ATTRIBUTE_NAME, "x86_64", //
// DEBUGGER_ATTRIBUTE_NAME, "dbgeng", //
@ -99,21 +104,12 @@ public class DbgModel2TargetRootImpl extends DbgModel2DefaultTargetModelRoot
if (doFire && focus != null) {
List<String> focusPath = focus.getPath();
List<String> selPath = sel.getPath();
for (int i = 0; i < focusPath.size(); i++) {
if (i >= selPath.size()) {
doFire = false;
break;
}
if (!focusPath.get(i).equals(selPath.get(i))) {
doFire = true;
break;
}
}
//doFire = !focusPath.containsAll(selPath);
doFire = !PathUtils.isAncestor(selPath, focusPath);
}
}
if (doFire) {
this.focus = sel;
fireAttributesChanged = true;
changeAttributes(List.of(), List.of(), Map.of( //
TargetFocusScope.FOCUS_ATTRIBUTE_NAME, focus //
), "Focus changed");
@ -201,28 +197,28 @@ public class DbgModel2TargetRootImpl extends DbgModel2DefaultTargetModelRoot
}
@Override
public void moduleLoaded(DbgProcess proc, String name, DbgCause cause) {
getObject(proc, List.of("Modules"), name).thenAccept(obj -> {
public void moduleLoaded(DbgProcess proc, DebugModuleInfo info, DbgCause cause) {
getObjectRevisited(proc, List.of("Modules"), info).thenAccept(obj -> {
DbgModelTargetModule mod = (DbgModelTargetModule) obj;
if (mod == null) {
return;
}
getListeners().fire(TargetEventScopeListener.class)
.event(this, null, TargetEventType.MODULE_LOADED, "Library " + name + " loaded",
List.of(mod));
.event(this, null, TargetEventType.MODULE_LOADED,
"Library " + info.moduleName + " loaded", List.of(mod));
});
}
@Override
public void moduleUnloaded(DbgProcess proc, String name, DbgCause cause) {
getObject(proc, List.of("Modules"), name).thenAccept(obj -> {
public void moduleUnloaded(DbgProcess proc, DebugModuleInfo info, DbgCause cause) {
getObjectRevisited(proc, List.of("Modules"), info).thenAccept(obj -> {
DbgModelTargetModule mod = (DbgModelTargetModule) obj;
if (mod == null) {
return;
}
getListeners().fire(TargetEventScopeListener.class)
.event(this, null, TargetEventType.MODULE_UNLOADED,
"Library " + name + " unloaded", List.of(mod));
"Library " + info.moduleName + " unloaded", List.of(mod));
});
}
@ -241,8 +237,8 @@ public class DbgModel2TargetRootImpl extends DbgModel2DefaultTargetModelRoot
}).finish();
}
private CompletableFuture<DbgModelTargetObject> getObject(Object object, List<String> ext,
String name) {
private CompletableFuture<DbgModelTargetObject> getObjectRevisited(Object object,
List<String> ext, Object info) {
List<String> objPath = findObject(object);
if (objPath == null) {
return CompletableFuture.completedFuture(null);
@ -257,19 +253,23 @@ public class DbgModel2TargetRootImpl extends DbgModel2DefaultTargetModelRoot
seq.exit();
return;
}
DbgModelTargetObject proxy = (DbgModelTargetObject) pobj;
DelegateDbgModel2TargetObject delegate =
DelegateDbgModel2TargetObject.getDelegate(proxy);
delegate.requestElements(true).thenAccept(__ -> {
Map<String, TargetObject> cachedElements = delegate.getCachedElements();
for (TargetObject val : cachedElements.values()) {
DbgModelTargetObject obj = (DbgModelTargetObject) val;
if (obj.getDisplay().contains(name)) {
seq.exit(obj);
}
DbgModel2TargetProxy proxy = (DbgModel2TargetProxy) pobj;
DelegateDbgModel2TargetObject delegate = proxy.getDelegate();
xpath.add(0, "Debugger");
DbgManager2Impl manager = (DbgManager2Impl) getManager();
List<ModelObject> list = manager.getAccess().getElements(xpath);
for (ModelObject obj : list) {
String searchKey = obj.getSearchKey();
if (searchKey.equals(info.toString())) {
String elKey = PathUtils.makeKey(searchKey);
DbgModel2TargetProxy proxyElement =
(DbgModel2TargetProxy) DelegateDbgModel2TargetObject
.makeProxy(delegate.getModel(), delegate, elKey, obj);
delegate.changeElements(List.of(), List.of(proxyElement), "Created");
seq.exit(proxyElement);
}
seq.exit((DbgModelTargetObject) null);
});
}
}).finish();
}
@ -350,17 +350,7 @@ public class DbgModel2TargetRootImpl extends DbgModel2DefaultTargetModelRoot
public void breakpointCreated(DbgBreakpointInfo info, DbgCause cause) {
int id = info.getDebugBreakpoint().getId();
bptInfoMap.put(id, info);
getObject(info.getProc(), List.of("Debug", "Breakpoints"), Integer.toHexString(id));
/*
getObject(info).thenAccept(obj -> {
DbgModelTargetBreakpointSpec bpt = (DbgModelTargetBreakpointSpec) obj;
if (bpt == null) {
return;
}
bpt.setBreakpointInfo(info);
bpt.setEnabled(true, "Created");
});
*/
getObjectRevisited(info.getProc(), List.of("Debug", "Breakpoints"), info);
}
@Override
@ -368,20 +358,19 @@ public class DbgModel2TargetRootImpl extends DbgModel2DefaultTargetModelRoot
DbgCause cause) {
int id = newInfo.getDebugBreakpoint().getId();
bptInfoMap.put(id, newInfo);
getObject(newInfo.getProc(), List.of("Debug", "Breakpoints"), Integer.toHexString(id));
getObjectRevisited(newInfo.getProc(), List.of("Debug", "Breakpoints"), newInfo);
}
@Override
public void breakpointDeleted(DbgBreakpointInfo info, DbgCause cause) {
int id = info.getDebugBreakpoint().getId();
bptInfoMap.remove(id);
getObject(info.getProc(), List.of("Debug", "Breakpoints"), Integer.toHexString(id));
getObjectRevisited(info.getProc(), List.of("Debug", "Breakpoints"), info);
}
@Override
public void breakpointHit(DbgBreakpointInfo info, DbgCause cause) {
int id = info.getDebugBreakpoint().getId();
getObject(info.getProc(), List.of("Debug", "Breakpoints"), Integer.toHexString(id))
getObjectRevisited(info.getProc(), List.of("Debug", "Breakpoints"), info)
.thenAccept(obj -> {
DbgModelTargetBreakpointSpec bpt = (DbgModelTargetBreakpointSpec) obj;
if (bpt == null) {

View file

@ -39,7 +39,7 @@ import utilities.util.ProxyUtilities;
public class DelegateDbgModel2TargetObject extends DbgModel2TargetObjectImpl implements //
DbgModelTargetAccessConditioned<DelegateDbgModel2TargetObject>, //
DbgModelTargetExecutionStateful<DelegateDbgModel2TargetObject>, //
DbgModelTargetBptHelper {
DbgModel2TargetProxy, DbgModelTargetBptHelper {
// Probably don-t need any of the handler-map or annotation stuff
protected final DbgStateListener accessListener = this::checkExited;
@ -163,12 +163,6 @@ public class DelegateDbgModel2TargetObject extends DbgModel2TargetObjectImpl imp
return new DelegateDbgModel2TargetObject(model, parent, key, object, mixins).proxy;
}
private static Map<DbgModelTargetObject, DelegateDbgModel2TargetObject> map = new HashMap<>();
public static DelegateDbgModel2TargetObject getDelegate(DbgModelTargetObject proxy) {
return map.get(proxy);
}
protected static final MethodHandles.Lookup LOOKUP = MethodHandles.lookup();
// NOTE: The Cleanable stuff is the replacement for overriding Object.finalize(), which
@ -201,15 +195,27 @@ public class DelegateDbgModel2TargetObject extends DbgModel2TargetObjectImpl imp
getManager().addStateListener(accessListener);
mixins.add(DbgModel2TargetProxy.class);
this.proxy =
ProxyUtilities.composeOnDelegate(DbgModelTargetObject.class, this, mixins, LOOKUP);
map.put(proxy, this);
if (proxy instanceof DbgEventsListener) {
model.getManager().addEventsListener((DbgEventsListener) proxy);
}
setModelObject(modelObject);
}
public DelegateDbgModel2TargetObject clone(String key, ModelObject modelObject) {
DbgModelTargetObject p = (DbgModelTargetObject) getImplParent();
List<Class<? extends TargetObject>> mixins = new ArrayList<>();
Class<? extends DbgModelTargetObject> mixin = lookupWrapperType(key, p.getName());
if (mixin != null) {
mixins.add(mixin);
}
DelegateDbgModel2TargetObject delegate =
new DelegateDbgModel2TargetObject(getModel(), p, key, modelObject, mixins);
return delegate;
}
@Override
public <T extends TypedTargetObject<T>> T as(Class<T> iface) {
return DebuggerObjectModel.requireIface(iface, proxy, getPath());
@ -348,6 +354,10 @@ public class DelegateDbgModel2TargetObject extends DbgModel2TargetObjectImpl imp
}
}
public DelegateDbgModel2TargetObject getDelegate() {
return this;
}
// Methods required for DbgModelTargetBreakpointSpec mixin
@Override

View file

@ -17,7 +17,6 @@
<attribute name="_value" schema="ANY" hidden="yes" />
<attribute name="_type" schema="STRING" hidden="yes" />
<attribute name="_order" schema="INT" hidden="yes" />
<attribute name="_supported_attach_kinds" schema="SET_ATTACH_KIND" required="yes" hidden="yes" />
<attribute name="_event_process" schema="STRING" hidden="yes" />
<attribute name="_event_thread" schema="STRING" hidden="yes" />
<attribute name="_parameters" schema="MAP_PARAMETERS" required="yes" hidden="yes" />
@ -29,7 +28,7 @@
<attribute name="Settings" schema="OBJECT" />
<attribute name="State" schema="OBJECT" />
<attribute name="Utility" schema="OBJECT" />
<attribute schema="VOID" />
<attribute schema="VOID" />
</schema>
<schema name="SessionContainer" canonical="yes">
<element schema="Session" />
@ -41,7 +40,7 @@
<attribute name="_value" schema="ANY" hidden="yes" />
<attribute name="_type" schema="STRING" hidden="yes" />
<attribute name="_order" schema="INT" hidden="yes" />
<attribute schema="VOID" />
<attribute schema="ANY" />
</schema>
<schema name="ConnectorContainer" canonical="yes">
<element schema="OBJECT" />
@ -135,7 +134,7 @@
<interface name="Interruptible" />
<interface name="Resumable" />
<element schema="VOID" />
<attribute name="_accessible" schema="BOOL" required="yes" hidden="yes" />
<attribute name="_accessible" schema="BOOL" hidden="yes" />
<attribute name="_modified" schema="BOOL" hidden="yes" />
<attribute name="_display" schema="STRING" hidden="yes" />
<attribute name="_kind" schema="STRING" fixed="yes" hidden="yes" />
@ -154,7 +153,7 @@
<schema name="Available">
<interface name="Attachable" />
<element schema="VOID" />
<attribute name="_pid" schema="LONG" hidden="yes" />
<attribute name="_pid" schema="INT" hidden="yes" />
<attribute name="_modified" schema="BOOL" hidden="yes" />
<attribute name="_display" schema="STRING" hidden="yes" />
<attribute name="_kind" schema="STRING" fixed="yes" hidden="yes" />
@ -182,7 +181,7 @@
<attribute name="_order" schema="INT" hidden="yes" />
<attribute name="Machine" schema="SessionAttributesMachine" fixed="yes" />
<attribute name="Target" schema="OBJECT" />
<attribute schema="VOID" />
<attribute schema="ANY" />
</schema>
<schema name="ProcessContainer" canonical="yes">
<interface name="EventScope" />
@ -197,7 +196,7 @@
<attribute name="_value" schema="ANY" hidden="yes" />
<attribute name="_type" schema="STRING" hidden="yes" />
<attribute name="_order" schema="INT" hidden="yes" />
<attribute schema="VOID" />
<attribute schema="ANY" />
</schema>
<schema name="SessionAttributesMachine">
<element schema="VOID" />
@ -213,7 +212,7 @@
<attribute name="Debugger" schema="STRING" />
<attribute name="OS" schema="STRING" />
<attribute name="Mode" schema="STRING" />
<attribute schema="VOID" />
<attribute schema="ANY" />
</schema>
<schema name="Process">
<interface name="Aggregate" />
@ -242,7 +241,6 @@
<attribute name="_state" schema="EXECUTION_STATE" required="yes" hidden="yes" />
<attribute name="_accessible" schema="BOOL" required="yes" hidden="yes" />
<attribute name="_supported_attach_kinds" schema="SET_ATTACH_KIND" required="yes" hidden="yes" />
<attribute name="_parameters" schema="MAP_PARAMETERS" required="yes" fixed="yes" hidden="yes" />
<attribute name="_supported_step_kinds" schema="SET_STEP_KIND" required="yes" fixed="yes" hidden="yes" />
<attribute name="Debug" schema="DebugContainer" required="yes" fixed="yes" />
<attribute name="Memory" schema="Memory" required="yes" fixed="yes" />
@ -253,8 +251,8 @@
<attribute name="Handle" schema="OBJECT" />
<attribute name="Id" schema="OBJECT" />
<attribute name="Io" schema="OBJECT" />
<attribute name="Name" schema="STRING" />
<attribute schema="VOID" />
<attribute name="Name" schema="OBJECT" />
<attribute schema="ANY" />
</schema>
<schema name="Memory" canonical="yes">
<interface name="Memory" />
@ -267,7 +265,7 @@
<attribute name="_value" schema="ANY" hidden="yes" />
<attribute name="_type" schema="STRING" hidden="yes" />
<attribute name="_order" schema="INT" hidden="yes" />
<attribute schema="VOID" />
<attribute schema="ANY" />
</schema>
<schema name="ModuleContainer" canonical="yes">
<interface name="ModuleContainer" />
@ -284,7 +282,7 @@
<attribute name="_value" schema="ANY" hidden="yes" />
<attribute name="_type" schema="STRING" hidden="yes" />
<attribute name="_order" schema="INT" hidden="yes" />
<attribute schema="VOID" />
<attribute schema="ANY" />
</schema>
<schema name="DebugContainer" canonical="yes">
<element schema="OBJECT" />
@ -297,7 +295,7 @@
<attribute name="_type" schema="STRING" hidden="yes" />
<attribute name="_order" schema="INT" hidden="yes" />
<attribute name="Breakpoints" schema="BreakpointContainer" required="yes" fixed="yes" />
<attribute schema="VOID" />
<attribute schema="ANY" />
</schema>
<schema name="ThreadContainer" canonical="yes">
<interface name="EventScope" />
@ -312,7 +310,7 @@
<attribute name="_value" schema="ANY" hidden="yes" />
<attribute name="_type" schema="STRING" hidden="yes" />
<attribute name="_order" schema="INT" hidden="yes" />
<attribute schema="VOID" />
<attribute schema="ANY" />
</schema>
<schema name="MemoryRegion">
<interface name="MemoryRegion" />
@ -360,11 +358,11 @@
<attribute name="_supported_step_kinds" schema="SET_STEP_KIND" required="yes" fixed="yes" hidden="yes" />
<attribute name="Registers" schema="RegisterContainer" required="yes" fixed="yes" />
<attribute name="Stack" schema="Stack" required="yes" fixed="yes" />
<attribute name="Environment" schema="OBJECT" />
<attribute name="Environment" schema="OBJECT" />
<attribute name="Id" schema="OBJECT" />
<attribute name="Name" schema="STRING" />
<attribute name="_arch" schema="STRING" />
<attribute schema="VOID" />
<attribute name="Name" schema="OBJECT" />
<attribute name="_arch" schema="STRING" />
<attribute schema="ANY" />
</schema>
<schema name="Module">
<interface name="Module" />
@ -379,12 +377,13 @@
<attribute name="_value" schema="ANY" hidden="yes" />
<attribute name="_type" schema="STRING" hidden="yes" />
<attribute name="_order" schema="INT" hidden="yes" />
<attribute name="Symbols" schema="SymbolContainer" required="yes" fixed="yes" />
<attribute name="BaseAddress" schema="ADDRESS" />
<attribute name="ImageName" schema="STRING" />
<attribute name="TimeStamp" schema="INT" />
<attribute name="Len" schema="STRING" />
<attribute schema="VOID" />
<attribute name="BaseAddress" schema="OBJECT" />
<attribute name="ImageName" schema="OBJECT" />
<attribute name="TimeStamp" schema="OBJECT" />
<attribute name="Len" schema="OBJECT" />
<attribute name="Name" schema="OBJECT" />
<attribute name="Size" schema="OBJECT" />
<attribute schema="ANY" />
</schema>
<schema name="BreakpointContainer" canonical="yes">
<interface name="BreakpointContainer" />
@ -398,7 +397,7 @@
<attribute name="_value" schema="ANY" hidden="yes" />
<attribute name="_type" schema="STRING" hidden="yes" />
<attribute name="_order" schema="INT" hidden="yes" />
<attribute schema="VOID" />
<attribute schema="ANY" />
</schema>
<schema name="SymbolContainer" canonical="yes">
<interface name="SymbolNamespace" />
@ -411,7 +410,7 @@
<attribute name="_value" schema="ANY" hidden="yes" />
<attribute name="_type" schema="STRING" hidden="yes" />
<attribute name="_order" schema="INT" hidden="yes" />
<attribute schema="VOID" />
<attribute schema="ANY" />
</schema>
<schema name="RegisterContainer" canonical="yes">
<interface name="RegisterContainer" />
@ -430,7 +429,7 @@
<attribute name="SIMD" schema="OBJECT" />
<attribute name="User" schema="RegisterBank" />
<attribute name="VFP" schema="OBJECT" />
<attribute schema="VOID" />
<attribute schema="ANY" />
</schema>
<schema name="RegisterBank">
<interface name="RegisterBank" />
@ -447,6 +446,19 @@
<attribute schema="OBJECT" />
</schema>
<schema name="Stack" canonical="yes">
<element schema="VOID" />
<attribute name="_modified" schema="BOOL" hidden="yes" />
<attribute name="_display" schema="STRING" hidden="yes" />
<attribute name="_kind" schema="STRING" fixed="yes" hidden="yes" />
<attribute name="_update_mode" schema="UPDATE_MODE" hidden="yes" />
<attribute name="_short_display" schema="STRING" hidden="yes" />
<attribute name="_value" schema="ANY" hidden="yes" />
<attribute name="_type" schema="STRING" hidden="yes" />
<attribute name="_order" schema="INT" hidden="yes" />
<attribute name="Frames" schema="Frames" />
<attribute schema="ANY" />
</schema>
<schema name="Frames" canonical="yes">
<interface name="Stack" />
<element schema="StackFrame" />
<attribute name="_modified" schema="BOOL" hidden="yes" />
@ -457,7 +469,7 @@
<attribute name="_value" schema="ANY" hidden="yes" />
<attribute name="_type" schema="STRING" hidden="yes" />
<attribute name="_order" schema="INT" hidden="yes" />
<attribute schema="VOID" />
<attribute schema="ANY" />
</schema>
<schema name="BreakpointSpec" canonical="yes">
<interface name="BreakpointSpec" />
@ -480,10 +492,10 @@
<attribute name="_value" schema="ANY" hidden="yes" />
<attribute name="_type" schema="STRING" hidden="yes" />
<attribute name="_order" schema="INT" hidden="yes" />
<attribute name="Type" schema="STRING" />
<attribute name="Disposition" schema="STRING" />
<attribute name="Pending" schema="STRING" />
<attribute name="Times" schema="INT" />
<attribute name="Type" schema="OBJECT" />
<attribute name="Disposition" schema="OBJECT" />
<attribute name="Pending" schema="OBJECT" />
<attribute name="Times" schema="OBJECT" />
<attribute schema="VOID" />
</schema>
<schema name="StackFrame">
@ -499,11 +511,11 @@
<attribute name="_type" schema="STRING" hidden="yes" />
<attribute name="_order" schema="INT" hidden="yes" />
<attribute name="Attributes" schema="StackFrameAttributes" />
<attribute schema="VOID" />
<attribute schema="ANY" />
</schema>
<schema name="StackFrameAttributes">
<element schema="VOID" />
<attribute name="_pc" schema="ADDRESS" required="yes" hidden="yes" />
<attribute name="_pc" schema="ADDRESS" hidden="yes" />
<attribute name="_modified" schema="BOOL" hidden="yes" />
<attribute name="_display" schema="STRING" hidden="yes" />
<attribute name="_kind" schema="STRING" fixed="yes" hidden="yes" />
@ -512,14 +524,14 @@
<attribute name="_value" schema="ANY" hidden="yes" />
<attribute name="_type" schema="STRING" hidden="yes" />
<attribute name="_order" schema="INT" hidden="yes" />
<attribute name="FrameNumber" schema="STRING" />
<attribute name="FrameOffset" schema="STRING" />
<attribute name="FuncTableEntry" schema="STRING" />
<attribute name="InstructionOffset" schema="STRING" />
<attribute name="ReturnOffset" schema="STRING" />
<attribute name="StackOffset" schema="STRING" />
<attribute name="Virtual" schema="STRING" />
<attribute schema="VOID" />
<attribute name="FrameNumber" schema="OBJECT" />
<attribute name="FrameOffset" schema="OBJECT" />
<attribute name="FuncTableEntry" schema="OBJECT" />
<attribute name="InstructionOffset" schema="OBJECT" />
<attribute name="ReturnOffset" schema="OBJECT" />
<attribute name="StackOffset" schema="OBJECT" />
<attribute name="Virtual" schema="OBJECT" />
<attribute schema="ANY" />
</schema>
<schema name="Symbol">
<interface name="Symbol" />