diff --git a/Ghidra/Debug/Debugger-agent-dbgeng/src/main/java/agent/dbgeng/model/impl/DbgModelImpl.java b/Ghidra/Debug/Debugger-agent-dbgeng/src/main/java/agent/dbgeng/model/impl/DbgModelImpl.java index f0e5c5f63d..2e72334ef2 100644 --- a/Ghidra/Debug/Debugger-agent-dbgeng/src/main/java/agent/dbgeng/model/impl/DbgModelImpl.java +++ b/Ghidra/Debug/Debugger-agent-dbgeng/src/main/java/agent/dbgeng/model/impl/DbgModelImpl.java @@ -110,7 +110,7 @@ public class DbgModelImpl extends AbstractDbgModel implements DebuggerObjectMode @Override public void terminate() throws IOException { - listeners.invoke().modelClosed(DebuggerModelClosedReason.NORMAL); + broadcast().modelClosed(DebuggerModelClosedReason.NORMAL); root.invalidateSubtree(root, "Dbgeng is terminating"); dbg.terminate(); } diff --git a/Ghidra/Debug/Debugger-agent-dbgmodel/src/main/java/agent/dbgmodel/model/impl/DbgModel2Impl.java b/Ghidra/Debug/Debugger-agent-dbgmodel/src/main/java/agent/dbgmodel/model/impl/DbgModel2Impl.java index ab1363e515..add4f98515 100644 --- a/Ghidra/Debug/Debugger-agent-dbgmodel/src/main/java/agent/dbgmodel/model/impl/DbgModel2Impl.java +++ b/Ghidra/Debug/Debugger-agent-dbgmodel/src/main/java/agent/dbgmodel/model/impl/DbgModel2Impl.java @@ -121,7 +121,7 @@ public class DbgModel2Impl extends AbstractDbgModel @Override public void terminate() throws IOException { - listeners.invoke().modelClosed(DebuggerModelClosedReason.NORMAL); + broadcast().modelClosed(DebuggerModelClosedReason.NORMAL); root.invalidateSubtree(root, "Dbgmodel is terminating"); dbg.terminate(); } diff --git a/Ghidra/Debug/Debugger-agent-frida/src/main/java/agent/frida/model/impl/FridaModelImpl.java b/Ghidra/Debug/Debugger-agent-frida/src/main/java/agent/frida/model/impl/FridaModelImpl.java index 988f88d999..0068898b81 100644 --- a/Ghidra/Debug/Debugger-agent-frida/src/main/java/agent/frida/model/impl/FridaModelImpl.java +++ b/Ghidra/Debug/Debugger-agent-frida/src/main/java/agent/frida/model/impl/FridaModelImpl.java @@ -98,7 +98,7 @@ public class FridaModelImpl extends AbstractFridaModel implements DebuggerObject @Override public void terminate() throws IOException { - listeners.invoke().modelClosed(DebuggerModelClosedReason.NORMAL); + broadcast().modelClosed(DebuggerModelClosedReason.NORMAL); root.invalidateSubtree(root, "Frida is terminating"); manager.terminate(); } diff --git a/Ghidra/Debug/Debugger-agent-gdb/src/main/java/agent/gdb/model/impl/GdbModelImpl.java b/Ghidra/Debug/Debugger-agent-gdb/src/main/java/agent/gdb/model/impl/GdbModelImpl.java index c94eb64299..1e371fd4e5 100644 --- a/Ghidra/Debug/Debugger-agent-gdb/src/main/java/agent/gdb/model/impl/GdbModelImpl.java +++ b/Ghidra/Debug/Debugger-agent-gdb/src/main/java/agent/gdb/model/impl/GdbModelImpl.java @@ -167,7 +167,7 @@ public class GdbModelImpl extends AbstractDebuggerObjectModel { } public void terminate() throws IOException { - listeners.invoke().modelClosed(DebuggerModelClosedReason.NORMAL); + broadcast().modelClosed(DebuggerModelClosedReason.NORMAL); session.invalidateSubtree(session, "GDB is terminating"); gdb.terminate(); } diff --git a/Ghidra/Debug/Debugger-agent-lldb/src/main/java/agent/lldb/model/impl/LldbModelImpl.java b/Ghidra/Debug/Debugger-agent-lldb/src/main/java/agent/lldb/model/impl/LldbModelImpl.java index 4f9120a1e5..0e845d11a7 100644 --- a/Ghidra/Debug/Debugger-agent-lldb/src/main/java/agent/lldb/model/impl/LldbModelImpl.java +++ b/Ghidra/Debug/Debugger-agent-lldb/src/main/java/agent/lldb/model/impl/LldbModelImpl.java @@ -110,7 +110,7 @@ public class LldbModelImpl extends AbstractLldbModel implements DebuggerObjectMo @Override public void terminate() throws IOException { - listeners.invoke().modelClosed(DebuggerModelClosedReason.NORMAL); + broadcast().modelClosed(DebuggerModelClosedReason.NORMAL); root.invalidateSubtree(root, "LLDB is terminating"); manager.terminate(); } diff --git a/Ghidra/Debug/Debugger-gadp/src/main/java/ghidra/dbg/gadp/client/GadpClient.java b/Ghidra/Debug/Debugger-gadp/src/main/java/ghidra/dbg/gadp/client/GadpClient.java index 7e281d9d83..1e1e7c7b25 100644 --- a/Ghidra/Debug/Debugger-gadp/src/main/java/ghidra/dbg/gadp/client/GadpClient.java +++ b/Ghidra/Debug/Debugger-gadp/src/main/java/ghidra/dbg/gadp/client/GadpClient.java @@ -323,10 +323,10 @@ public class GadpClient extends AbstractDebuggerObjectModel protected void channelStateChanged(ChannelState old, ChannelState set, DebuggerModelClosedReason reason) { if (old == ChannelState.NEGOTIATING && set == ChannelState.ACTIVE) { - listeners.invoke().modelOpened(); + broadcast().modelOpened(); } else if (old == ChannelState.ACTIVE && set == ChannelState.CLOSED) { - listeners.invoke().modelClosed(reason); + broadcast().modelClosed(reason); root.invalidateSubtree(root, "GADP Client disconnected"); messageMatcher.flush(new DebuggerModelTerminatingException("GADP Client disconnected")); } diff --git a/Ghidra/Debug/Framework-Debugging/src/main/java/ghidra/dbg/agent/AbstractDebuggerObjectModel.java b/Ghidra/Debug/Framework-Debugging/src/main/java/ghidra/dbg/agent/AbstractDebuggerObjectModel.java index 3b3d7d6856..12d687ec7d 100644 --- a/Ghidra/Debug/Framework-Debugging/src/main/java/ghidra/dbg/agent/AbstractDebuggerObjectModel.java +++ b/Ghidra/Debug/Framework-Debugging/src/main/java/ghidra/dbg/agent/AbstractDebuggerObjectModel.java @@ -28,6 +28,7 @@ import ghidra.dbg.target.TargetObject; import ghidra.dbg.util.PathUtils; import ghidra.util.Msg; import ghidra.util.datastruct.ListenerSet; +import ghidra.util.datastruct.PrivatelyQueuedListener; public abstract class AbstractDebuggerObjectModel implements SpiDebuggerObjectModel { public final Object lock = new Object(); @@ -39,6 +40,10 @@ public abstract class AbstractDebuggerObjectModel implements SpiDebuggerObjectMo protected final ListenerSet listeners = new ListenerSet<>(DebuggerModelListener.class, true); + protected final PrivatelyQueuedListener asyncListeners = + new PrivatelyQueuedListener(DebuggerModelListener.class, + clientExecutor, listeners.invoke()); + protected SpiTargetObject root; protected boolean rootAdded; protected boolean cbRootAdded; @@ -99,9 +104,8 @@ public abstract class AbstractDebuggerObjectModel implements SpiDebuggerObjectMo }); this.completedRoot.completeAsync(() -> root, clientExecutor); - clientExecutor.execute(() -> { - listeners.invoke().rootAdded(root); - }); + // broadcast is privately queued on clientExecutor + broadcast().rootAdded(root); } } @@ -201,6 +205,10 @@ public abstract class AbstractDebuggerObjectModel implements SpiDebuggerObjectMo listeners.remove(listener); } + protected DebuggerModelListener broadcast() { + return asyncListeners.in; + } + /** * Ensure that dependent computations occur on the client executor * diff --git a/Ghidra/Debug/Framework-Debugging/src/main/java/ghidra/dbg/agent/AbstractTargetObject.java b/Ghidra/Debug/Framework-Debugging/src/main/java/ghidra/dbg/agent/AbstractTargetObject.java index b315bb1d4d..ed08b9802a 100644 --- a/Ghidra/Debug/Framework-Debugging/src/main/java/ghidra/dbg/agent/AbstractTargetObject.java +++ b/Ghidra/Debug/Framework-Debugging/src/main/java/ghidra/dbg/agent/AbstractTargetObject.java @@ -304,6 +304,6 @@ public abstract class AbstractTargetObject

implements Sp @Override public DebuggerModelListener broadcast() { - return model.listeners.invoke(); + return model.broadcast(); } } diff --git a/Ghidra/Debug/Framework-Debugging/src/test/java/ghidra/dbg/model/TestDebuggerObjectModel.java b/Ghidra/Debug/Framework-Debugging/src/test/java/ghidra/dbg/model/TestDebuggerObjectModel.java index bf5ac32e17..a2e82d98da 100644 --- a/Ghidra/Debug/Framework-Debugging/src/test/java/ghidra/dbg/model/TestDebuggerObjectModel.java +++ b/Ghidra/Debug/Framework-Debugging/src/test/java/ghidra/dbg/model/TestDebuggerObjectModel.java @@ -263,6 +263,6 @@ public class TestDebuggerObjectModel extends EmptyDebuggerObjectModel { } public DebuggerModelListener fire() { - return listeners.invoke(); + return broadcast(); } }