From 991da5eb170a3ed97929d253693dd4060689d333 Mon Sep 17 00:00:00 2001 From: Dan <46821332+nsadeveloper789@users.noreply.github.com> Date: Mon, 8 Feb 2021 13:50:47 -0500 Subject: [PATCH] GP-665: Deleting DebuggerTimelineProvider and related. --- .../DebuggerTimelineActionContext.java | 30 -- .../gui/timeline/DebuggerTimelinePanel.java | 161 ------ .../gui/timeline/DebuggerTimelinePlugin.java | 124 ----- .../timeline/DebuggerTimelineProvider.java | 487 ------------------ .../core/debug/gui/timeline/TimelineRow.java | 109 ---- .../debug/gui/timeline/TimelineState.java | 43 -- .../gui/timeline/TimelineTableColumns.java | 73 --- .../core/debug/gui/timeline/TraceObject.java | 151 ------ 8 files changed, 1178 deletions(-) delete mode 100644 Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/timeline/DebuggerTimelineActionContext.java delete mode 100644 Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/timeline/DebuggerTimelinePanel.java delete mode 100644 Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/timeline/DebuggerTimelinePlugin.java delete mode 100644 Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/timeline/DebuggerTimelineProvider.java delete mode 100644 Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/timeline/TimelineRow.java delete mode 100644 Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/timeline/TimelineState.java delete mode 100644 Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/timeline/TimelineTableColumns.java delete mode 100644 Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/timeline/TraceObject.java diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/timeline/DebuggerTimelineActionContext.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/timeline/DebuggerTimelineActionContext.java deleted file mode 100644 index e245a549dd..0000000000 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/timeline/DebuggerTimelineActionContext.java +++ /dev/null @@ -1,30 +0,0 @@ -/* ### - * IP: GHIDRA - * - * 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. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package ghidra.app.plugin.core.debug.gui.timeline; - -import docking.ActionContext; - -public class DebuggerTimelineActionContext extends ActionContext { - private final TimelineRow selection; - - public DebuggerTimelineActionContext(TimelineRow selection) { - this.selection = selection; - } - - public TimelineRow getSelection() { - return selection; - } -} diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/timeline/DebuggerTimelinePanel.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/timeline/DebuggerTimelinePanel.java deleted file mode 100644 index acd8ae2fb9..0000000000 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/timeline/DebuggerTimelinePanel.java +++ /dev/null @@ -1,161 +0,0 @@ -/* ### - * IP: GHIDRA - * - * 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. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package ghidra.app.plugin.core.debug.gui.timeline; - -import java.awt.*; -import java.util.List; - -import javax.swing.*; -import javax.swing.event.ListSelectionEvent; - -import com.google.common.collect.Range; - -import docking.widgets.*; -import docking.widgets.RangeCursorPanel.Direction; -import docking.widgets.table.RowObjectTableModel; -import docking.widgets.timeline.TimelinePanel; -import docking.widgets.timeline.TimelineViewRangeListener; -import ghidra.util.datastruct.ListenerSet; - -public class DebuggerTimelinePanel extends JScrollPane { - static class SnapRequestVetoedException extends Exception { - private final long requestedSnap; - private final long newSnap; - - public SnapRequestVetoedException(long requestedSnap, long newSnap) { - this.requestedSnap = requestedSnap; - this.newSnap = newSnap; - } - - public long getRequestedSnap() { - return requestedSnap; - } - - public long getNewSnap() { - return newSnap; - } - } - - public interface VetoableSnapRequestListener { - void snapRequested(long snap, EventTrigger trigger) throws SnapRequestVetoedException; - } - - protected class ObjectTimelinePanel extends TimelinePanel { - private DebuggerTimelinePanel panel; - - public ObjectTimelinePanel(DebuggerTimelinePanel panel, - RowObjectTableModel model) { - super(model, TimelineRow::getLifespan); - this.panel = panel; - } - - @Override - protected void selectionChanged(ListSelectionEvent e) { - super.selectionChanged(e); - List items = rows.items(); - int min = selectionModel.getMinSelectionIndex(); - if (items != null && min >= 0) { - TimelineRow row = items.get(min); - Component component = getComponent(row); - Point loc = component.getLocation(); - JViewport vp = panel.getViewport(); - vp.setViewPosition(new Point(loc.x, vp.getView().getY())); - } - } - } - - protected class ObjectRangeCursorPanel extends RangeCursorPanel { - public ObjectRangeCursorPanel(Direction direction) { - super(direction); - } - - @Override - protected double adjustRequestedValue(double requested) { - double rounded = Math.round(requested); - // TODO: Also remove 1-snap view buffer? - // Until I figure out the event processing order, leaving the buffer - // prevents some stepping glitches. - if (range.hasLowerBound() && rounded < range.lowerEndpoint() /*+1*/) { - return range.lowerEndpoint(); // +1 - } - if (range.hasUpperBound() && rounded > range.upperEndpoint() /*-1*/) { - return range.upperEndpoint(); // -1 - } - return rounded; - } - } - - protected final ObjectTimelinePanel timeline; - protected final RangeCursorPanel topCursor = new ObjectRangeCursorPanel(Direction.SOUTH) { - Dimension preferredSize = new Dimension(super.getPreferredSize()); - - @Override - public Dimension getPreferredSize() { - preferredSize.width = timeline.getPreferredSize().width; - return preferredSize; - } - }; - protected final ListenerSet listeners = - new ListenerSet<>(VetoableSnapRequestListener.class); - protected final RangeCursorValueListener positionListener = this::cursorPositionChanged; - protected final TimelineViewRangeListener viewRangeListener = this::viewRangeChanged; - - protected ListSelectionModel selectionModel; - - public DebuggerTimelinePanel(RowObjectTableModel model) { - setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); - setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED); - - timeline = new ObjectTimelinePanel(this, model); - timeline.setCompressed(false); - setViewportView(timeline); - setColumnHeaderView(topCursor); - - topCursor.addValueListener(positionListener); - timeline.addViewRangeListener(viewRangeListener); - } - - public void addSnapRequestedListener(VetoableSnapRequestListener listener) { - listeners.add(listener); - } - - private void cursorPositionChanged(double position, EventTrigger trigger) { -// try { -// listeners.fire.snapRequested(Math.round(position), trigger); -// } -// catch (SnapRequestVetoedException e) { -// position = e.getNewSnap(); -// } - } - - private void viewRangeChanged(Range range) { - topCursor.setRange(range); - } - - public void setSelectionModel(ListSelectionModel selectionModel) { - timeline.setSelectionModel(selectionModel); - } - - public void setSnap(long snap) { - topCursor.requestValue(snap); - } - - public void setMaxSnapAtLeast(Long maxSnapAtLeast) { - if (maxSnapAtLeast != null) { - timeline.setMaxAtLeast(maxSnapAtLeast); - } - } -} diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/timeline/DebuggerTimelinePlugin.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/timeline/DebuggerTimelinePlugin.java deleted file mode 100644 index e51687a67e..0000000000 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/timeline/DebuggerTimelinePlugin.java +++ /dev/null @@ -1,124 +0,0 @@ -/* ### - * IP: GHIDRA - * - * 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. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package ghidra.app.plugin.core.debug.gui.timeline; - -import java.util.LinkedHashMap; -import java.util.Map; - -import ghidra.app.events.*; -import ghidra.app.plugin.PluginCategoryNames; -import ghidra.app.plugin.core.debug.AbstractDebuggerPlugin; -import ghidra.app.plugin.core.debug.DebuggerPluginPackage; -import ghidra.app.plugin.core.debug.event.TraceActivatedPluginEvent; -import ghidra.app.plugin.core.debug.gui.objects.ObjectUpdatedEvent; -import ghidra.app.services.DebuggerTraceManagerService; -import ghidra.framework.plugintool.*; -import ghidra.framework.plugintool.util.PluginStatus; -import ghidra.program.model.lang.CompilerSpec; -import ghidra.program.model.listing.Program; -import ghidra.trace.database.DBTrace; -import ghidra.trace.model.Trace; - -@PluginInfo( // - shortDescription = "Debugger timeline manager", // - description = "GUI to view object timelines", // - category = PluginCategoryNames.DEBUGGER, // - packageName = DebuggerPluginPackage.NAME, // - status = PluginStatus.UNSTABLE, // - eventsConsumed = { // - ProgramOpenedPluginEvent.class, // TODO: Remove? - ProgramSelectionPluginEvent.class, // TODO: Later or remove - ProgramHighlightPluginEvent.class, // TODO: Later or remove - ProgramActivatedPluginEvent.class, // TODO: Remove? Covered by Location? - ProgramClosedPluginEvent.class, // For marker set cleanup - ProgramLocationPluginEvent.class, // For static listing sync - TraceActivatedPluginEvent.class, // - ObjectUpdatedEvent.class, // - }, // - servicesRequired = { // - DebuggerTraceManagerService.class, // - } // -) - -public class DebuggerTimelinePlugin extends AbstractDebuggerPlugin { - protected DebuggerTimelineProvider provider; - private Program currentProgram; - private Map traceMap = new LinkedHashMap<>(); - - public DebuggerTimelinePlugin(PluginTool tool) { - super(tool); - } - - @Override - protected void init() { - provider = new DebuggerTimelineProvider(this); - super.init(); - } - - @Override - protected void dispose() { - tool.removeComponentProvider(provider); - super.dispose(); - } - - @Override - public void processEvent(PluginEvent event) { - super.processEvent(event); - if (event instanceof ProgramOpenedPluginEvent) { - setProgram(((ProgramOpenedPluginEvent) event).getProgram(), false); - } - if (event instanceof ProgramActivatedPluginEvent) { - setProgram(((ProgramActivatedPluginEvent) event).getActiveProgram(), false); - } - if (event instanceof ProgramClosedPluginEvent) { - setProgram(((ProgramClosedPluginEvent) event).getProgram(), true); - } - if (event instanceof ObjectUpdatedEvent) { - provider.update(((ObjectUpdatedEvent) event).getObject()); - } - if (event instanceof TraceActivatedPluginEvent) { - TraceActivatedPluginEvent ev = (TraceActivatedPluginEvent) event; - provider.coordinatesActivated(ev.getActiveCoordinates()); - } - } - - private void setProgram(Program pgm, boolean remove) { - currentProgram = pgm; - if (pgm == null) { - return; - } - try { - Trace trace = null; - if (traceMap.containsKey(pgm)) { - trace = traceMap.get(pgm); - if (remove) { - traceMap.remove(pgm); - trace = null; - } - } - else { - // TODO: I'm not sure what this is doing, but it seems like a bad idea.... - CompilerSpec cspec = pgm.getCompilerSpec(); - trace = new DBTrace(pgm.getName(), cspec, this); - } - // TODO: Nothing seems to put into traceMap, so just commenting out - // provider.doSetTrace(trace); - } - catch (Exception e) { - e.printStackTrace(); - } - } -} diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/timeline/DebuggerTimelineProvider.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/timeline/DebuggerTimelineProvider.java deleted file mode 100644 index 9f9583fff2..0000000000 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/timeline/DebuggerTimelineProvider.java +++ /dev/null @@ -1,487 +0,0 @@ -/* ### - * IP: GHIDRA - * - * 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. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package ghidra.app.plugin.core.debug.gui.timeline; - -import static ghidra.app.plugin.core.debug.gui.DebuggerResources.*; - -import java.awt.BorderLayout; -import java.awt.event.MouseEvent; -import java.util.*; - -import javax.swing.*; - -import docking.ActionContext; -import docking.WindowPosition; -import docking.action.DockingActionIf; -import docking.action.ToolBarData; -import docking.widgets.EventTrigger; -import docking.widgets.table.*; -import ghidra.app.plugin.core.debug.DebuggerCoordinates; -import ghidra.app.plugin.core.debug.DebuggerPluginPackage; -import ghidra.app.plugin.core.debug.gui.DebuggerResources.*; -import ghidra.app.plugin.core.debug.gui.DebuggerSnapActionContext; -import ghidra.app.plugin.core.debug.gui.objects.ObjectContainer; -import ghidra.app.plugin.core.debug.gui.timeline.DebuggerTimelinePanel.VetoableSnapRequestListener; -import ghidra.app.services.*; -import ghidra.framework.model.DomainObject; -import ghidra.framework.plugintool.AutoService; -import ghidra.framework.plugintool.ComponentProviderAdapter; -import ghidra.framework.plugintool.annotation.AutoServiceConsumed; -import ghidra.trace.model.Trace; -import ghidra.trace.model.Trace.TraceSnapshotChangeType; -import ghidra.trace.model.Trace.TraceThreadChangeType; -import ghidra.trace.model.TraceDomainObjectListener; -import ghidra.trace.model.modules.TraceModule; -import ghidra.trace.model.modules.TraceModuleManager; -import ghidra.trace.model.thread.TraceThread; -import ghidra.trace.model.thread.TraceThreadManager; -import ghidra.trace.model.time.TraceSnapshot; -import ghidra.util.database.UndoableTransaction; -import ghidra.util.table.GhidraTable; -import ghidra.util.table.GhidraTableFilterPanel; - -public class DebuggerTimelineProvider extends ComponentProviderAdapter { - - protected static boolean sameCoordinates(DebuggerCoordinates a, DebuggerCoordinates b) { - if (!Objects.equals(a.getTrace(), b.getTrace())) { - return false; - } - if (!Objects.equals(a.getSnap(), b.getSnap())) { - return false; - } - return true; - } - - private final DebuggerTimelinePlugin plugin; - - @AutoServiceConsumed - private DebuggerModelService modelService; - @AutoServiceConsumed - private DebuggerTraceManagerService traceManager; - @SuppressWarnings("unused") - private final AutoService.Wiring autoWiring; - - DebuggerCoordinates current = DebuggerCoordinates.NOWHERE; - private Trace currentTrace; // Copy for transition - private TraceObject currentObject; - - private final ThreadsListener threadsListener = new ThreadsListener(); - private final VetoableSnapRequestListener snapListener = this::snapRequested; - - protected final EnumeratedColumnTableModel timelineTableModel = - new DefaultEnumeratedColumnTableModel<>("Objects", TimelineTableColumns.class); - - private JSplitPane mainPanel = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT); - protected GTable objectTable; - private DebuggerTimelinePanel timelinePanel; - private GhidraTableFilterPanel timelineFilterPanel; - - private ActionContext myActionContext; - - StepTraceBackwardAction actionStepTraceBackward; - StepTraceForwardAction actionStepTraceForward; - SeekTracePresentAction actionSeekTracePresent; - - private Map map = new LinkedHashMap(); - private Map rowMap = new LinkedHashMap(); - - public DebuggerTimelineProvider(final DebuggerTimelinePlugin plugin) { - super(plugin.getTool(), TITLE_PROVIDER_OBJECTS, plugin.getName()); - this.plugin = plugin; - - this.autoWiring = AutoService.wireServicesConsumed(plugin, this); - - setIcon(ICON_PROVIDER_OBJECTS); - setHelpLocation(HELP_PROVIDER_OBJECTS); - setWindowMenuGroup(DebuggerPluginPackage.NAME); - - buildMainPanel(); - - // TODO: Consider a custom cell renderer in the table instead of a timeline widget? - // TODO: Should I receive clicks on that renderer to seek to a given snap? - setDefaultWindowPosition(WindowPosition.BOTTOM); - - myActionContext = new DebuggerSnapActionContext(0); - createActions(); - contextChanged(); - - setVisible(true); - } - - private void doSetTrace(Trace trace) { - removeOldListeners(); - currentTrace = trace; - addNewListeners(); - - loadObjects(); - } - - private void doSetObject(TraceObject object) { - // TODO: Use a map if speed becomes an issue - timelineFilterPanel - .setSelectedItem(timelineTableModel.findFirst(row -> row.getObject() == object)); - currentObject = object; - } - - private void doSetSnap(long snap) { - timelinePanel.setSnap(snap); - myActionContext = new DebuggerSnapActionContext(snap); - } - - public void coordinatesActivated(DebuggerCoordinates coordinates) { - if (sameCoordinates(current, coordinates)) { - current = coordinates; - return; - } - current = coordinates; - - doSetTrace(current.getTrace()); - doSetSnap(current.getSnap()); - contextChanged(); - } - - public void setObject(TraceObject object) { - if (currentObject == object) { - return; - } - doSetObject(object); - contextChanged(); - } - - private void removeOldListeners() { - if (currentTrace == null) { - return; - } - currentTrace.removeListener(threadsListener); - } - - private void addNewListeners() { - if (currentTrace == null) { - return; - } - currentTrace.addListener(threadsListener); - } - - protected void loadObjects() { - map.clear(); - rowMap.clear(); - timelineTableModel.clear(); - Trace curTrace = current.getTrace(); - if (curTrace == null) { - return; - } - TraceThreadManager manager = curTrace.getThreadManager(); - Collection allThreads = manager.getAllThreads(); - for (TraceThread thread : allThreads) { - TraceObject t = new TraceObject(thread); - timelineTableModel.add(new TimelineRow(modelService, t)); - } - TraceModuleManager modmgr = curTrace.getModuleManager(); - Collection allModules = modmgr.getAllModules(); - for (TraceModule module : allModules) { - TraceObject t = new TraceObject(module); - timelineTableModel.add(new TimelineRow(modelService, t)); - } - timelinePanel.setMaxSnapAtLeast(curTrace.getTimeManager().getMaxSnap()); - } - - @Override - public void addLocalAction(DockingActionIf action) { - super.addLocalAction(action); - } - - @Override - public ActionContext getActionContext(MouseEvent event) { - if (myActionContext == null) { - return super.getActionContext(event); - } - return myActionContext; - } - - private void snapRequested(long snap, EventTrigger trigger) { - if (snap < 0) { - snap = 0; - } - Trace curTrace = current.getTrace(); - if (curTrace == null) { - snap = 0; - } - else { - Long maxSnap = curTrace.getTimeManager().getMaxSnap(); - if (maxSnap == null) { - maxSnap = 0L; - } - if (snap > maxSnap) { - snap = maxSnap; - } - } - if (trigger == EventTrigger.GUI_ACTION) { - traceManager.activateSnap(snap); - } - myActionContext = new DebuggerSnapActionContext(snap); - contextChanged(); - } - - protected void buildMainPanel() { - mainPanel.setContinuousLayout(true); - - JPanel tablePanel = new JPanel(new BorderLayout()); - objectTable = new GhidraTable(timelineTableModel); - objectTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); - tablePanel.add(new JScrollPane(objectTable)); - timelineFilterPanel = new GhidraTableFilterPanel<>(objectTable, timelineTableModel); - tablePanel.add(timelineFilterPanel, BorderLayout.SOUTH); - mainPanel.setLeftComponent(tablePanel); - - timelinePanel = new DebuggerTimelinePanel(timelineFilterPanel.getTableFilterModel()); - mainPanel.setRightComponent(timelinePanel); - - mainPanel.setResizeWeight(0.4); - - objectTable.getSelectionModel().addListSelectionListener(evt -> { - TimelineRow row = timelineFilterPanel.getSelectedItem(); - myActionContext = new DebuggerTimelineActionContext(row); - contextChanged(); - if (row != null && traceManager != null) { - TraceObject object = row.getObject(); - if (object.isThread()) { - traceManager.activateThread((TraceThread) object.getObject()); - } - } - }); - timelinePanel.setSelectionModel(objectTable.getSelectionModel()); - timelinePanel.addSnapRequestedListener(snapListener); - } - - protected void createActions() { - actionStepTraceBackward = new StepTraceBackwardAction(); - actionStepTraceForward = new StepTraceForwardAction(); - actionSeekTracePresent = new SeekTracePresentAction(); - } - - @Override - public JComponent getComponent() { - return mainPanel; - } - - public void update(ObjectContainer container) { - String shortName = container.getShortName(); - if (shortName == null || !shortName.equals("Sequence")) { - return; - } - - TraceObject object = null; - Trace curTrace = current.getTrace(); - try (UndoableTransaction tid = - UndoableTransaction.start(curTrace, "Populate Snapshot", true)) { - ObjectContainer ancestor = container; - while (ancestor != null && !ancestor.getPrefixedName().contains("[")) { - ancestor = ancestor.getParent(); - } - if (ancestor == null) { - return; - } - String objName = ancestor.getPrefixedName(); - TimelineRow row = null; - if (map.containsKey(objName)) { - object = map.get(objName); - row = rowMap.get(objName); - } - else { - object = new TraceObject(curTrace); - object.setName(objName); - map.put(objName, object); - row = new TimelineRow(modelService, object); - rowMap.put(objName, row); - timelineTableModel.add(row); - } - String[] split = container.getName().split(" "); - String searchString = container.getTargetObject().getJoinedPath("."); - long pos = -1; - if (searchString.contains("MinPos")) { - System.err.println("minpos"); - pos = Long.parseLong(split[split.length - 1], 16); - object.setCreationSnap(pos); - curTrace.getTimeManager() - .getSnapshot(pos, true) - .setDescription(object + " created"); - } - else if (searchString.contains("MaxPos")) { - System.err.println("maxpos"); - pos = Long.parseLong(split[split.length - 1], 16); - object.setDestructionSnap(pos); - curTrace.getTimeManager() - .getSnapshot(pos, true) - .setDescription(object + " destroyed"); - } - else if (searchString.contains("Position")) { - /* - pos = Long.parseLong(split[split.length - 1], 16); - object.setCreationSnap(pos); - curTrace.getTimeManager() - .getSnapshot(pos, true) - .setDescription(object + " mark set"); - */ - } - if (pos >= 0L) { - timelinePanel.setMaxSnapAtLeast(pos); - } - timelineTableModel.notifyUpdated(row); - mainPanel.validate(); - mainPanel.repaint(); - } - catch (Exception e) { - e.printStackTrace(); - } - - setObject(object); - } - - protected class StepTraceBackwardAction extends AbstractStepTraceBackwardAction { - public static final String GROUP = GROUP_GENERAL; - - public StepTraceBackwardAction() { - super(plugin); - setToolBarData(new ToolBarData(ICON, GROUP)); - addLocalAction(this); - setEnabled(false); - } - - @Override - public void actionPerformed(ActionContext context) { - traceManager.activateSnap(current.getSnap() - 1); - } - - @Override - public boolean isEnabledForContext(ActionContext context) { - if (current.getTrace() == null) { - return false; - } - // TODO: Can I track minTick? - if (current.getSnap() <= 0) { - return false; - } - return true; - } - } - - protected class StepTraceForwardAction extends AbstractStepTraceForwardAction { - public static final String GROUP = GROUP_GENERAL; - - public StepTraceForwardAction() { - super(plugin); - setToolBarData(new ToolBarData(ICON, GROUP)); - addLocalAction(this); - setEnabled(false); - } - - @Override - public void actionPerformed(ActionContext context) { - traceManager.activateSnap(current.getSnap() + 1); - } - - @Override - public boolean isEnabledForContext(ActionContext context) { - Trace curTrace = current.getTrace(); - if (curTrace == null) { - return false; - } - Long maxSnap = curTrace.getTimeManager().getMaxSnap(); - if (maxSnap == null || current.getSnap() >= maxSnap) { - return false; - } - return true; - } - } - - protected class SeekTracePresentAction extends AbstractSeekTracePresentAction { - public static final String GROUP = GROUP_GENERAL; - - public SeekTracePresentAction() { - super(plugin); - setToolBarData(new ToolBarData(ICON, GROUP)); - addLocalAction(this); - setEnabled(false); - } - - @Override - public void actionPerformed(ActionContext context) { - if (current.getTrace() == null) { - return; - } - TraceRecorder recorder = current.getRecorder(); - if (recorder == null) { - return; - } - traceManager.activateSnap(recorder.getSnap()); - } - - @Override - public boolean isEnabled() { - if (current.getTrace() == null) { - return false; - } - TraceRecorder recorder = current.getRecorder(); - if (recorder == null) { - return false; - } - if (current.getSnap() == recorder.getSnap()) { - return false; - } - return true; - } - } - - private class ThreadsListener extends TraceDomainObjectListener { - public ThreadsListener() { - listenForUntyped(DomainObject.DO_OBJECT_RESTORED, e -> objectRestored()); - - listenFor(TraceThreadChangeType.ADDED, this::threadAdded); - listenFor(TraceThreadChangeType.CHANGED, this::threadChanged); - listenFor(TraceThreadChangeType.LIFESPAN_CHANGED, this::threadChanged); - listenFor(TraceThreadChangeType.DELETED, this::threadDeleted); - - listenFor(TraceSnapshotChangeType.ADDED, this::snapshotAdded); - listenFor(TraceSnapshotChangeType.DELETED, this::snapshotDeleted); - } - - private void objectRestored() { - loadObjects(); - } - - private void threadAdded(TraceThread thread) { - timelineTableModel.add(new TimelineRow(modelService, new TraceObject(thread))); - } - - private void threadChanged(TraceThread thread) { - timelineTableModel.notifyUpdatedWith(row -> row.getObject() == thread); - } - - private void threadDeleted(TraceThread thread) { - timelineTableModel.deleteWith(row -> row.getObject() == thread); - } - - private void snapshotAdded(TraceSnapshot snapshot) { - long maxSnap = current.getTrace().getTimeManager().getMaxSnap(); - timelinePanel.setMaxSnapAtLeast(maxSnap); - } - - private void snapshotDeleted(TraceSnapshot snapshot) { - timelinePanel.setMaxSnapAtLeast(current.getTrace().getTimeManager().getMaxSnap()); - } - } - -} diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/timeline/TimelineRow.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/timeline/TimelineRow.java deleted file mode 100644 index 579a69ba37..0000000000 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/timeline/TimelineRow.java +++ /dev/null @@ -1,109 +0,0 @@ -/* ### - * IP: GHIDRA - * - * 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. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package ghidra.app.plugin.core.debug.gui.timeline; - -import com.google.common.collect.Range; - -import ghidra.app.services.DebuggerModelService; -import ghidra.app.services.TraceRecorder; -import ghidra.dbg.target.TargetExecutionStateful.TargetExecutionState; -import ghidra.trace.model.Trace; -import ghidra.util.database.UndoableTransaction; - -public class TimelineRow { - private final DebuggerModelService service; - private final TraceObject object; - - public TimelineRow(DebuggerModelService service, TraceObject object) { - this.service = service; - this.object = object; - } - - public TraceObject getObject() { - return object; - } - - public Trace getTrace() { - return object.getTrace(); - } - - public void setName(String name) { - try (UndoableTransaction tid = - UndoableTransaction.start(object.getTrace(), "Renamed thread", true)) { - object.setName(name); - } - } - - public String getName() { - return object.getName(); - } - - public long getCreationTick() { - return object.getCreationSnap(); - } - - public String getDestructionTick() { - long tick = object.getDestructionSnap(); - return tick == Long.MAX_VALUE ? "" : Long.toString(tick); - } - - public Range getLifespan() { - return object.getLifespan(); - } - - public void setComment(String comment) { - try (UndoableTransaction tid = - UndoableTransaction.start(object.getTrace(), "Renamed thread", true)) { - object.setComment(comment); - } - } - - public String getComment() { - return object.getComment(); - } - - public TimelineState getState() { - if (!object.isAlive()) { - return TimelineState.TERMINATED; - } - TraceRecorder recorder = service.getRecorder(object.getTrace()); - if (recorder == null) { - return TimelineState.ALIVE; - } - TargetExecutionState targetState = recorder.getTargetThreadState(object); - if (targetState == null) { - return TimelineState.UNKNOWN; - } - switch (targetState) { - case ALIVE: - return TimelineState.ALIVE; - case INACTIVE: - return TimelineState.UNKNOWN; - case RUNNING: - return TimelineState.RUNNING; - case STOPPED: - return TimelineState.STOPPED; - case TERMINATED: - return TimelineState.TERMINATED; - } - throw new AssertionError(); - } - - @Override - public String toString() { - return getName(); - } -} diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/timeline/TimelineState.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/timeline/TimelineState.java deleted file mode 100644 index 8b843ed9b5..0000000000 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/timeline/TimelineState.java +++ /dev/null @@ -1,43 +0,0 @@ -/* ### - * IP: GHIDRA - * - * 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. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package ghidra.app.plugin.core.debug.gui.timeline; - -public enum TimelineState { - /** - * The last recorded state is alive, but the recorder is not tracking the live thread - * - * This state is generally erroneous. If it is seen, the recorder has fallen out of sync with - * the live session and/or the trace. - */ - UNKNOWN, - /** - * The last recorded state is alive, but there is no live session to know STOPPED or RUNNING - */ - // TODO: Should the thread state transitions be recorded? - ALIVE, - /** - * The thread is alive, but suspended - */ - STOPPED, - /** - * The thread is alive and running - */ - RUNNING, - /** - * The thread has been terminated (either as recorded, or as reported by the live session) - */ - TERMINATED; -} diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/timeline/TimelineTableColumns.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/timeline/TimelineTableColumns.java deleted file mode 100644 index ff0cf973b8..0000000000 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/timeline/TimelineTableColumns.java +++ /dev/null @@ -1,73 +0,0 @@ -/* ### - * IP: GHIDRA - * - * 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. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package ghidra.app.plugin.core.debug.gui.timeline; - -import java.util.function.BiConsumer; -import java.util.function.Function; - -import docking.widgets.table.DefaultEnumeratedColumnTableModel.EnumeratedTableColumn; - -public enum TimelineTableColumns - implements EnumeratedTableColumn { - NAME("Name", String.class, TimelineRow::getName, TimelineRow::setName), - CREATED("Created", Long.class, TimelineRow::getCreationTick), - DESTROYED("Destroyed", String.class, TimelineRow::getDestructionTick), - STATE("State", TimelineState.class, TimelineRow::getState), - COMMENT("Comment", String.class, TimelineRow::getComment, TimelineRow::setComment); - - private final String header; - private final Function getter; - private final BiConsumer setter; - private final Class cls; - - TimelineTableColumns(String header, Class cls, Function getter) { - this(header, cls, getter, null); - } - - @SuppressWarnings("unchecked") - TimelineTableColumns(String header, Class cls, Function getter, - BiConsumer setter) { - this.header = header; - this.cls = cls; - this.getter = getter; - this.setter = (BiConsumer) setter; - } - - @Override - public String getHeader() { - return header; - } - - @Override - public Class getValueClass() { - return cls; - } - - @Override - public Object getValueOf(TimelineRow row) { - return getter.apply(row); - } - - @Override - public boolean isEditable(TimelineRow row) { - return setter != null; - } - - @Override - public void setValueOf(TimelineRow row, Object value) { - setter.accept(row, value); - } -} diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/timeline/TraceObject.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/timeline/TraceObject.java deleted file mode 100644 index ab0d83af41..0000000000 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/timeline/TraceObject.java +++ /dev/null @@ -1,151 +0,0 @@ -/* ### - * IP: GHIDRA - * - * 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. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package ghidra.app.plugin.core.debug.gui.timeline; - -import com.google.common.collect.Range; - -import ghidra.trace.model.Trace; -import ghidra.trace.model.modules.TraceModule; -import ghidra.trace.model.thread.TraceThread; - -// TODO: Create an interface for time-bound objects -// Then either: -// 1) The appropriate trace and/or target objects can implement them -// 2) We create the necessary wrappers, one for trace threads, and another for TTD target objects -public class TraceObject implements TraceThread { - - private Object object; - private Trace trace; - private String name; - private Long creationTick; - private Long destructionTick; - private Range lifespan; - private String comment; - private long key = 0L; - private boolean isThread = false; - - public TraceObject(Trace currentTrace) { - this.trace = currentTrace; - this.object = null; - creationTick = 0L; - destructionTick = Long.MAX_VALUE; - lifespan = Range.atLeast(creationTick); - } - - public TraceObject(TraceThread thread) { - this.trace = thread.getTrace(); - this.object = thread; - name = thread.getName(); - creationTick = thread.getCreationSnap(); - destructionTick = thread.getDestructionSnap(); - lifespan = thread.getLifespan(); - key = thread.getKey(); - comment = thread.getComment(); - isThread = true; - } - - public TraceObject(TraceModule module) { - this.trace = module.getTrace(); - this.object = module; - name = module.getName(); - creationTick = module.getLoadedSnap(); - destructionTick = module.getUnloadedSnap(); - lifespan = module.getLifespan(); - comment = module.toString(); - } - - public Object getObject() { - return object; - } - - @Override - public Trace getTrace() { - return trace; - } - - @Override - public long getKey() { - return key; - } - - @Override - public String getPath() { - return name; // TODO - } - - @Override - public String getName() { - return name; - } - - @Override - public void setName(String name) { - this.name = name; - } - - @Override - public void setCreationSnap(long creationTick) { - this.creationTick = creationTick; - lifespan = Range.closed(creationTick, destructionTick); - } - - @Override - public long getCreationSnap() { - return creationTick; - } - - @Override - public void setDestructionSnap(long destructionTick) { - this.destructionTick = destructionTick; - lifespan = Range.closed(creationTick, destructionTick); - } - - @Override - public long getDestructionSnap() { - return destructionTick; - } - - @Override - public void setLifespan(Range lifespan) { - this.lifespan = lifespan; - } - - @Override - public Range getLifespan() { - return lifespan; - } - - @Override - public void setComment(String comment) { - this.comment = comment; - } - - @Override - public String getComment() { - return comment; - } - - @Override - public void delete() { - // TODO Auto-generated method stub - - } - - public boolean isThread() { - return isThread; - } - -}