mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-06 03:50:02 +02:00
Merge remote-tracking branch 'origin/GP-0_Dan_testFixes-20220802-1'
This commit is contained in:
commit
781c765e60
7 changed files with 83 additions and 35 deletions
|
@ -1060,6 +1060,11 @@ public class DebuggerLogicalBreakpointServicePlugin extends Plugin
|
||||||
changeListeners.remove(l);
|
changeListeners.remove(l);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CompletableFuture<Void> changesSettled() {
|
||||||
|
return CompletableFuture.supplyAsync(() -> null, executor);
|
||||||
|
}
|
||||||
|
|
||||||
protected MappedLogicalBreakpoint synthesizeLogicalBreakpoint(Program program, Address address,
|
protected MappedLogicalBreakpoint synthesizeLogicalBreakpoint(Program program, Address address,
|
||||||
long length, Collection<TraceBreakpointKind> kinds) {
|
long length, Collection<TraceBreakpointKind> kinds) {
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -18,6 +18,7 @@ package ghidra.app.plugin.core.debug.service.modules;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import org.apache.commons.lang3.ArrayUtils;
|
import org.apache.commons.lang3.ArrayUtils;
|
||||||
|
@ -596,6 +597,11 @@ public class DebuggerStaticMappingServicePlugin extends Plugin
|
||||||
changeListeners.remove(l);
|
changeListeners.remove(l);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CompletableFuture<Void> changesSettled() {
|
||||||
|
return changeDebouncer.settled();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void processEvent(PluginEvent event) {
|
public void processEvent(PluginEvent event) {
|
||||||
if (event instanceof ProgramOpenedPluginEvent) {
|
if (event instanceof ProgramOpenedPluginEvent) {
|
||||||
|
|
|
@ -147,6 +147,16 @@ public interface DebuggerLogicalBreakpointService {
|
||||||
*/
|
*/
|
||||||
void removeChangeListener(LogicalBreakpointsChangeListener l);
|
void removeChangeListener(LogicalBreakpointsChangeListener l);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a future which completes after pending changes have been processed
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* The returned future completes after all change listeners have been invoked
|
||||||
|
*
|
||||||
|
* @return the future
|
||||||
|
*/
|
||||||
|
CompletableFuture<Void> changesSettled();
|
||||||
|
|
||||||
static <T> T programOrTrace(ProgramLocation loc,
|
static <T> T programOrTrace(ProgramLocation loc,
|
||||||
BiFunction<? super Program, ? super Address, ? extends T> progFunc,
|
BiFunction<? super Program, ? super Address, ? extends T> progFunc,
|
||||||
BiFunction<? super Trace, ? super Address, ? extends T> traceFunc) {
|
BiFunction<? super Trace, ? super Address, ? extends T> traceFunc) {
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
package ghidra.app.services;
|
package ghidra.app.services;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
|
||||||
import com.google.common.collect.Range;
|
import com.google.common.collect.Range;
|
||||||
|
|
||||||
|
@ -400,6 +401,16 @@ public interface DebuggerStaticMappingService {
|
||||||
*/
|
*/
|
||||||
void removeChangeListener(DebuggerStaticMappingChangeListener l);
|
void removeChangeListener(DebuggerStaticMappingChangeListener l);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a future which completes when pending changes have all settled
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* The returned future completes after all change listeners have been invoked.
|
||||||
|
*
|
||||||
|
* @return the future
|
||||||
|
*/
|
||||||
|
CompletableFuture<Void> changesSettled();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Collect likely matches for destination programs for the given trace module
|
* Collect likely matches for destination programs for the given trace module
|
||||||
*
|
*
|
||||||
|
|
|
@ -20,6 +20,7 @@ import static org.junit.Assert.*;
|
||||||
import java.awt.event.MouseEvent;
|
import java.awt.event.MouseEvent;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
|
@ -63,12 +64,14 @@ public class DebuggerBreakpointsProviderTest extends AbstractGhidraHeadedDebugge
|
||||||
protected DebuggerBreakpointsPlugin breakpointsPlugin;
|
protected DebuggerBreakpointsPlugin breakpointsPlugin;
|
||||||
protected DebuggerBreakpointsProvider breakpointsProvider;
|
protected DebuggerBreakpointsProvider breakpointsProvider;
|
||||||
protected DebuggerStaticMappingService mappingService;
|
protected DebuggerStaticMappingService mappingService;
|
||||||
|
protected DebuggerLogicalBreakpointService breakpointService;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUpBreakpointsProviderTest() throws Exception {
|
public void setUpBreakpointsProviderTest() throws Exception {
|
||||||
breakpointsPlugin = addPlugin(tool, DebuggerBreakpointsPlugin.class);
|
breakpointsPlugin = addPlugin(tool, DebuggerBreakpointsPlugin.class);
|
||||||
breakpointsProvider = waitForComponentProvider(DebuggerBreakpointsProvider.class);
|
breakpointsProvider = waitForComponentProvider(DebuggerBreakpointsProvider.class);
|
||||||
mappingService = tool.getService(DebuggerStaticMappingService.class);
|
mappingService = tool.getService(DebuggerStaticMappingService.class);
|
||||||
|
breakpointService = tool.getService(DebuggerLogicalBreakpointService.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void waitAndFlush(TraceRecorder recorder) throws Throwable {
|
protected void waitAndFlush(TraceRecorder recorder) throws Throwable {
|
||||||
|
@ -538,7 +541,7 @@ public class DebuggerBreakpointsProviderTest extends AbstractGhidraHeadedDebugge
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testActionFilters() throws Exception {
|
public void testActionFilters() throws Throwable {
|
||||||
createTestModel();
|
createTestModel();
|
||||||
mb.createTestProcessesAndThreads();
|
mb.createTestProcessesAndThreads();
|
||||||
|
|
||||||
|
@ -561,14 +564,23 @@ public class DebuggerBreakpointsProviderTest extends AbstractGhidraHeadedDebugge
|
||||||
addLiveBreakpoint(recorder1, 0x55550321);
|
addLiveBreakpoint(recorder1, 0x55550321);
|
||||||
addLiveMemoryAndBreakpoint(mb.testProcess3, recorder3);
|
addLiveMemoryAndBreakpoint(mb.testProcess3, recorder3);
|
||||||
addLiveBreakpoint(recorder3, 0x55550321);
|
addLiveBreakpoint(recorder3, 0x55550321);
|
||||||
|
waitRecorder(recorder1);
|
||||||
|
waitRecorder(recorder3);
|
||||||
addStaticMemoryAndBreakpoint();
|
addStaticMemoryAndBreakpoint();
|
||||||
// Note, no program breakpoint for 0321...
|
// Note, no program breakpoint for 0321...
|
||||||
|
|
||||||
programManager.openProgram(program);
|
programManager.openProgram(program);
|
||||||
traceManager.openTrace(trace1);
|
traceManager.openTrace(trace1);
|
||||||
|
CompletableFuture<Void> mappingsSettled = mappingService.changesSettled();
|
||||||
|
CompletableFuture<Void> breakpointsSettled = breakpointService.changesSettled();
|
||||||
traceManager.openTrace(trace3);
|
traceManager.openTrace(trace3);
|
||||||
// Because mapping service debounces, wait for breakpoints to be reconciled
|
waitForSwing();
|
||||||
|
waitOn(mappingsSettled);
|
||||||
|
waitOn(breakpointsSettled);
|
||||||
|
waitForSwing();
|
||||||
|
|
||||||
LogicalBreakpointTableModel bptModel = breakpointsProvider.breakpointTableModel;
|
LogicalBreakpointTableModel bptModel = breakpointsProvider.breakpointTableModel;
|
||||||
waitForPass(() -> {
|
|
||||||
List<LogicalBreakpointRow> data = copyModelData(bptModel);
|
List<LogicalBreakpointRow> data = copyModelData(bptModel);
|
||||||
assertEquals(2, data.size());
|
assertEquals(2, data.size());
|
||||||
LogicalBreakpointRow row1 = data.get(0);
|
LogicalBreakpointRow row1 = data.get(0);
|
||||||
|
@ -590,13 +602,11 @@ public class DebuggerBreakpointsProviderTest extends AbstractGhidraHeadedDebugge
|
||||||
// OK, back to work
|
// OK, back to work
|
||||||
assertEquals(2, lb1.getTraceBreakpoints().size());
|
assertEquals(2, lb1.getTraceBreakpoints().size());
|
||||||
assertEquals(2, lb2.getTraceBreakpoints().size());
|
assertEquals(2, lb2.getTraceBreakpoints().size());
|
||||||
});
|
|
||||||
|
|
||||||
List<LogicalBreakpointRow> breakData = copyModelData(bptModel);
|
|
||||||
List<BreakpointLocationRow> filtLocs =
|
List<BreakpointLocationRow> filtLocs =
|
||||||
breakpointsProvider.locationFilterPanel.getTableFilterModel().getModelData();
|
breakpointsProvider.locationFilterPanel.getTableFilterModel().getModelData();
|
||||||
|
|
||||||
for (LogicalBreakpointRow breakRow : breakData) {
|
for (LogicalBreakpointRow breakRow : data) {
|
||||||
assertEquals(2, breakRow.getLocationCount());
|
assertEquals(2, breakRow.getLocationCount());
|
||||||
}
|
}
|
||||||
assertEquals(4, filtLocs.size());
|
assertEquals(4, filtLocs.size());
|
||||||
|
@ -605,9 +615,9 @@ public class DebuggerBreakpointsProviderTest extends AbstractGhidraHeadedDebugge
|
||||||
performAction(breakpointsProvider.actionFilterByCurrentTrace);
|
performAction(breakpointsProvider.actionFilterByCurrentTrace);
|
||||||
|
|
||||||
// No trace active, so empty :)
|
// No trace active, so empty :)
|
||||||
breakData = bptModel.getModelData();
|
data = copyModelData(bptModel);
|
||||||
filtLocs = breakpointsProvider.locationFilterPanel.getTableFilterModel().getModelData();
|
filtLocs = breakpointsProvider.locationFilterPanel.getTableFilterModel().getModelData();
|
||||||
for (LogicalBreakpointRow breakRow : breakData) {
|
for (LogicalBreakpointRow breakRow : data) {
|
||||||
assertEquals(0, breakRow.getLocationCount());
|
assertEquals(0, breakRow.getLocationCount());
|
||||||
}
|
}
|
||||||
assertEquals(0, filtLocs.size());
|
assertEquals(0, filtLocs.size());
|
||||||
|
@ -615,9 +625,9 @@ public class DebuggerBreakpointsProviderTest extends AbstractGhidraHeadedDebugge
|
||||||
traceManager.activateTrace(trace1);
|
traceManager.activateTrace(trace1);
|
||||||
waitForSwing();
|
waitForSwing();
|
||||||
|
|
||||||
breakData = bptModel.getModelData();
|
data = copyModelData(bptModel);
|
||||||
filtLocs = breakpointsProvider.locationFilterPanel.getTableFilterModel().getModelData();
|
filtLocs = breakpointsProvider.locationFilterPanel.getTableFilterModel().getModelData();
|
||||||
for (LogicalBreakpointRow breakRow : breakData) {
|
for (LogicalBreakpointRow breakRow : data) {
|
||||||
assertEquals(1, breakRow.getLocationCount());
|
assertEquals(1, breakRow.getLocationCount());
|
||||||
}
|
}
|
||||||
assertEquals(2, filtLocs.size());
|
assertEquals(2, filtLocs.size());
|
||||||
|
@ -626,14 +636,14 @@ public class DebuggerBreakpointsProviderTest extends AbstractGhidraHeadedDebugge
|
||||||
performAction(breakpointsProvider.actionFilterLocationsByBreakpoints);
|
performAction(breakpointsProvider.actionFilterLocationsByBreakpoints);
|
||||||
|
|
||||||
// No breakpoint selected, so no change, yet.
|
// No breakpoint selected, so no change, yet.
|
||||||
breakData = bptModel.getModelData();
|
data = copyModelData(bptModel);
|
||||||
filtLocs = breakpointsProvider.locationFilterPanel.getTableFilterModel().getModelData();
|
filtLocs = breakpointsProvider.locationFilterPanel.getTableFilterModel().getModelData();
|
||||||
for (LogicalBreakpointRow breakRow : breakData) {
|
for (LogicalBreakpointRow breakRow : data) {
|
||||||
assertEquals(1, breakRow.getLocationCount());
|
assertEquals(1, breakRow.getLocationCount());
|
||||||
}
|
}
|
||||||
assertEquals(2, filtLocs.size());
|
assertEquals(2, filtLocs.size());
|
||||||
|
|
||||||
breakpointsProvider.setSelectedBreakpoints(Set.of(breakData.get(0).getLogicalBreakpoint()));
|
breakpointsProvider.setSelectedBreakpoints(Set.of(data.get(0).getLogicalBreakpoint()));
|
||||||
waitForSwing();
|
waitForSwing();
|
||||||
|
|
||||||
filtLocs = breakpointsProvider.locationFilterPanel.getTableFilterModel().getModelData();
|
filtLocs = breakpointsProvider.locationFilterPanel.getTableFilterModel().getModelData();
|
||||||
|
@ -642,9 +652,9 @@ public class DebuggerBreakpointsProviderTest extends AbstractGhidraHeadedDebugge
|
||||||
assertTrue(breakpointsProvider.actionFilterByCurrentTrace.isEnabled());
|
assertTrue(breakpointsProvider.actionFilterByCurrentTrace.isEnabled());
|
||||||
performAction(breakpointsProvider.actionFilterByCurrentTrace);
|
performAction(breakpointsProvider.actionFilterByCurrentTrace);
|
||||||
|
|
||||||
breakData = bptModel.getModelData();
|
data = copyModelData(bptModel);
|
||||||
filtLocs = breakpointsProvider.locationFilterPanel.getTableFilterModel().getModelData();
|
filtLocs = breakpointsProvider.locationFilterPanel.getTableFilterModel().getModelData();
|
||||||
for (LogicalBreakpointRow breakRow : breakData) {
|
for (LogicalBreakpointRow breakRow : data) {
|
||||||
assertEquals(2, breakRow.getLocationCount());
|
assertEquals(2, breakRow.getLocationCount());
|
||||||
}
|
}
|
||||||
assertEquals(2, filtLocs.size());
|
assertEquals(2, filtLocs.size());
|
||||||
|
|
|
@ -547,16 +547,19 @@ public class DebuggerModelProviderTest extends AbstractGhidraHeadedDebuggerGUITe
|
||||||
modelProvider.setPath(TraceObjectKeyPath.parse("Processes[0].Threads[2]"));
|
modelProvider.setPath(TraceObjectKeyPath.parse("Processes[0].Threads[2]"));
|
||||||
waitForSwing();
|
waitForSwing();
|
||||||
|
|
||||||
AbstractNode nodeThread2 = modelProvider.objectsTreePanel.getSelectedItem();
|
AbstractNode nodeThread2 =
|
||||||
|
waitForValue(() -> modelProvider.objectsTreePanel.getSelectedItem());
|
||||||
assertEquals(1, nodeThread2.getChildren().size());
|
assertEquals(1, nodeThread2.getChildren().size());
|
||||||
|
|
||||||
performAction(modelProvider.actionShowPrimitivesInTree, modelProvider, true);
|
performAction(modelProvider.actionShowPrimitivesInTree, modelProvider, true);
|
||||||
assertTrue(modelProvider.isShowPrimitivesInTree());
|
assertTrue(modelProvider.isShowPrimitivesInTree());
|
||||||
|
nodeThread2 = waitForValue(() -> modelProvider.objectsTreePanel.getSelectedItem());
|
||||||
assertEquals(3, nodeThread2.getChildren().size());
|
assertEquals(3, nodeThread2.getChildren().size());
|
||||||
assertEquals(nodeThread2, modelProvider.objectsTreePanel.getSelectedItem());
|
assertEquals(nodeThread2, modelProvider.objectsTreePanel.getSelectedItem());
|
||||||
|
|
||||||
performAction(modelProvider.actionShowPrimitivesInTree, modelProvider, true);
|
performAction(modelProvider.actionShowPrimitivesInTree, modelProvider, true);
|
||||||
assertFalse(modelProvider.isShowPrimitivesInTree());
|
assertFalse(modelProvider.isShowPrimitivesInTree());
|
||||||
|
nodeThread2 = waitForValue(() -> modelProvider.objectsTreePanel.getSelectedItem());
|
||||||
assertEquals(1, nodeThread2.getChildren().size());
|
assertEquals(1, nodeThread2.getChildren().size());
|
||||||
assertEquals(nodeThread2, modelProvider.objectsTreePanel.getSelectedItem());
|
assertEquals(nodeThread2, modelProvider.objectsTreePanel.getSelectedItem());
|
||||||
}
|
}
|
||||||
|
|
|
@ -112,6 +112,9 @@ public class AsyncDebouncer<T> {
|
||||||
/**
|
/**
|
||||||
* Receive the next settled event
|
* Receive the next settled event
|
||||||
*
|
*
|
||||||
|
* <p>
|
||||||
|
* The returned future completes <em>after</em> all registered listeners have been invoked.
|
||||||
|
*
|
||||||
* @return a future which completes with the value of the next settled event.
|
* @return a future which completes with the value of the next settled event.
|
||||||
*/
|
*/
|
||||||
public synchronized CompletableFuture<T> settled() {
|
public synchronized CompletableFuture<T> settled() {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue