diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/time/DebuggerSnapshotTablePanel.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/time/DebuggerSnapshotTablePanel.java index 5676a31630..0cec92c03c 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/time/DebuggerSnapshotTablePanel.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/time/DebuggerSnapshotTablePanel.java @@ -228,16 +228,15 @@ public class DebuggerSnapshotTablePanel extends JPanel { } TraceSnapshot snapshot = row.getSnapshot(); - if (snapshot.getSchedule().isSnapOnly() || - snapshot.getVersion() >= current.getTrace().getEmulatorCacheVersion()) { + if (snapshot.isStale(true)) { + setForeground( + data.isSelected() ? COLOR_FOREGROUND_STALE_SEL : COLOR_FOREGROUND_STALE); + } + else { JTable table = data.getTable(); setForeground( data.isSelected() ? table.getSelectionForeground() : table.getForeground()); } - else { - setForeground( - data.isSelected() ? COLOR_FOREGROUND_STALE_SEL : COLOR_FOREGROUND_STALE); - } return this; } diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/emulation/DebuggerEmulationServicePlugin.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/emulation/DebuggerEmulationServicePlugin.java index 196a53d905..98c5f667cc 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/emulation/DebuggerEmulationServicePlugin.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/emulation/DebuggerEmulationServicePlugin.java @@ -688,7 +688,7 @@ public class DebuggerEmulationServicePlugin extends Plugin implements DebuggerEm TraceSchedule time = key.time; TraceSnapshot tracePrefix = trace.getTimeManager().findSnapshotWithNearestPrefix(time); - if (tracePrefix.getSchedule().isSnapOnly()) { + if (tracePrefix != null && tracePrefix.isSnapOnly(true)) { tracePrefix = null; } Map.Entry cachePrefix = findNearestPrefix(key); diff --git a/Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/trace/database/time/DBTraceSnapshot.java b/Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/trace/database/time/DBTraceSnapshot.java index 809e5cbfda..290087089b 100644 --- a/Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/trace/database/time/DBTraceSnapshot.java +++ b/Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/trace/database/time/DBTraceSnapshot.java @@ -227,6 +227,28 @@ public class DBTraceSnapshot extends DBAnnotatedObject implements TraceSnapshot } } + @Override + public boolean isSnapOnly(boolean whenInconsistent) { + if (schedule == null && key < 0) { + return whenInconsistent; + } + return schedule == null || schedule.isSnapOnly(); + } + + @Override + public boolean isStale(boolean whenInconsistent) { + if (schedule == null) { + if (key < 0) { + return whenInconsistent; + } + return false; // A recorded snapshot + } + if (schedule.isSnapOnly()) { + return false; + } + return version < manager.trace.getEmulatorCacheVersion(); + } + @Override public void delete() { manager.deleteSnapshot(this); diff --git a/Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/trace/model/time/TraceSnapshot.java b/Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/trace/model/time/TraceSnapshot.java index 5befec010f..d691d4ed06 100644 --- a/Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/trace/model/time/TraceSnapshot.java +++ b/Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/trace/model/time/TraceSnapshot.java @@ -4,9 +4,9 @@ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -43,7 +43,7 @@ public interface TraceSnapshot { /** * Get the description of the snapshot * - * @return + * @return the description */ String getDescription(); @@ -131,6 +131,34 @@ public interface TraceSnapshot { */ void setVersion(long version); + /** + * Check if a snapshot involves any steps of emulation + *

+ * A scratch snapshot, i.e., whose key is negative, without a schedule set is considered + * inconsistent. + * + * @param whenInconsistent the value to return for a scratch snapshot without a set schedule + * @return true if no emulation is involved + */ + boolean isSnapOnly(boolean whenInconsistent); + + /** + * For an emulated snapshot, check if re-emulation is necessary to produce an up-to-date + * snapshot. + *

+ * For non-emulated snapshots, this always returns false. A non-emulated snapshot is a snapshot + * whose schedule includes no emulation steps. An emulation snapshot is stale when its version + * is less than the trace's emulator cache version. A scratch snapshot, i.e., whose key is + * negative, without a schedule set is considered inconsistent. + * + * @param whenInconsistent the value to return for a scratch snapshot without a set schedule + * @return true if re-emulation is needed + * @see #getVersion() + * @see #setVersion(long) + * @see Trace#getEmulatorCacheVersion() + */ + boolean isStale(boolean whenInconsistent); + /** * Delete this snapshot *