diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/model/ObjectTreeModel.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/model/ObjectTreeModel.java index cc8b0e6e65..b68a1b9a31 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/model/ObjectTreeModel.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/model/ObjectTreeModel.java @@ -26,6 +26,7 @@ import docking.widgets.tree.GTreeLazyNode; import docking.widgets.tree.GTreeNode; import ghidra.app.plugin.core.debug.gui.DebuggerResources; import ghidra.dbg.target.*; +import ghidra.framework.model.DomainObjectClosedListener; import ghidra.trace.database.DBTraceUtils; import ghidra.trace.model.Trace; import ghidra.trace.model.Trace.TraceObjectChangeType; @@ -37,7 +38,8 @@ import utilities.util.IDKeyed; public class ObjectTreeModel implements DisplaysModified { - class ListenerForChanges extends TraceDomainObjectListener { + class ListenerForChanges extends TraceDomainObjectListener + implements DomainObjectClosedListener { public ListenerForChanges() { listenFor(TraceObjectChangeType.CREATED, this::objectCreated); listenFor(TraceObjectChangeType.VALUE_CREATED, this::valueCreated); @@ -45,6 +47,11 @@ public class ObjectTreeModel implements DisplaysModified { listenFor(TraceObjectChangeType.VALUE_LIFESPAN_CHANGED, this::valueLifespanChanged); } + @Override + public void domainObjectClosed() { + setTrace(null); + } + protected boolean isEventValue(TraceObjectValue value) { if (!value.getParent() .getTargetSchema() @@ -174,6 +181,11 @@ public class ObjectTreeModel implements DisplaysModified { } return byObject.get(new IDKeyed<>(object)); } + + public void invalidate() { + byObject.clear(); + byValue.clear(); + } } public abstract class AbstractNode extends GTreeLazyNode { @@ -600,12 +612,14 @@ public class ObjectTreeModel implements DisplaysModified { protected void removeOldListeners() { if (trace != null) { trace.removeListener(listenerForChanges); + trace.removeCloseListener(listenerForChanges); } } protected void addNewListeners() { if (trace != null) { trace.addListener(listenerForChanges); + trace.addCloseListener(listenerForChanges); } } @@ -616,6 +630,7 @@ public class ObjectTreeModel implements DisplaysModified { } protected void reload() { + nodeCache.invalidate(); root.unloadChildren(); } diff --git a/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/modules/DebuggerModulesProviderTest.java b/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/modules/DebuggerModulesProviderTest.java index 6beddac12a..d89753aa5a 100644 --- a/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/modules/DebuggerModulesProviderTest.java +++ b/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/modules/DebuggerModulesProviderTest.java @@ -232,7 +232,7 @@ public class DebuggerModulesProviderTest extends AbstractGhidraHeadedDebuggerGUI waitForDomainObject(program); waitForPass(() -> assertEquals(4, modulesProvider.sectionTable.getRowCount())); - modulesProvider.setSelectedSections(Set.of(secExeText)); + runSwing(() -> modulesProvider.setSelectedSections(Set.of(secExeText))); performAction(modulesProvider.actionMapSections, false); DebuggerSectionMapProposalDialog propDialog =