Skip to content

Commit 2d3f68c

Browse files
committed
Merge remote-tracking branch 'origin/patch'
Conflicts: Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/trace/database/memory/DBTraceMemorySpace.java
2 parents e4dde8c + bb30c21 commit 2d3f68c

File tree

5 files changed

+67
-24
lines changed

5 files changed

+67
-24
lines changed

Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/breakpoint/DebuggerBreakpointMarkerPlugin.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -969,7 +969,7 @@ protected void doToggleBreakpointsAt(String title, ActionContext context) {
969969
*/
970970
Trace trace = getTraceFromContext(context);
971971
boolean mapped = breakpointService.anyMapped(bs, trace);
972-
Enablement toggled = en.getToggled(mapped);
972+
Enablement toggled = en.getToggled(mapped && trace == null);
973973
if (toggled.enabled) {
974974
breakpointService.enableAll(bs, trace).exceptionally(ex -> {
975975
breakpointError(title, "Could not enable breakpoints", ex);

Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/pcode/DebuggerPcodeStepperProvider.java

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616
package ghidra.app.plugin.core.debug.gui.pcode;
1717

1818
import java.awt.*;
19+
import java.awt.font.FontRenderContext;
20+
import java.awt.geom.AffineTransform;
1921
import java.math.BigInteger;
2022
import java.util.*;
2123
import java.util.List;
@@ -65,6 +67,8 @@
6567
import ghidra.util.table.column.AbstractGColumnRenderer;
6668

6769
public class DebuggerPcodeStepperProvider extends ComponentProviderAdapter {
70+
private static final FontRenderContext METRIC_FRC =
71+
new FontRenderContext(new AffineTransform(), false, false);
6872
private static final String BACKGROUND_COLOR = "Background Color";
6973
private static final String ADDRESS_COLOR = "Address Color";
7074
private static final String CONSTANT_COLOR = "Constant Color";
@@ -458,6 +462,12 @@ protected void recomputeStyle() {
458462
pcodeTableModel.fireTableDataChanged();
459463
}
460464

465+
protected int computeSeqColWidth(JLabel renderer) {
466+
Font font = renderer.getFont();
467+
Insets insets = renderer.getBorder().getBorderInsets(renderer);
468+
return (int) font.getStringBounds("00", METRIC_FRC).getWidth() + insets.left + insets.right;
469+
}
470+
461471
protected void buildMainPanel() {
462472
JPanel pcodePanel = new JPanel(new BorderLayout());
463473
pcodeTable = new GhidraTable(pcodeTableModel);
@@ -486,9 +496,11 @@ protected void buildMainPanel() {
486496

487497
TableColumnModel pcodeColModel = pcodeTable.getColumnModel();
488498
TableColumn seqCol = pcodeColModel.getColumn(PcodeTableColumns.SEQUENCE.ordinal());
489-
seqCol.setCellRenderer(new CounterBackgroundCellRenderer());
490-
seqCol.setMinWidth(24);
491-
seqCol.setMaxWidth(24);
499+
CounterBackgroundCellRenderer seqColRenderer = new CounterBackgroundCellRenderer();
500+
seqCol.setCellRenderer(seqColRenderer);
501+
int seqColWidth = computeSeqColWidth(seqColRenderer);
502+
seqCol.setMinWidth(seqColWidth);
503+
seqCol.setMaxWidth(seqColWidth);
492504
TableColumn codeCol = pcodeColModel.getColumn(PcodeTableColumns.CODE.ordinal());
493505
codeCol.setCellRenderer(new PcodeCellRenderer());
494506
//codeCol.setPreferredWidth(75);

Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/breakpoint/DebuggerBreakpointMarkerPluginTest.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -499,6 +499,20 @@ public void testActionToggleBreakpointTrace() throws Exception {
499499
dynamicCtx(trace, addr(trace, 0x55550123)), true);
500500

501501
waitForPass(() -> assertEquals(Enablement.ENABLED, lb.computeEnablementForTrace(trace)));
502+
503+
lb.disable();
504+
waitForPass(() -> assertEquals(Enablement.DISABLED, lb.computeEnablementForTrace(trace)));
505+
506+
performAction(breakpointMarkerPlugin.actionToggleBreakpoint,
507+
dynamicCtx(trace, addr(trace, 0x55550123)), true);
508+
509+
waitForPass(
510+
() -> assertEquals(Enablement.ENABLED_DISABLED, lb.computeEnablementForTrace(trace)));
511+
512+
performAction(breakpointMarkerPlugin.actionToggleBreakpoint,
513+
dynamicCtx(trace, addr(trace, 0x55550123)), true);
514+
515+
waitForPass(() -> assertEquals(Enablement.DISABLED, lb.computeEnablementForTrace(trace)));
502516
}
503517

504518
protected void testActionSetBreakpointProgram(DockingAction action,

Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/trace/database/memory/DBTraceMemorySpace.java

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,8 @@
4444
import ghidra.trace.model.Trace.*;
4545
import ghidra.trace.model.memory.*;
4646
import ghidra.trace.model.thread.TraceThread;
47+
import ghidra.trace.util.DefaultTraceTimeViewport;
4748
import ghidra.trace.util.TraceChangeRecord;
48-
import ghidra.trace.util.TraceViewportSpanIterator;
4949
import ghidra.util.*;
5050
import ghidra.util.AddressIteratorAdapter;
5151
import ghidra.util.database.*;
@@ -93,6 +93,8 @@ public class DBTraceMemorySpace implements Unfinished, TraceMemorySpace, DBTrace
9393
.build()
9494
.asMap();
9595

96+
protected final DefaultTraceTimeViewport viewport;
97+
9698
public DBTraceMemorySpace(DBTraceMemoryManager manager, DBHandle dbh, AddressSpace space,
9799
DBTraceSpaceEntry ent) throws IOException, VersionException {
98100
this.manager = manager;
@@ -127,6 +129,8 @@ public DBTraceMemorySpace(DBTraceMemoryManager manager, DBHandle dbh, AddressSpa
127129
true);
128130
this.blocksByOffset =
129131
blockStore.getIndex(OffsetSnap.class, DBTraceMemoryBlockEntry.LOCATION_COLUMN);
132+
133+
this.viewport = new DefaultTraceTimeViewport(trace);
130134
}
131135

132136
private void regionCacheEntryRemoved(
@@ -375,9 +379,7 @@ public TraceMemoryState getState(long snap, Address address) {
375379

376380
@Override
377381
public Entry<Long, TraceMemoryState> getViewState(long snap, Address address) {
378-
TraceViewportSpanIterator spit = new TraceViewportSpanIterator(trace, snap);
379-
while (spit.hasNext()) {
380-
Range<Long> span = spit.next();
382+
for (Range<Long> span : viewport.getOrderedSpans(snap)) {
381383
TraceMemoryState state = getState(span.upperEndpoint(), address);
382384
switch (state) {
383385
case KNOWN:
@@ -403,9 +405,7 @@ public Entry<TraceAddressSnapRange, TraceMemoryState> getMostRecentStateEntry(lo
403405
@Override
404406
public Entry<TraceAddressSnapRange, TraceMemoryState> getViewMostRecentStateEntry(long snap,
405407
Address address) {
406-
TraceViewportSpanIterator spit = new TraceViewportSpanIterator(trace, snap);
407-
while (spit.hasNext()) {
408-
Range<Long> span = spit.next();
408+
for (Range<Long> span: viewport.getOrderedSpans(snap)) {
409409
Entry<TraceAddressSnapRange, TraceMemoryState> entry =
410410
stateMapSpace.reduce(TraceAddressSnapRangeQuery.mostRecent(address, span))
411411
.firstEntry();
@@ -738,9 +738,8 @@ public int getViewBytes(long snap, Address start, ByteBuffer buf) {
738738
}
739739
Map<AddressRange, Long> sources = new TreeMap<>();
740740
AddressSet remains = new AddressSet(toRead);
741-
TraceViewportSpanIterator spit = new TraceViewportSpanIterator(trace, snap);
742-
spans: while (spit.hasNext()) {
743-
Range<Long> span = spit.next();
741+
742+
spans: for (Range<Long> span : viewport.getOrderedSpans(snap)) {
744743
Iterator<AddressRange> arit =
745744
getAddressesWithState(span, s -> s == TraceMemoryState.KNOWN).iterator(start, true);
746745
while (arit.hasNext()) {
@@ -765,15 +764,19 @@ public int getViewBytes(long snap, Address start, ByteBuffer buf) {
765764
int offset = (int) rng.getMinAddress().subtract(toRead.getMinAddress());
766765
int length = (int) rng.getLength();
767766
buf.limit(pos + offset + length);
768-
buf.position(pos + offset);
767+
while (buf.position() < pos + offset) {
768+
buf.put((byte) 0); // fill gaps with 0
769+
}
769770
int read = getBytes(ent.getValue(), rng.getMinAddress(), buf);
770771
if (read < length) {
771772
break;
772773
}
773774
}
774775
// We "got it all", even if there were gaps in "KNOWN"
775776
buf.limit(lim);
776-
buf.position(pos + len);
777+
while (buf.position() < pos + len) {
778+
buf.put((byte) 0); // fill final gap with 0
779+
}
777780
return len;
778781
}
779782

Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/trace/util/DefaultTraceTimeViewport.java

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -100,22 +100,20 @@ public void domainObjectClosed() {
100100
}
101101

102102
protected final Trace trace;
103-
protected final TraceTimeManager timeManager;
104103
/**
105-
* NB: This is the syncing object for the viewport. If there's even a chance an operation may
106-
* need the DB's lock, esp., considering user callbacks, then it must <em>first</em> acquire the
107-
* DB lock.
104+
* NB: This is also the syncing object for the viewport. If there's even a chance an operation
105+
* may need the DB's lock, esp., considering user callbacks, then it must <em>first</em> acquire
106+
* the DB lock.
108107
*/
109-
protected final List<Range<Long>> ordered = new ArrayList<>();
108+
protected final List<Range<Long>> ordered = new ArrayList<>(List.of(Range.singleton(0L)));
110109
protected final RangeSet<Long> spanSet = TreeRangeSet.create();
111110
protected final ForSnapshotsListener listener = new ForSnapshotsListener();
112111
protected final ListenerSet<Runnable> changeListeners = new ListenerSet<>(Runnable.class);
113112

114-
protected long snap;
113+
protected long snap = 0;
115114

116115
public DefaultTraceTimeViewport(Trace trace) {
117116
this.trace = trace;
118-
this.timeManager = trace.getTimeManager();
119117
trace.addCloseListener(listener);
120118
trace.addListener(listener);
121119
}
@@ -266,7 +264,7 @@ protected void refreshSnapRanges() {
266264
RangeSet<Long> spanSet = TreeRangeSet.create();
267265
List<Range<Long>> ordered = new ArrayList<>();
268266
try (LockHold hold = trace.lockRead()) {
269-
collectForkRanges(timeManager, snap, spanSet, ordered);
267+
collectForkRanges(trace.getTimeManager(), snap, spanSet, ordered);
270268
}
271269
synchronized (this.ordered) {
272270
this.spanSet.clear();
@@ -279,6 +277,9 @@ protected void refreshSnapRanges() {
279277
}
280278

281279
public void setSnap(long snap) {
280+
if (this.snap == snap) {
281+
return;
282+
}
282283
this.snap = snap;
283284
refreshSnapRanges();
284285
}
@@ -329,6 +330,19 @@ public boolean isForked() {
329330
}
330331
}
331332

333+
public List<Range<Long>> getOrderedSpans() {
334+
synchronized (ordered) {
335+
return List.copyOf(ordered);
336+
}
337+
}
338+
339+
public List<Range<Long>> getOrderedSpans(long snap) {
340+
synchronized (ordered) {
341+
setSnap(snap);
342+
return getOrderedSpans();
343+
}
344+
}
345+
332346
@Override
333347
public List<Long> getOrderedSnaps() {
334348
synchronized (ordered) {

0 commit comments

Comments
 (0)