diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/model/DefaultStackRecorder.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/model/DefaultStackRecorder.java index 7ba6ea8356..f9ad574dc1 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/model/DefaultStackRecorder.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/model/DefaultStackRecorder.java @@ -57,23 +57,7 @@ public class DefaultStackRecorder implements ManagedStackRecorder { @Override public void recordStack() { - long snap = recorder.getSnap(); - DebuggerMemoryMapper mm = recorder.getMemoryMapper(); - Map pcsByLevel; - synchronized (stack) { - pcsByLevel = stack.entrySet() - .stream() - .collect(Collectors.toMap(e -> e.getKey(), e -> { - return mm.targetToTrace(e.getValue().getProgramCounter()); - })); - } - recorder.parTx.execute("Stack changed", () -> { - TraceStack traceStack = stackManager.getStack(thread, snap, true); - traceStack.setDepth(stackDepth(), false); - for (Map.Entry ent : pcsByLevel.entrySet()) { - doRecordFrame(traceStack, ent.getKey(), ent.getValue()); - } - }, thread.getPath()); + doRecordStack(recorder.getSnap(), getPcsByLevel()); } public void popStack() { @@ -89,21 +73,35 @@ public class DefaultStackRecorder implements ManagedStackRecorder { traceFrame.setProgramCounter(null, pc); // Not object-based, so span=null } + protected Map getPcsByLevel() { + DebuggerMemoryMapper mm = recorder.getMemoryMapper(); + synchronized (stack) { + return stack.entrySet() + .stream() + .collect(Collectors.toMap(e -> e.getKey(), e -> { + return mm.targetToTrace(e.getValue().getProgramCounter()); + })); + } + } + + protected void doRecordStack(long snap, Map pcsByLevel) { + recorder.parTx.execute("Stack changed", () -> { + TraceStack traceStack = stackManager.getStack(thread, snap, true); + traceStack.setDepth(stackDepth(), false); + for (Map.Entry ent : pcsByLevel.entrySet()) { + doRecordFrame(traceStack, ent.getKey(), ent.getValue()); + } + }, thread.getPath()); + } + public void recordFrame(TargetStackFrame frame) { long snap = recorder.getSnap(); + Map pcsByLevel; synchronized (stack) { stack.put(getFrameLevel(frame), frame); + pcsByLevel = getPcsByLevel(); } - recorder.parTx.execute("Stack frame added", () -> { - DebuggerMemoryMapper memoryMapper = recorder.getMemoryMapper(); - if (memoryMapper == null) { - return; - } - Address pc = frame.getProgramCounter(); - Address tracePc = pc == null ? null : memoryMapper.targetToTrace(pc); - TraceStack traceStack = stackManager.getStack(thread, snap, true); - doRecordFrame(traceStack, getFrameLevel(frame), tracePc); - }, thread.getPath()); + doRecordStack(snap, pcsByLevel); } protected int stackDepth() { @@ -117,7 +115,7 @@ public class DefaultStackRecorder implements ManagedStackRecorder { for (TargetObject p = successor; p != null; p = p.getParent()) { if (p instanceof TargetStackFrame) { if (!PathUtils.isIndex(p.getPath())) { - throw new AssertionError("Invalid path index "+p.getPath()); + throw new AssertionError("Invalid path index " + p.getPath()); } int index = Integer.decode(p.getIndex()); TargetStackFrame frame;