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 cc8c0a62f3..7d4ea2cf88 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 @@ -16,6 +16,7 @@ package ghidra.app.plugin.core.debug.service.model; import java.util.*; +import java.util.stream.Collectors; import ghidra.app.plugin.core.debug.mapping.DebuggerMemoryMapper; import ghidra.app.plugin.core.debug.service.model.interfaces.ManagedStackRecorder; @@ -57,13 +58,17 @@ public class DefaultStackRecorder implements ManagedStackRecorder { @Override public void recordStack() { long snap = recorder.getSnap(); + Map pcsByLevel = stack.entrySet() + .stream() + .collect(Collectors.toMap(e -> e.getKey(), e -> { + return recorder.getMemoryMapper() + .targetToTrace(e.getValue().getProgramCounter()); + })); recorder.parTx.execute("Stack changed", () -> { TraceStack traceStack = stackManager.getStack(thread, snap, true); traceStack.setDepth(stackDepth(), false); - for (Map.Entry ent : stack.entrySet()) { - Address tracePc = - recorder.getMemoryMapper().targetToTrace(ent.getValue().getProgramCounter()); - doRecordFrame(traceStack, ent.getKey(), tracePc); + for (Map.Entry ent : pcsByLevel.entrySet()) { + doRecordFrame(traceStack, ent.getKey(), ent.getValue()); } }, thread.getPath()); } @@ -82,6 +87,7 @@ public class DefaultStackRecorder implements ManagedStackRecorder { } public void recordFrame(TargetStackFrame frame) { + long snap = recorder.getSnap(); stack.put(getFrameLevel(frame), frame); recorder.parTx.execute("Stack frame added", () -> { DebuggerMemoryMapper memoryMapper = recorder.getMemoryMapper(); @@ -90,7 +96,7 @@ public class DefaultStackRecorder implements ManagedStackRecorder { } Address pc = frame.getProgramCounter(); Address tracePc = pc == null ? null : memoryMapper.targetToTrace(pc); - TraceStack traceStack = stackManager.getStack(thread, recorder.getSnap(), true); + TraceStack traceStack = stackManager.getStack(thread, snap, true); doRecordFrame(traceStack, getFrameLevel(frame), tracePc); }, thread.getPath()); } diff --git a/Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/trace/database/stack/DBTraceStack.java b/Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/trace/database/stack/DBTraceStack.java index fd5a9afabf..900f30cdca 100644 --- a/Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/trace/database/stack/DBTraceStack.java +++ b/Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/trace/database/stack/DBTraceStack.java @@ -99,7 +99,10 @@ public class DBTraceStack extends DBAnnotatedObject implements TraceStack { } } - @DBAnnotatedField(column = THREAD_SNAP_COLUMN_NAME, indexed = true, codec = ThreadSnapDBFieldCodec.class) + @DBAnnotatedField( + column = THREAD_SNAP_COLUMN_NAME, + indexed = true, + codec = ThreadSnapDBFieldCodec.class) private ThreadSnap threadSnap; @DBAnnotatedField(column = FRAMES_COLUMN_NAME) private long[] frameKeys; @@ -109,7 +112,8 @@ public class DBTraceStack extends DBAnnotatedObject implements TraceStack { private DBTraceThread thread; private final List frames = new ArrayList<>(); - public DBTraceStack(DBTraceStackManager manager, DBCachedObjectStore store, DBRecord record) { + public DBTraceStack(DBTraceStackManager manager, DBCachedObjectStore store, + DBRecord record) { super(store, record); this.manager = manager; } @@ -170,6 +174,8 @@ public class DBTraceStack extends DBAnnotatedObject implements TraceStack { @Override public void setDepth(int depth, boolean atInner) { + //System.err.println("setDepth(threadKey=" + thread.getKey() + "snap=" + getSnap() + + // ",depth=" + depth + ",inner=" + atInner + ");"); int curDepth = frameKeys == null ? 0 : frameKeys.length; if (depth == curDepth) { return; diff --git a/Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/trace/database/stack/DBTraceStackFrame.java b/Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/trace/database/stack/DBTraceStackFrame.java index 75eb549233..6dcbc13706 100644 --- a/Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/trace/database/stack/DBTraceStackFrame.java +++ b/Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/trace/database/stack/DBTraceStackFrame.java @@ -103,6 +103,8 @@ public class DBTraceStackFrame extends DBAnnotatedObject @Override public void setProgramCounter(Address pc) { + //System.err.println("setPC(threadKey=" + stack.getThread().getKey() + ",snap=" + + // stack.getSnap() + ",level=" + level + ",pc=" + pc + ");"); manager.trace.assertValidAddress(pc); try (LockHold hold = LockHold.lock(manager.lock.writeLock())) { if (Objects.equals(this.pc, pc)) {