GP-740: Removed TargetObjectRef and cleaned up.

This commit is contained in:
Dan 2021-03-01 15:14:27 -05:00
parent b9f9c69be4
commit 6614b54248
328 changed files with 3177 additions and 4428 deletions

View file

@ -16,6 +16,7 @@
package agent.dbgeng.model;
import static agent.dbgeng.testutil.DummyProc.runProc;
import static ghidra.lifecycle.Unfinished.TODO;
import static org.junit.Assert.*;
import java.util.*;
@ -33,12 +34,10 @@ import ghidra.async.*;
import ghidra.dbg.DebugModelConventions;
import ghidra.dbg.DebugModelConventions.AllRequiredAccess;
import ghidra.dbg.DebuggerObjectModel;
import ghidra.dbg.attributes.TargetObjectRef;
import ghidra.dbg.attributes.TargetObjectRefList;
import ghidra.dbg.attributes.TargetObjectList;
import ghidra.dbg.error.DebuggerModelNoSuchPathException;
import ghidra.dbg.error.DebuggerModelTypeException;
import ghidra.dbg.target.*;
import ghidra.dbg.target.TargetAccessConditioned.TargetAccessibility;
import ghidra.dbg.target.TargetBreakpointContainer.TargetBreakpointKindSet;
import ghidra.dbg.target.TargetBreakpointSpec.TargetBreakpointKind;
import ghidra.dbg.target.TargetConsole.Channel;
@ -139,7 +138,7 @@ public abstract class AbstractModelForDbgTest
DebugModelConventions.trackAccessibility(root.get()).handle(seq::next);
}, access).then(seq -> {
Msg.debug(this, "Waiting for session access...");
access.get().waitValue(TargetAccessibility.ACCESSIBLE).handle(seq::next);
access.get().waitValue(true).handle(seq::next);
}).then(seq -> {
model.fetchModelObject("Doesn't exist").handle(seq::next);
}, TypeSpec.cls(TargetObject.class)).then((obj, seq) -> {
@ -156,7 +155,7 @@ public abstract class AbstractModelForDbgTest
AtomicReference<TargetObject> root = new AtomicReference<>();
AtomicReference<AllRequiredAccess> access = new AtomicReference<>();
AtomicReference<DbgModelTargetLauncher<?>> launcher = new AtomicReference<>();
AtomicReference<DbgModelTargetLauncher> launcher = new AtomicReference<>();
TypeSpec<Map<String, ? extends TargetObject>> t = TypeSpec.auto();
waitOn(AsyncUtils.sequence(TypeSpec.VOID).then(seq -> {
@ -169,7 +168,7 @@ public abstract class AbstractModelForDbgTest
DebugModelConventions.trackAccessibility(root.get()).handle(seq::next);
}, access).then(seq -> {
Msg.debug(this, "Waiting for session access...");
access.get().waitValue(TargetAccessibility.ACCESSIBLE).handle(seq::next);
access.get().waitValue(true).handle(seq::next);
}).then(seq -> {
Msg.debug(this, "Finding TargetLauncher...");
DebugModelConventions.findSuitable(DbgModelTargetLauncher.class, root.get())
@ -179,11 +178,10 @@ public abstract class AbstractModelForDbgTest
launcher.get().launch("notepad", "junk.txt").handle(seq::nextIgnore);
}).then(seq -> {
Msg.debug(this, "Waiting for session access...");
access.get().waitValue(TargetAccessibility.ACCESSIBLE).handle(seq::next);
access.get().waitValue(true).handle(seq::next);
}).then(seq -> {
Msg.debug(this, "Getting Processes (after launch)...");
model.fetchObjectElements(List.of("Sessions", "[0]"))
.thenCompose(DebugModelConventions::fetchAll)
.handle(seq::next);
}, t).then((children, seq) -> {
Msg.debug(this, "Processes after: " + children);
@ -201,7 +199,7 @@ public abstract class AbstractModelForDbgTest
AtomicReference<TargetObject> root = new AtomicReference<>();
AtomicReference<TargetObject> session = new AtomicReference<>();
AtomicReference<AllRequiredAccess> rootAccess = new AtomicReference<>();
AtomicReference<DbgModelTargetLauncher<?>> launcher = new AtomicReference<>();
AtomicReference<DbgModelTargetLauncher> launcher = new AtomicReference<>();
AtomicReference<AllRequiredAccess> launcherAccess = new AtomicReference<>();
TypeSpec<Map<String, ? extends TargetObject>> t = TypeSpec.auto();
@ -215,7 +213,7 @@ public abstract class AbstractModelForDbgTest
DebugModelConventions.trackAccessibility(root.get()).handle(seq::next);
}, rootAccess).then(seq -> {
Msg.debug(this, "Waiting for session access...");
rootAccess.get().waitValue(TargetAccessibility.ACCESSIBLE).handle(seq::next);
rootAccess.get().waitValue(true).handle(seq::next);
}).then(seq -> {
model.fetchModelObject(List.of("Sessions", "[0]")).handle(seq::next);
}, session).then(seq -> {
@ -224,22 +222,21 @@ public abstract class AbstractModelForDbgTest
session.get()).handle(seq::next);
}, TypeSpec.cls(TargetObject.class)).then((obj, seq) -> {
assertTrue(obj.getInterfaceNames().contains("Launcher"));
launcher.set((DbgModelTargetLauncher<?>) obj);
launcher.set((DbgModelTargetLauncher) obj);
Msg.debug(this, "Tracking process access...");
DebugModelConventions.trackAccessibility(obj).handle(seq::next);
}, launcherAccess).then(seq -> {
Msg.debug(this, "Waiting for process access...");
launcherAccess.get().waitValue(TargetAccessibility.ACCESSIBLE).handle(seq::next);
launcherAccess.get().waitValue(true).handle(seq::next);
}).then(seq -> {
Msg.debug(this, "Launching...");
launcher.get().launch("notepad", "junk.txt").handle(seq::nextIgnore);
}).then(seq -> {
Msg.debug(this, "Waiting for session access (again)...");
rootAccess.get().waitValue(TargetAccessibility.ACCESSIBLE).handle(seq::next);
rootAccess.get().waitValue(true).handle(seq::next);
}).then(seq -> {
Msg.debug(this, "Getting Processes (after launch)...");
model.fetchObjectElements(List.of("Sessions", "[0]", "Processes"))
.thenCompose(DebugModelConventions::fetchAll)
.handle(seq::next);
}, t).then((elements, seq) -> {
Msg.debug(this, "Processes after: " + elements);
@ -267,10 +264,9 @@ public abstract class AbstractModelForDbgTest
DebugModelConventions.trackAccessibility(root.get()).handle(seq::next);
}, access).then(seq -> {
Msg.debug(this, "Waiting for session access...");
access.get().waitValue(TargetAccessibility.ACCESSIBLE).handle(seq::next);
access.get().waitValue(true).handle(seq::next);
}).then(seq -> {
model.fetchObjectElements(List.of("Sessions", "[0]", "Available"))
.thenCompose(DebugModelConventions::fetchAll)
.handle(seq::next);
}, DebuggerObjectModel.ELEMENT_MAP_TYPE).then((available, seq) -> {
assertTrue(available.containsKey(Long.toString(np.pid)));
@ -298,7 +294,7 @@ public abstract class AbstractModelForDbgTest
DebugModelConventions.trackAccessibility(root.get()).handle(seq::next);
}, access).then(seq -> {
Msg.debug(this, "Waiting for session access...");
access.get().waitValue(TargetAccessibility.ACCESSIBLE).handle(seq::next);
access.get().waitValue(true).handle(seq::next);
}).then(seq -> {
Msg.debug(this, "Finding TargetLauncher...");
DebugModelConventions.findSuitable(TargetAttacher.class, root.get())
@ -306,16 +302,11 @@ public abstract class AbstractModelForDbgTest
seq::next);
}, proc).then(seq -> {
Msg.debug(this, "Attaching to bogus path...");
TargetAttacher<?> attacher = proc.get().as(TargetAttacher.tclass);
attacher.attach(
model.createRef("Sessions", "[0]", "Available", "[" + np.pid + "]")
.as(
TargetAttachable.tclass))
.handle(
seq::nextIgnore);
TargetAttacher attacher = proc.get().as(TargetAttacher.class);
TODO();
seq.next(null, null);
}).then(seq -> {
model.fetchObjectElements(List.of("Sessions", "[0]", "Processes"))
.thenCompose(DebugModelConventions::fetchAll)
.handle(seq::next);
// NB: listProcesses will fail if no process is being debugged
}, DebuggerObjectModel.ELEMENT_MAP_TYPE).then((processes, seq) -> {
@ -332,8 +323,8 @@ public abstract class AbstractModelForDbgTest
AtomicReference<TargetObject> root = new AtomicReference<>();
AtomicReference<AllRequiredAccess> access = new AtomicReference<>();
AtomicReference<TargetAttacher<?>> attacher = new AtomicReference<>();
AtomicReference<TargetAttachable<?>> attachable = new AtomicReference<>();
AtomicReference<TargetAttacher> attacher = new AtomicReference<>();
AtomicReference<TargetAttachable> attachable = new AtomicReference<>();
TypeSpec<Map<String, ? extends TargetObject>> t = TypeSpec.auto();
waitOn(AsyncUtils.sequence(TypeSpec.VOID).then(seq -> {
@ -346,7 +337,7 @@ public abstract class AbstractModelForDbgTest
DebugModelConventions.trackAccessibility(root.get()).handle(seq::next);
}, access).then(seq -> {
Msg.debug(this, "Waiting for session access...");
access.get().waitValue(TargetAccessibility.ACCESSIBLE).handle(seq::next);
access.get().waitValue(true).handle(seq::next);
}).then(seq -> {
// Msg.debug(this, "Getting Processes (before attach)...");
// model.getObjectElements(List.of("Sessions", "[0]", "Processes")).handle(seq::next);
@ -366,7 +357,7 @@ public abstract class AbstractModelForDbgTest
.thenAccept(o -> {
Msg.debug(this, " Got Attachable: " + o);
assertTrue(o.getInterfaceNames().contains("Attachable"));
attachable.set((TargetAttachable<?>) o);
attachable.set((TargetAttachable) o);
}));
fence.ready().handle(seq::next);
}).then(seq -> {
@ -374,11 +365,10 @@ public abstract class AbstractModelForDbgTest
attacher.get().attach(attachable.get()).handle(seq::nextIgnore);
}).then(seq -> {
Msg.debug(this, "Waiting for session access (again)...");
access.get().waitValue(TargetAccessibility.ACCESSIBLE).handle(seq::next);
access.get().waitValue(true).handle(seq::next);
}).then(seq -> {
Msg.debug(this, "Getting Processes (after attach)...");
model.fetchObjectElements(List.of("Sessions", "[0]", "Processes"))
.thenCompose(DebugModelConventions::fetchAll)
.handle(seq::next);
}, t).then((elements, seq) -> {
Msg.debug(this, "Processes after: " + elements);
@ -386,7 +376,7 @@ public abstract class AbstractModelForDbgTest
Msg.debug(this, "Killing...");
TargetObject attached = elements.get("0");
assertTrue(attached.getInterfaceNames().contains("Killable"));
TargetKillable<?> killable = (TargetKillable<?>) attached;
TargetKillable killable = (TargetKillable) attached;
killable.kill().handle(seq::next);
}).finish());
}
@ -412,7 +402,7 @@ public abstract class AbstractModelForDbgTest
DebugModelConventions.trackAccessibility(root.get()).handle(seq::next);
}, access).then(seq -> {
Msg.debug(this, "Waiting for session access...");
access.get().waitValue(TargetAccessibility.ACCESSIBLE).handle(seq::next);
access.get().waitValue(true).handle(seq::next);
}).then(seq -> {
Msg.debug(this, "Finding TargetLauncher...");
DebugModelConventions.findSuitable(TargetAttacher.class, root.get())
@ -420,17 +410,15 @@ public abstract class AbstractModelForDbgTest
seq::next);
}, obj).then(seq -> {
Msg.debug(this, "Attaching...");
TargetAttacher<?> attacher = obj.get().as(TargetAttacher.tclass);
attacher.attach(model.createRef("Sessions", "[0]", "Available", "[" + np.pid + "]")
.as(TargetAttachable.tclass))
TargetAttacher attacher = obj.get().as(TargetAttacher.class);
attacher.attach(np.pid)
.handle(seq::nextIgnore);
}).then(seq -> {
Msg.debug(this, "Waiting for session access (again, again)...");
access.get().waitValue(TargetAccessibility.ACCESSIBLE).handle(seq::next);
access.get().waitValue(true).handle(seq::next);
}).then(seq -> {
Msg.debug(this, "Getting Processes (after attach)...");
model.fetchObjectElements(List.of("Sessions", "[0]", "Processes"))
.thenCompose(DebugModelConventions::fetchAll)
.handle(seq::next);
}, t).then((elements, seq) -> {
Msg.debug(this, "Processes after: " + elements);
@ -438,7 +426,7 @@ public abstract class AbstractModelForDbgTest
Msg.debug(this, "Killing...");
TargetObject attached = elements.get("0");
assertTrue(attached.getInterfaceNames().contains("Killable"));
TargetKillable<?> killable = (TargetKillable<?>) attached;
TargetKillable killable = (TargetKillable) attached;
killable.kill().handle(seq::next);
}).finish());
}
@ -464,7 +452,7 @@ public abstract class AbstractModelForDbgTest
DebugModelConventions.trackAccessibility(root.get()).handle(seq::next);
}, access).then(seq -> {
Msg.debug(this, "Waiting for session access...");
access.get().waitValue(TargetAccessibility.ACCESSIBLE).handle(seq::next);
access.get().waitValue(true).handle(seq::next);
}).then(seq -> {
Msg.debug(this, "Finding TargetLauncher...");
DebugModelConventions.findSuitable(TargetAttacher.class, root.get())
@ -472,29 +460,25 @@ public abstract class AbstractModelForDbgTest
seq::next);
}, obj).then(seq -> {
Msg.debug(this, "Attaching...");
TargetAttacher<?> attacher = obj.get().as(TargetAttacher.tclass);
attacher.attach(
model.createRef("Sessions", "[0]", "Available", "[" + np.pid + "]")
.as(
TargetAttachable.tclass))
TargetAttacher attacher = obj.get().as(TargetAttacher.class);
attacher.attach(np.pid)
.handle(seq::nextIgnore);
}).then(seq -> {
Msg.debug(this, "Waiting for session access (again, again)...");
access.get().waitValue(TargetAccessibility.ACCESSIBLE).handle(seq::next);
access.get().waitValue(true).handle(seq::next);
}).then(seq -> {
Msg.debug(this, "Getting Process 1...");
model.fetchModelObject("Sessions", "[0]", "Processes", "[0]").handle(seq::next);
}, obj).then(seq -> {
Msg.debug(this, "Resuming...");
TargetResumable<?> resumable = obj.get().as(TargetResumable.tclass);
TargetResumable resumable = obj.get().as(TargetResumable.class);
resumable.resume().handle(seq::next);
}).then(seq -> {
Msg.debug(this, "Waiting for session access (after resume)...");
access.get().waitValue(TargetAccessibility.INACCESSIBLE).handle(seq::next);
access.get().waitValue(true).handle(seq::next);
}).then(seq -> {
Msg.debug(this, "Getting Processes (after attach)...");
model.fetchObjectElements(List.of("Sessions", "[0]", "Processes"))
.thenCompose(DebugModelConventions::fetchAll)
.handle(seq::next);
}, t).then((elements, seq) -> {
Msg.debug(this, "Processes after: " + elements);
@ -502,7 +486,7 @@ public abstract class AbstractModelForDbgTest
Msg.debug(this, "Killing...");
TargetObject attached = elements.get("0");
assertTrue(attached.getInterfaceNames().contains("Killable"));
TargetKillable<?> killable = (TargetKillable<?>) attached;
TargetKillable killable = (TargetKillable) attached;
killable.kill().handle(seq::nextIgnore);
}).finish());
}
@ -526,29 +510,29 @@ public abstract class AbstractModelForDbgTest
DebugModelConventions.trackAccessibility(root.get()).handle(seq::next);
}, access).then(seq -> {
Msg.debug(this, "Waiting for session access...");
access.get().waitValue(TargetAccessibility.ACCESSIBLE).handle(seq::next);
access.get().waitValue(true).handle(seq::next);
}).then(seq -> {
Msg.debug(this, "Finding TargetLauncher...");
DebugModelConventions.findSuitable(DbgModelTargetLauncher.class, root.get())
.handle(seq::next);
}, obj).then(seq -> {
Msg.debug(this, "Launching...");
TargetLauncher<?> launcher = obj.get().as(TargetLauncher.tclass);
TargetLauncher launcher = obj.get().as(TargetLauncher.class);
launcher.launch(Map.of(TargetCmdLineLauncher.CMDLINE_ARGS_NAME, "notepad junk.txt"))
.handle(seq::nextIgnore);
}).then(seq -> {
Msg.debug(this, "Waiting for session access (again)...");
access.get().waitValue(TargetAccessibility.ACCESSIBLE).handle(seq::next);
access.get().waitValue(true).handle(seq::next);
}).then(seq -> {
Msg.debug(this, "Getting Process 1...");
model.fetchModelObject("Sessions", "[0]", "Processes", "[0]").handle(seq::next);
}, obj).then(seq -> {
Msg.debug(this, "Resuming...");
TargetResumable<?> resumable = obj.get().as(TargetResumable.tclass);
TargetResumable resumable = obj.get().as(TargetResumable.class);
resumable.resume().handle(seq::next);
}).then(seq -> {
Msg.debug(this, "Waiting for session access (after resume)...");
access.get().waitValue(TargetAccessibility.INACCESSIBLE).handle(seq::next);
access.get().waitValue(true).handle(seq::next);
}).finish());
}
}
@ -572,7 +556,7 @@ public abstract class AbstractModelForDbgTest
DebugModelConventions.trackAccessibility(root.get()).handle(seq::next);
}, access).then(seq -> {
Msg.debug(this, "Waiting for session access...");
access.get().waitValue(TargetAccessibility.ACCESSIBLE).handle(seq::next);
access.get().waitValue(true).handle(seq::next);
}).then(seq -> {
Msg.debug(this, "Finding TargetLauncher...");
DebugModelConventions.findSuitable(TargetAttacher.class, root.get())
@ -580,10 +564,9 @@ public abstract class AbstractModelForDbgTest
seq::next);
}, proc).then(seq -> {
Msg.debug(this, "Attaching to bogus path...");
TargetAttacher<?> attacher = proc.get().as(TargetAttacher.tclass);
attacher.attach(model.createRef("Sessions", "[0]", "Available", "Process -1")
.as(TargetAttachable.tclass))
.handle(seq::nextIgnore);
TargetAttacher attacher = proc.get().as(TargetAttacher.class);
TODO();
seq.next(null, null);
}).finish());
}
}
@ -607,7 +590,7 @@ public abstract class AbstractModelForDbgTest
DebugModelConventions.trackAccessibility(root.get()).handle(seq::next);
}, access).then(seq -> {
Msg.debug(this, "Waiting for session access...");
access.get().waitValue(TargetAccessibility.ACCESSIBLE).handle(seq::next);
access.get().waitValue(true).handle(seq::next);
}).then(seq -> {
Msg.debug(this, "Finding TargetLauncher...");
DebugModelConventions.findSuitable(TargetAttacher.class, root.get())
@ -615,11 +598,9 @@ public abstract class AbstractModelForDbgTest
seq::next);
}, proc).then(seq -> {
Msg.debug(this, "Attaching to bogus path...");
TargetAttacher<?> attacher = proc.get().as(TargetAttacher.tclass);
attacher.attach(model.createRef("Sessions", "[0]", "Available")
.as(
TargetAttachable.tclass))
.handle(seq::nextIgnore);
TargetAttacher attacher = proc.get().as(TargetAttacher.class);
TODO();
seq.next(null, null);
}).finish());
fail("Exception expected");
}
@ -662,10 +643,10 @@ public abstract class AbstractModelForDbgTest
DebugModelConventions.trackAccessibility(root.get()).handle(seq::next);
}, access).then(seq -> {
Msg.debug(this, "Waiting for session access...");
access.get().waitValue(TargetAccessibility.ACCESSIBLE).handle(seq::next);
access.get().waitValue(true).handle(seq::next);
}).then(seq -> {
Msg.debug(this, "Running command...");
TargetInterpreter<?> interpreter = root.get().as(TargetInterpreter.tclass);
TargetInterpreter interpreter = root.get().as(TargetInterpreter.class);
interpreter.execute(".echo xyzzy").handle(seq::next);
}).then(seq -> {
Msg.debug(this, "Waiting for expected output...");
@ -705,10 +686,10 @@ public abstract class AbstractModelForDbgTest
DebugModelConventions.trackAccessibility(root.get()).handle(seq::next);
}, access).then(seq -> {
Msg.debug(this, "Waiting for session access...");
access.get().waitValue(TargetAccessibility.ACCESSIBLE).handle(seq::next);
access.get().waitValue(true).handle(seq::next);
}).then(seq -> {
Msg.debug(this, "Running command with capture...");
TargetInterpreter<?> interpreter = root.get().as(TargetInterpreter.tclass);
TargetInterpreter interpreter = root.get().as(TargetInterpreter.class);
interpreter.executeCapture(".echo xyzzy").handle(seq::next);
}, TypeSpec.STRING).then((out, seq) -> {
Msg.debug(this, "Captured: " + out);
@ -725,7 +706,7 @@ public abstract class AbstractModelForDbgTest
AtomicReference<TargetObject> root = new AtomicReference<>();
AtomicReference<AllRequiredAccess> access = new AtomicReference<>();
AtomicReference<TargetBreakpointContainer<?>> breaks = new AtomicReference<>();
AtomicReference<TargetBreakpointContainer> breaks = new AtomicReference<>();
waitOn(AsyncUtils.sequence(TypeSpec.VOID).then(seq -> {
m.init().handle(seq::next);
@ -737,7 +718,7 @@ public abstract class AbstractModelForDbgTest
DebugModelConventions.trackAccessibility(root.get()).handle(seq::next);
}, access).then(seq -> {
Msg.debug(this, "Waiting for session access...");
access.get().waitValue(TargetAccessibility.ACCESSIBLE).handle(seq::next);
access.get().waitValue(true).handle(seq::next);
}).then(seq -> {
Msg.debug(this, "Finding breakpoint container...");
DebugModelConventions.findSuitable(TargetBreakpointContainer.class, root.get())
@ -752,7 +733,7 @@ public abstract class AbstractModelForDbgTest
}
}
public static final TypeSpec<Collection<? extends TargetBreakpointLocation<?>>> BL_COL_SPEC =
public static final TypeSpec<Collection<? extends TargetBreakpointLocation>> BL_COL_SPEC =
null;
@Test
@ -762,9 +743,9 @@ public abstract class AbstractModelForDbgTest
AtomicReference<TargetObject> root = new AtomicReference<>();
AtomicReference<AllRequiredAccess> access = new AtomicReference<>();
AtomicReference<DbgModelTargetLauncher<?>> launcher = new AtomicReference<>();
AtomicReference<TargetBreakpointContainer<?>> breaks = new AtomicReference<>();
AtomicReference<TargetBreakpointLocation<?>> eff = new AtomicReference<>();
AtomicReference<DbgModelTargetLauncher> launcher = new AtomicReference<>();
AtomicReference<TargetBreakpointContainer> breaks = new AtomicReference<>();
AtomicReference<TargetBreakpointLocation> loc = new AtomicReference<>();
waitOn(AsyncUtils.sequence(TypeSpec.VOID).then(seq -> {
m.init().handle(seq::next);
@ -776,7 +757,7 @@ public abstract class AbstractModelForDbgTest
DebugModelConventions.trackAccessibility(root.get()).handle(seq::next);
}, access).then(seq -> {
Msg.debug(this, "Waiting for session access...");
access.get().waitValue(TargetAccessibility.ACCESSIBLE).handle(seq::next);
access.get().waitValue(true).handle(seq::next);
}).then(seq -> {
Msg.debug(this, "Finding TargetLauncher...");
DebugModelConventions.findSuitable(DbgModelTargetLauncher.class, root.get())
@ -801,20 +782,19 @@ public abstract class AbstractModelForDbgTest
Msg.debug(this, "Getting breakpoint specs...");
breaks.get()
.fetchElements()
.thenCompose(DebugModelConventions::fetchAll)
.handle(seq::next);
}, DebuggerObjectModel.ELEMENT_MAP_TYPE).then((specs, seq) -> {
Msg.debug(this, "Got specs: " + specs);
assertEquals(1, specs.size());
TargetBreakpointSpec<?> spec = specs.get("0").as(TargetBreakpointSpec.tclass);
TargetBreakpointSpec spec = specs.get("0").as(TargetBreakpointSpec.class);
spec.getLocations().handle(seq::next);
}, BL_COL_SPEC).then((es, seq) -> {
Msg.debug(this, "Got effectives: " + es);
assertEquals(1, es.size());
eff.set(es.iterator().next());
Address addr = eff.get().getAddress();
loc.set(es.iterator().next());
Address addr = loc.get().getAddress();
Msg.debug(this, "Got address: " + addr);
TargetObjectRefList<?> list = eff.get().getAffects();
TargetObjectList<?> list = loc.get().getAffects();
Msg.debug(this, "Got affects: " + list);
assertEquals(1, list.size());
seq.exit();
@ -829,8 +809,8 @@ public abstract class AbstractModelForDbgTest
AtomicReference<TargetObject> root = new AtomicReference<>();
AtomicReference<AllRequiredAccess> access = new AtomicReference<>();
AtomicReference<TargetBreakpointContainer<?>> breaks = new AtomicReference<>();
AtomicReference<DbgModelTargetLauncher<?>> launcher = new AtomicReference<>();
AtomicReference<TargetBreakpointContainer> breaks = new AtomicReference<>();
AtomicReference<TargetLauncher> launcher = new AtomicReference<>();
AtomicReference<TargetObject> obj = new AtomicReference<>();
waitOn(AsyncUtils.sequence(TypeSpec.VOID).then(seq -> {
m.init().handle(seq::next);
@ -842,18 +822,20 @@ public abstract class AbstractModelForDbgTest
DebugModelConventions.trackAccessibility(root.get()).handle(seq::next);
}, access).then(seq -> {
Msg.debug(this, "Waiting for session access...");
access.get().waitValue(TargetAccessibility.ACCESSIBLE).handle(seq::next);
access.get().waitValue(true).handle(seq::next);
}).then(seq -> {
Msg.debug(this, "Finding TargetLauncher...");
DebugModelConventions.findSuitable(DbgModelTargetLauncher.class, root.get())
DebugModelConventions.findSuitable(TargetLauncher.class, root.get())
.handle(
seq::next);
}, launcher).then(seq -> {
Msg.debug(this, "Launching...");
launcher.get().launch("notepad", "junk.txt").handle(seq::nextIgnore);
launcher.get()
.launch(Map.of("args", List.of("notepad", "junk.txt")))
.handle(seq::nextIgnore);
}).then(seq -> {
Msg.debug(this, "Waiting for session access (again)...");
access.get().waitValue(TargetAccessibility.ACCESSIBLE).handle(seq::next);
access.get().waitValue(true).handle(seq::next);
}).then(seq -> {
Msg.debug(this, "Finding breakpoint container...");
DebugModelConventions.findSuitable(TargetBreakpointContainer.class, root.get())
@ -869,20 +851,17 @@ public abstract class AbstractModelForDbgTest
model.fetchModelObject("Sessions", "[0]", "Processes", "[0]").handle(seq::next);
}, obj).then(seq -> {
Msg.debug(this, "Resuming...");
TargetResumable<?> resumable = obj.get().as(TargetResumable.tclass);
TargetResumable resumable = obj.get().as(TargetResumable.class);
resumable.resume().handle(seq::next);
}).then(seq -> {
Msg.debug(this, "Waiting for session access (after resume)...");
access.get().waitValue(TargetAccessibility.ACCESSIBLE).handle(seq::next);
access.get().waitValue(true).handle(seq::next);
}).then(seq -> {
obj.get()
.fetchSubElements("Threads", "[0]", "Stack")
.thenCompose(DebugModelConventions::fetchAll)
.handle(seq::next);
obj.get().fetchSubElements("Threads", "[0]", "Stack").handle(seq::next);
}, DebuggerObjectModel.ELEMENT_MAP_TYPE).then((frames, seq) -> {
Msg.debug(this, "Got stack:");
for (Map.Entry<String, ? extends TargetObject> ent : frames.entrySet()) {
TargetStackFrame<?> frame = ent.getValue().as(TargetStackFrame.tclass);
TargetStackFrame frame = ent.getValue().as(TargetStackFrame.class);
Msg.debug(this, ent.getKey() + ": " + frame.getProgramCounter());
}
long offset = frames.get("0")
@ -904,10 +883,10 @@ public abstract class AbstractModelForDbgTest
AtomicReference<TargetObject> root = new AtomicReference<>();
AtomicReference<AllRequiredAccess> access = new AtomicReference<>();
AtomicReference<DbgModelTargetLauncher<?>> launcher = new AtomicReference<>();
AtomicReference<TargetLauncher> launcher = new AtomicReference<>();
AtomicReference<TargetObject> proc = new AtomicReference<>();
AtomicReference<TargetRegisterBank<?>> bank = new AtomicReference<>();
Set<TargetRegister<?>> descs = new LinkedHashSet<>();
AtomicReference<TargetRegisterBank> bank = new AtomicReference<>();
Set<TargetRegister> descs = new LinkedHashSet<>();
waitOn(AsyncUtils.sequence(TypeSpec.VOID).then(seq -> {
m.init().handle(seq::next);
@ -919,7 +898,7 @@ public abstract class AbstractModelForDbgTest
DebugModelConventions.trackAccessibility(root.get()).handle(seq::next);
}, access).then(seq -> {
Msg.debug(this, "Waiting for session access...");
access.get().waitValue(TargetAccessibility.ACCESSIBLE).handle(seq::next);
access.get().waitValue(true).handle(seq::next);
}).then(seq -> {
Msg.debug(this, "Finding TargetLauncher...");
DebugModelConventions.findSuitable(DbgModelTargetLauncher.class, root.get())
@ -927,10 +906,12 @@ public abstract class AbstractModelForDbgTest
seq::next);
}, launcher).then(seq -> {
Msg.debug(this, "Launching...");
launcher.get().launch("notepad", "junk.txt").handle(seq::nextIgnore);
launcher.get()
.launch(Map.of("args", List.of("notepad", "junk.txt")))
.handle(seq::nextIgnore);
}).then(seq -> {
Msg.debug(this, "Waiting for session access (again)...");
access.get().waitValue(TargetAccessibility.ACCESSIBLE).handle(seq::next);
access.get().waitValue(true).handle(seq::next);
}).then(seq -> {
Msg.debug(this, "Getting Process 1...");
model.fetchModelObject(List.of("Sessions", "[0]", "Processes", "[0]"))
@ -938,18 +919,17 @@ public abstract class AbstractModelForDbgTest
seq::next);
}, proc).then(seq -> {
proc.get().fetchSuccessor("Threads", "[0]", "Stack", "[0]").thenAccept(top -> {
bank.set(top.as(TargetRegisterBank.tclass));
bank.set(top.as(TargetRegisterBank.class));
}).handle(seq::next);
}).then(seq -> {
Msg.debug(this, "Got bank: " + bank.get());
Msg.debug(this, "Descriptions ref: " + bank.get().getDescriptions());
bank.get().getDescriptions().fetch().handle(seq::next);
}, TypeSpec.cls(TargetRegisterContainer.wclass)).then((cont, seq) -> {
TargetRegisterContainer cont = bank.get().getDescriptions();
Msg.debug(this, "Register descriptions: " + cont);
cont.getRegisters().thenAccept(descs::addAll).handle(seq::next);
}).then(seq -> {
Msg.debug(this, "Elements: ");
for (TargetRegister<?> reg : descs) {
for (TargetRegister reg : descs) {
Msg.debug(this, " " + reg.getIndex() + ": " + reg.getBitLength());
}
bank.get().readRegisters(descs).handle(seq::next);
@ -982,7 +962,7 @@ public abstract class AbstractModelForDbgTest
DebuggerObjectModel model = m.getModel();
AtomicReference<TargetObject> root = new AtomicReference<>();
AtomicReference<TargetFocusScope<?>> scope = new AtomicReference<>();
AtomicReference<TargetFocusScope> scope = new AtomicReference<>();
AtomicReference<AllRequiredAccess> access = new AtomicReference<>();
AtomicReference<TargetObject> processes = new AtomicReference<>();
AtomicReference<TargetObject> obj1 = new AtomicReference<>();
@ -993,13 +973,13 @@ public abstract class AbstractModelForDbgTest
TargetObjectListener procListener = new TargetObjectListener() {
@Override
public void elementsChanged(TargetObject parent, Collection<String> removed,
Map<String, ? extends TargetObjectRef> added) {
Map<String, ? extends TargetObject> added) {
processCount.set(processes.get().getCachedElements().size(), null);
}
};
TargetFocusScopeListener focusListener = new TargetFocusScopeListener() {
@Override
public void focusChanged(TargetFocusScope<?> object, TargetObjectRef focused) {
public void focusChanged(TargetFocusScope object, TargetObject focused) {
// Truncate the path to the parent process
focusProcPath.set(focused.getPath().subList(0, 2), null);
}
@ -1011,13 +991,13 @@ public abstract class AbstractModelForDbgTest
Msg.debug(this, "Getting session root object");
model.fetchModelObject("Sessions", "[0]").handle(seq::next);
}, root).then(seq -> {
scope.set(root.get().as(TargetFocusScope.tclass));
scope.set(root.get().as(TargetFocusScope.class));
scope.get().addListener(focusListener);
Msg.debug(this, "Tracking session access...");
DebugModelConventions.trackAccessibility(root.get()).handle(seq::next);
}, access).then(seq -> {
Msg.debug(this, "Waiting for session access...");
access.get().waitValue(TargetAccessibility.ACCESSIBLE).handle(seq::next);
access.get().waitValue(true).handle(seq::next);
}).then(seq -> {
Msg.debug(this, "Finding TargetLauncher...");
DebugModelConventions.findSuitable(DbgModelTargetLauncher.class, root.get())
@ -1025,12 +1005,8 @@ public abstract class AbstractModelForDbgTest
seq::next);
}, obj1).then(seq -> {
Msg.debug(this, "Attaching...");
TargetAttacher<?> attacher = obj1.get().as(TargetAttacher.tclass);
attacher.attach(
model.createRef("Sessions", "[0]", "Available", "[" + np.pid + "]")
.as(
TargetAttachable.tclass))
.handle(seq::nextIgnore);
TargetAttacher attacher = obj1.get().as(TargetAttacher.class);
attacher.attach(np.pid).handle(seq::nextIgnore);
}).then(seq -> {
Msg.debug(this, "Getting processes container");
model.fetchModelObject("Sessions", "[0]", "Processes").handle(seq::next);
@ -1042,12 +1018,12 @@ public abstract class AbstractModelForDbgTest
seq::next);
}, obj2).then(seq -> {
Msg.debug(this, "Creating another process");
TargetLauncher<?> launcher = obj2.get().as(TargetLauncher.tclass);
TargetLauncher launcher = obj2.get().as(TargetLauncher.class);
launcher.launch(Map.of(TargetCmdLineLauncher.CMDLINE_ARGS_NAME, "notepad junk.txt"))
.handle(seq::nextIgnore);
}).then(seq -> {
Msg.debug(this, "Waiting for session access (again)...");
access.get().waitValue(TargetAccessibility.ACCESSIBLE).handle(seq::next);
access.get().waitValue(true).handle(seq::next);
}).then(seq -> {
assertTrue(PathUtils.isAncestor(List.of("Sessions", "[0]", "Processes", "[1]"),
scope.get().getFocus().getPath()));
@ -1056,9 +1032,9 @@ public abstract class AbstractModelForDbgTest
Msg.debug(this, "Requesting focus on process 0");
AsyncFence fence = new AsyncFence();
TargetObjectRef i2 = model.createRef("Sessions", "[0]", "Processes", "[0]");
fence.include(focusProcPath.waitValue(i2.getPath()));
fence.include(scope.get().requestFocus(i2));
TargetObject p2 = model.getModelObject("Sessions", "[0]", "Processes", "[0]");
fence.include(focusProcPath.waitValue(p2.getPath()));
fence.include(scope.get().requestFocus(p2));
fence.ready().handle(seq::next);
}).then(seq -> {
assertTrue(PathUtils.isAncestor(List.of("Sessions", "[0]", "Processes", "[0]"),