/*******************************************************************************
- * Copyright (c) 2013 Ericsson
+ * Copyright (c) 2013, 2014 Ericsson
*
* All rights reserved. This program and the accompanying materials are
* made available under the terms of the Eclipse Public License v1.0 which
package org.eclipse.linuxtools.tmf.ui.views.callstack;
+import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
+import java.util.Map;
import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.action.IStatusLineManager;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.linuxtools.internal.tmf.ui.Activator;
import org.eclipse.linuxtools.internal.tmf.ui.ITmfImageConstants;
import org.eclipse.linuxtools.internal.tmf.ui.Messages;
+import org.eclipse.linuxtools.statesystem.core.ITmfStateSystem;
+import org.eclipse.linuxtools.statesystem.core.exceptions.AttributeNotFoundException;
+import org.eclipse.linuxtools.statesystem.core.exceptions.StateSystemDisposedException;
+import org.eclipse.linuxtools.statesystem.core.exceptions.StateValueTypeException;
+import org.eclipse.linuxtools.statesystem.core.exceptions.TimeRangeException;
+import org.eclipse.linuxtools.statesystem.core.interval.ITmfStateInterval;
+import org.eclipse.linuxtools.statesystem.core.statevalue.ITmfStateValue;
+import org.eclipse.linuxtools.statesystem.core.statevalue.ITmfStateValue.Type;
import org.eclipse.linuxtools.tmf.core.callstack.CallStackStateProvider;
-import org.eclipse.linuxtools.tmf.core.ctfadaptor.CtfTmfTimestamp;
-import org.eclipse.linuxtools.tmf.core.exceptions.AttributeNotFoundException;
-import org.eclipse.linuxtools.tmf.core.exceptions.StateSystemDisposedException;
-import org.eclipse.linuxtools.tmf.core.exceptions.StateValueTypeException;
-import org.eclipse.linuxtools.tmf.core.exceptions.TimeRangeException;
-import org.eclipse.linuxtools.tmf.core.interval.ITmfStateInterval;
import org.eclipse.linuxtools.tmf.core.signal.TmfRangeSynchSignal;
import org.eclipse.linuxtools.tmf.core.signal.TmfSignalHandler;
import org.eclipse.linuxtools.tmf.core.signal.TmfTimeSynchSignal;
import org.eclipse.linuxtools.tmf.core.signal.TmfTraceClosedSignal;
import org.eclipse.linuxtools.tmf.core.signal.TmfTraceOpenedSignal;
import org.eclipse.linuxtools.tmf.core.signal.TmfTraceSelectedSignal;
-import org.eclipse.linuxtools.tmf.core.statesystem.ITmfStateSystem;
-import org.eclipse.linuxtools.tmf.core.statevalue.ITmfStateValue;
-import org.eclipse.linuxtools.tmf.core.statevalue.ITmfStateValue.Type;
import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp;
+import org.eclipse.linuxtools.tmf.core.timestamp.TmfNanoTimestamp;
import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimeRange;
import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestamp;
import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestampDelta;
import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace;
-import org.eclipse.linuxtools.tmf.core.trace.TmfExperiment;
+import org.eclipse.linuxtools.tmf.core.trace.TmfTraceManager;
import org.eclipse.linuxtools.tmf.ui.editors.ITmfTraceEditor;
import org.eclipse.linuxtools.tmf.ui.views.TmfView;
import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.ITimeGraphRangeListener;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.ui.IActionBars;
import org.eclipse.ui.IEditorPart;
*/
private enum State { IDLE, BUSY, PENDING }
- private final String[] COLUMN_NAMES = new String[] {
+ private static final String[] COLUMN_NAMES = new String[] {
Messages.CallStackView_FunctionColumn,
Messages.CallStackView_DepthColumn,
Messages.CallStackView_EntryTimeColumn,
Messages.CallStackView_DurationColumn
};
+ private static final int[] COLUMN_WIDTHS = new int[] {
+ 200,
+ 50,
+ 120,
+ 120,
+ 120
+ };
+
+ // Fraction of a function duration to be added as spacing
+ private static final double SPACING_RATIO = 0.01;
+
private static final Image THREAD_IMAGE = Activator.getDefault().getImageFromPath("icons/obj16/thread_obj.gif"); //$NON-NLS-1$
private static final Image STACKFRAME_IMAGE = Activator.getDefault().getImageFromPath("icons/obj16/stckframe_obj.gif"); //$NON-NLS-1$
+ private static final String IMPORT_MAPPING_ICON_PATH = "icons/etool16/import.gif"; //$NON-NLS-1$
+
// ------------------------------------------------------------------------
// Fields
// ------------------------------------------------------------------------
// The time graph combo
- TimeGraphCombo fTimeGraphCombo;
+ private TimeGraphCombo fTimeGraphCombo;
// The selected trace
private ITmfTrace fTrace;
// The selected thread map
- final private HashMap<ITmfTrace, String> fSelectedThreadMap = new HashMap<ITmfTrace, String>();
+ private final Map<ITmfTrace, String> fSelectedThreadMap = new HashMap<>();
// The time graph entry list
- private ArrayList<ThreadEntry> fEntryList;
+ private List<ThreadEntry> fEntryList;
// The trace to entry list hash map
- final private HashMap<ITmfTrace, ArrayList<ThreadEntry>> fEntryListMap = new HashMap<ITmfTrace, ArrayList<ThreadEntry>>();
+ private final Map<ITmfTrace, ArrayList<ThreadEntry>> fEntryListMap = new HashMap<>();
// The trace to build thread hash map
- final private HashMap<ITmfTrace, BuildThread> fBuildThreadMap = new HashMap<ITmfTrace, BuildThread>();
+ private final Map<ITmfTrace, BuildThread> fBuildThreadMap = new HashMap<>();
+
+ /** The map to map function addresses to function names */
+ private Map<String, String> fNameMapping;
// The start time
private long fStartTime;
// The previous item action
private Action fPreviousItemAction;
+ /** The action to import a function-name mapping file */
+ private Action fImportMappingAction;
+
// The zoom thread
private ZoomThread fZoomThread;
private State fRedrawState = State.IDLE;
// The redraw synchronization object
- final private Object fSyncObj = new Object();
+ private final Object fSyncObj = new Object();
// The saved time sync. signal used when switching off the pinning of a view
private TmfTimeSynchSignal fSavedTimeSyncSignal;
// ------------------------------------------------------------------------
private class ThreadEntry implements ITimeGraphEntry {
- // The Trace
- private final ITmfTrace fThreadTrace;
// The start time
private final long fTraceStartTime;
// The end time
private final String fName;
// The thread attribute quark
private final int fThreadQuark;
+ // The state system from which this entry comes
+ private final ITmfStateSystem fSS;
public ThreadEntry(ITmfTrace trace, String name, int threadQuark, long startTime, long endTime) {
- fThreadTrace = trace;
- fChildren = new ArrayList<CallStackEntry>();
+ fChildren = new ArrayList<>();
fName = name;
fTraceStartTime = startTime;
fTraceEndTime = endTime;
fThreadQuark = threadQuark;
+
+ fSS = getCallStackStateSystem(trace);
}
@Override
@Override
public boolean hasChildren() {
if (fChildren == null) {
- ITmfStateSystem ss = fThreadTrace.getStateSystems().get(CallStackStateProvider.ID);
+ ITmfStateSystem ss = getStateSystem();
+ if (ss == null) {
+ return false;
+ }
try {
int eventStackQuark = ss.getQuarkRelative(fThreadQuark, CallStackStateProvider.CALL_STACK);
ITmfStateInterval eventStackInterval = ss.querySingleState(ss.getStartTime(), eventStackQuark);
return ! eventStackInterval.getStateValue().isNull() || eventStackInterval.getEndTime() != ss.getCurrentEndTime();
} catch (AttributeNotFoundException e) {
- e.printStackTrace();
+ Activator.getDefault().logError("Error querying state system", e); //$NON-NLS-1$
} catch (TimeRangeException e) {
- e.printStackTrace();
+ Activator.getDefault().logError("Error querying state system", e); //$NON-NLS-1$
} catch (StateSystemDisposedException e) {
/* Ignored */
}
return fThreadQuark;
}
- public ITmfTrace getTrace() {
- return fThreadTrace;
+ @Nullable
+ public ITmfStateSystem getStateSystem() {
+ return fSS;
}
public void addChild(CallStackEntry entry) {
CallStackEntry entry = (CallStackEntry) element;
if (columnIndex == 0) {
return entry.getFunctionName();
- } else if (columnIndex == 1) {
- if (entry.getFunctionName().length() > 0) {
- int depth = entry.getStackLevel();
- return Integer.toString(depth);
- }
- } else if (columnIndex == 2) {
- if (entry.getFunctionName().length() > 0) {
- ITmfTimestamp ts = new TmfTimestamp(entry.getStartTime(), ITmfTimestamp.NANOSECOND_SCALE);
- return ts.toString();
- }
- } else if (columnIndex == 3) {
- if (entry.getFunctionName().length() > 0) {
- ITmfTimestamp ts = new TmfTimestamp(entry.getEndTime(), ITmfTimestamp.NANOSECOND_SCALE);
- return ts.toString();
- }
- } else if (columnIndex == 4) {
- if (entry.getFunctionName().length() > 0) {
- ITmfTimestamp ts = new TmfTimestampDelta(entry.getEndTime() - entry.getStartTime(), ITmfTimestamp.NANOSECOND_SCALE);
- return ts.toString();
- }
+ } else if (columnIndex == 1 && entry.getFunctionName().length() > 0) {
+ int depth = entry.getStackLevel();
+ return Integer.toString(depth);
+ } else if (columnIndex == 2 && entry.getFunctionName().length() > 0) {
+ ITmfTimestamp ts = new TmfTimestamp(entry.getStartTime(), ITmfTimestamp.NANOSECOND_SCALE);
+ return ts.toString();
+ } else if (columnIndex == 3 && entry.getFunctionName().length() > 0) {
+ ITmfTimestamp ts = new TmfTimestamp(entry.getEndTime(), ITmfTimestamp.NANOSECOND_SCALE);
+ return ts.toString();
+ } else if (columnIndex == 4 && entry.getFunctionName().length() > 0) {
+ ITmfTimestamp ts = new TmfTimestampDelta(entry.getEndTime() - entry.getStartTime(), ITmfTimestamp.NANOSECOND_SCALE);
+ return ts.toString();
}
}
return ""; //$NON-NLS-1$
}
private class ZoomThread extends Thread {
- private final ArrayList<ThreadEntry> fZoomEntryList;
+ private final List<ThreadEntry> fZoomEntryList;
private final long fZoomStartTime;
private final long fZoomEndTime;
private final IProgressMonitor fMonitor;
- public ZoomThread(ArrayList<ThreadEntry> entryList, long startTime, long endTime) {
+ public ZoomThread(List<ThreadEntry> entryList, long startTime, long endTime) {
super("ResourcesView zoom"); //$NON-NLS-1$
fZoomEntryList = entryList;
fZoomStartTime = startTime;
}
long resolution = Math.max(1, (fZoomEndTime - fZoomStartTime) / fDisplayWidth);
for (ThreadEntry threadEntry : fZoomEntryList) {
- ITmfStateSystem ss = threadEntry.fThreadTrace.getStateSystems().get(CallStackStateProvider.ID);
- if (ss == null || !ss.waitUntilBuilt()) {
+ ITmfStateSystem ss = threadEntry.getStateSystem();
+ if (ss == null) {
+ continue;
+ }
+ ss.waitUntilBuilt();
+ if (ss.isCancelled()) {
continue;
}
for (ITimeGraphEntry child : threadEntry.getChildren()) {
fTimeGraphCombo.setTreeColumns(COLUMN_NAMES);
- fTimeGraphCombo.getTreeViewer().getTree().getColumn(0).setWidth(200);
- fTimeGraphCombo.getTreeViewer().getTree().getColumn(1).setWidth(50);
- fTimeGraphCombo.getTreeViewer().getTree().getColumn(2).setWidth(120);
- fTimeGraphCombo.getTreeViewer().getTree().getColumn(3).setWidth(120);
- fTimeGraphCombo.getTreeViewer().getTree().getColumn(4).setWidth(120);
+ fTimeGraphCombo.getTreeViewer().getTree().getColumn(0).setWidth(COLUMN_WIDTHS[0]);
+ fTimeGraphCombo.getTreeViewer().getTree().getColumn(1).setWidth(COLUMN_WIDTHS[1]);
+ fTimeGraphCombo.getTreeViewer().getTree().getColumn(2).setWidth(COLUMN_WIDTHS[2]);
+ fTimeGraphCombo.getTreeViewer().getTree().getColumn(3).setWidth(COLUMN_WIDTHS[3]);
+ fTimeGraphCombo.getTreeViewer().getTree().getColumn(4).setWidth(COLUMN_WIDTHS[4]);
- fTimeGraphCombo.setTimeGraphProvider(new CallStackPresentationProvider());
+ fTimeGraphCombo.setTimeGraphProvider(new CallStackPresentationProvider(this));
fTimeGraphCombo.getTimeGraphViewer().setTimeFormat(TimeFormat.CALENDAR);
fTimeGraphCombo.getTimeGraphViewer().addRangeListener(new ITimeGraphRangeListener() {
public void timeRangeUpdated(TimeGraphRangeUpdateEvent event) {
long startTime = event.getStartTime();
long endTime = event.getEndTime();
- TmfTimeRange range = new TmfTimeRange(new CtfTmfTimestamp(startTime), new CtfTmfTimestamp(endTime));
- TmfTimestamp time = new CtfTmfTimestamp(fTimeGraphCombo.getTimeGraphViewer().getSelectedTime());
- broadcast(new TmfRangeSynchSignal(CallStackView.this, range, time));
+ TmfTimeRange range = new TmfTimeRange(new TmfNanoTimestamp(startTime), new TmfNanoTimestamp(endTime));
+ broadcast(new TmfRangeSynchSignal(CallStackView.this, range));
startZoomThread(startTime, endTime);
}
});
fTimeGraphCombo.getTimeGraphViewer().addTimeListener(new ITimeGraphTimeListener() {
@Override
public void timeSelected(TimeGraphTimeEvent event) {
- long time = event.getTime();
- selectTime(time);
- broadcast(new TmfTimeSynchSignal(CallStackView.this, new CtfTmfTimestamp(time)));
+ long beginTime = event.getBeginTime();
+ long endTime = event.getEndTime();
+ selectTime(beginTime);
+ broadcast(new TmfTimeSynchSignal(CallStackView.this, new TmfNanoTimestamp(beginTime), new TmfNanoTimestamp(endTime)));
}
});
if (entry.getFunctionName().length() > 0) {
long startTime = entry.getStartTime();
long endTime = entry.getEndTime();
- long spacingTime = (long) ((endTime - startTime) * 0.01);
+ long spacingTime = (long) ((endTime - startTime) * SPACING_RATIO);
startTime -= spacingTime;
endTime += spacingTime;
- TmfTimeRange range = new TmfTimeRange(new CtfTmfTimestamp(startTime), new CtfTmfTimestamp(endTime));
- TmfTimestamp time = new CtfTmfTimestamp(fTimeGraphCombo.getTimeGraphViewer().getSelectedTime());
- broadcast(new TmfRangeSynchSignal(CallStackView.this, range, time));
+ TmfTimeRange range = new TmfTimeRange(new TmfNanoTimestamp(startTime), new TmfNanoTimestamp(endTime));
+ broadcast(new TmfRangeSynchSignal(CallStackView.this, range));
fTimeGraphCombo.getTimeGraphViewer().setStartFinishTime(startTime, endTime);
startZoomThread(startTime, endTime);
}
CallStackEvent event = (CallStackEvent) o;
long startTime = event.getTime();
long endTime = startTime + event.getDuration();
- long spacingTime = (long) ((endTime - startTime) * 0.01);
+ long spacingTime = (long) ((endTime - startTime) * SPACING_RATIO);
startTime -= spacingTime;
endTime += spacingTime;
- TmfTimeRange range = new TmfTimeRange(new CtfTmfTimestamp(startTime), new CtfTmfTimestamp(endTime));
- TmfTimestamp time = new CtfTmfTimestamp(fTimeGraphCombo.getTimeGraphViewer().getSelectedTime());
- broadcast(new TmfRangeSynchSignal(CallStackView.this, range, time));
+ TmfTimeRange range = new TmfTimeRange(new TmfNanoTimestamp(startTime), new TmfNanoTimestamp(endTime));
+ broadcast(new TmfRangeSynchSignal(CallStackView.this, range));
fTimeGraphCombo.getTimeGraphViewer().setStartFinishTime(startTime, endTime);
startZoomThread(startTime, endTime);
}
}
});
+ IStatusLineManager statusLineManager = getViewSite().getActionBars().getStatusLineManager();
+ fTimeGraphCombo.getTimeGraphViewer().getTimeGraphControl().setStatusLineManager(statusLineManager);
+
// View Action Handling
makeActions();
contributeToActionBars();
@TmfSignalHandler
public void synchToTime(final TmfTimeSynchSignal signal) {
- fSavedTimeSyncSignal = isPinned() ? new TmfTimeSynchSignal(signal.getSource(), signal.getCurrentTime()) : null;
+ fSavedTimeSyncSignal = isPinned() ? new TmfTimeSynchSignal(signal.getSource(), signal.getBeginTime(), signal.getEndTime()) : null;
if (signal.getSource() == this || fTrace == null || isPinned()) {
return;
}
- final long time = signal.getCurrentTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue();
+ final long beginTime = signal.getBeginTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue();
+ final long endTime = signal.getEndTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue();
Display.getDefault().asyncExec(new Runnable() {
@Override
public void run() {
if (fTimeGraphCombo.isDisposed()) {
return;
}
- selectTime(time);
+ if (beginTime == endTime) {
+ fTimeGraphCombo.getTimeGraphViewer().setSelectedTime(beginTime, true);
+ } else {
+ fTimeGraphCombo.getTimeGraphViewer().setSelectionRange(beginTime, endTime);
+ }
+ selectTime(beginTime);
startZoomThread(fTimeGraphCombo.getTimeGraphViewer().getTime0(), fTimeGraphCombo.getTimeGraphViewer().getTime1());
if (fEntryList == null) {
return;
}
TimeGraphViewer viewer = fTimeGraphCombo.getTimeGraphViewer();
for (ThreadEntry threadEntry : fEntryList) {
- ITmfStateSystem ss = threadEntry.getTrace().getStateSystems().get(CallStackStateProvider.ID);
- if (ss == null || time < ss.getStartTime() || time > ss.getCurrentEndTime()) {
+ ITmfStateSystem ss = threadEntry.getStateSystem();
+ if (ss == null || beginTime < ss.getStartTime() || beginTime > ss.getCurrentEndTime()) {
continue;
}
try {
int quark = ss.getQuarkRelative(threadEntry.getThreadQuark(), CallStackStateProvider.CALL_STACK);
- ITmfStateInterval stackInterval = ss.querySingleState(time, quark);
- if (time == stackInterval.getStartTime()) {
+ ITmfStateInterval stackInterval = ss.querySingleState(beginTime, quark);
+ if (beginTime == stackInterval.getStartTime()) {
int stackLevel = stackInterval.getStateValue().unboxInt();
CallStackEntry selectedEntry = threadEntry.getChildren().get(Math.max(0, stackLevel - 1));
fTimeGraphCombo.setSelection(selectedEntry);
break;
}
} catch (AttributeNotFoundException e) {
- e.printStackTrace();
+ Activator.getDefault().logError("Error querying state system", e); //$NON-NLS-1$
} catch (TimeRangeException e) {
- e.printStackTrace();
+ Activator.getDefault().logError("Error querying state system", e); //$NON-NLS-1$
} catch (StateSystemDisposedException e) {
- e.printStackTrace();
+ Activator.getDefault().logError("Error querying state system", e); //$NON-NLS-1$
} catch (StateValueTypeException e) {
- e.printStackTrace();
+ Activator.getDefault().logError("Error querying state system", e); //$NON-NLS-1$
}
}
}
if (isPinned()) {
fSavedRangeSyncSignal =
- new TmfRangeSynchSignal(signal.getSource(), new TmfTimeRange(signal.getCurrentRange().getStartTime(), signal.getCurrentRange().getEndTime()), signal.getCurrentTime());
+ new TmfRangeSynchSignal(signal.getSource(), new TmfTimeRange(signal.getCurrentRange().getStartTime(), signal.getCurrentRange().getEndTime()));
fSavedTimeSyncSignal = null;
}
}
final long startTime = signal.getCurrentRange().getStartTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue();
final long endTime = signal.getCurrentRange().getEndTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue();
- final long time = signal.getCurrentTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue();
Display.getDefault().asyncExec(new Runnable() {
@Override
public void run() {
return;
}
fTimeGraphCombo.getTimeGraphViewer().setStartFinishTime(startTime, endTime);
- fTimeGraphCombo.getTimeGraphViewer().setSelectedTime(time, false);
startZoomThread(startTime, endTime);
}
});
// ------------------------------------------------------------------------
// Internal
// ------------------------------------------------------------------------
+
private void loadTrace() {
synchronized (fEntryListMap) {
fEntryList = fEntryListMap.get(fTrace);
private void buildThreadList(final ITmfTrace trace, IProgressMonitor monitor) {
fStartTime = Long.MAX_VALUE;
fEndTime = Long.MIN_VALUE;
- ITmfTrace[] traces;
- if (trace instanceof TmfExperiment) {
- TmfExperiment experiment = (TmfExperiment) trace;
- traces = experiment.getTraces();
- } else {
- traces = new ITmfTrace[] { trace };
- }
- ArrayList<ThreadEntry> entryList = new ArrayList<ThreadEntry>();
+ ITmfTrace[] traces = TmfTraceManager.getTraceSet(trace);
+ ArrayList<ThreadEntry> entryList = new ArrayList<>();
for (ITmfTrace aTrace : traces) {
if (monitor.isCanceled()) {
return;
}
- ITmfStateSystem ss = aTrace.getStateSystems().get(CallStackStateProvider.ID);
- if (ss == null || !ss.waitUntilBuilt()) {
- String threadName = Messages.CallStackView_StackInfoNotAvailable + ' ' + '(' + aTrace.getName() + ')';
- ThreadEntry threadEntry = new ThreadEntry(aTrace, threadName, -1, 0, 0);
- entryList.add(threadEntry);
+ ITmfStateSystem ss = getCallStackStateSystem(aTrace);
+ if (ss == null) {
+ addUnavailableEntry(aTrace, entryList);
+ continue;
+ }
+ ss.waitUntilBuilt();
+ if (ss.isCancelled()) {
+ addUnavailableEntry(aTrace, entryList);
continue;
}
long startTime = ss.getStartTime();
threadEntry.addChild(callStackEntry);
}
} catch (AttributeNotFoundException e) {
- e.printStackTrace();
+ Activator.getDefault().logError("Error querying state system", e); //$NON-NLS-1$
}
}
}
synchronized (fEntryListMap) {
- fEntryListMap.put(trace, (ArrayList<ThreadEntry>) entryList.clone());
+ fEntryListMap.put(trace, new ArrayList<>(entryList));
}
if (trace == fTrace) {
refresh();
}
}
+ private void addUnavailableEntry(ITmfTrace trace, List<ThreadEntry> list) {
+ String threadName = Messages.CallStackView_StackInfoNotAvailable + ' ' + '(' + trace.getName() + ')';
+ ThreadEntry threadEntry = new ThreadEntry(trace, threadName, -1, 0, 0);
+ list.add(threadEntry);
+ }
+
private void buildStatusEvents(ITmfTrace trace, CallStackEntry entry, IProgressMonitor monitor) {
- ITmfStateSystem ss = entry.getTrace().getStateSystems().get(CallStackStateProvider.ID);
+ ITmfStateSystem ss = getCallStackStateSystem(entry.getTrace());
+ if (ss == null) {
+ return;
+ }
long start = ss.getStartTime();
long end = ss.getCurrentEndTime() + 1;
long resolution = Math.max(1, (end - start) / fDisplayWidth);
private static List<ITimeEvent> getEventList(CallStackEntry entry,
long startTime, long endTime, long resolution,
IProgressMonitor monitor) {
- ITmfStateSystem ss = entry.getTrace().getStateSystems().get(CallStackStateProvider.ID);
+ ITmfStateSystem ss = getCallStackStateSystem(entry.getTrace());
+ if (ss == null) {
+ return null;
+ }
long start = Math.max(startTime, ss.getStartTime());
long end = Math.min(endTime, ss.getCurrentEndTime() + 1);
if (end <= start) {
List<ITimeEvent> eventList = null;
try {
List<ITmfStateInterval> stackIntervals = ss.queryHistoryRange(entry.getQuark(), start, end - 1, resolution, monitor);
- eventList = new ArrayList<ITimeEvent>(stackIntervals.size());
+ eventList = new ArrayList<>(stackIntervals.size());
long lastEndTime = -1;
boolean lastIsNull = true;
for (ITmfStateInterval statusInterval : stackIntervals) {
long time = statusInterval.getStartTime();
long duration = statusInterval.getEndTime() - time + 1;
if (!statusInterval.getStateValue().isNull()) {
- final int MODULO = CallStackPresentationProvider.NUM_COLORS / 2;
- int value = statusInterval.getStateValue().toString().hashCode() % MODULO + MODULO;
+ final int modulo = CallStackPresentationProvider.NUM_COLORS / 2;
+ int value = statusInterval.getStateValue().toString().hashCode() % modulo + modulo;
eventList.add(new CallStackEvent(entry, time, duration, value));
lastIsNull = false;
} else {
- if (lastEndTime != time && lastEndTime != -1 && lastIsNull) {
- eventList.add(new TimeEvent(entry, lastEndTime, time - lastEndTime));
+ if (lastEndTime == -1) {
+ // add null event if it intersects the start time
+ eventList.add(new NullTimeEvent(entry, time, duration));
+ } else {
+ if (lastEndTime != time && lastIsNull) {
+ // add unknown event if between two null states
+ eventList.add(new TimeEvent(entry, lastEndTime, time - lastEndTime));
+ }
+ if (time + duration >= endTime) {
+ // add null event if it intersects the end time
+ eventList.add(new NullTimeEvent(entry, time, duration));
+ }
}
- eventList.add(new NullTimeEvent(entry, time, duration));
lastIsNull = true;
}
lastEndTime = time + duration;
}
} catch (AttributeNotFoundException e) {
- e.printStackTrace();
+ Activator.getDefault().logError("Error querying state system", e); //$NON-NLS-1$
} catch (TimeRangeException e) {
- e.printStackTrace();
+ Activator.getDefault().logError("Error querying state system", e); //$NON-NLS-1$
} catch (StateSystemDisposedException e) {
/* Ignored */
}
if (fEntryList == null) {
return;
}
- fTimeGraphCombo.getTimeGraphViewer().setSelectedTime(time, true);
for (ThreadEntry threadEntry : fEntryList) {
- ITmfStateSystem ss = threadEntry.fThreadTrace.getStateSystems().get(CallStackStateProvider.ID);
- if (ss == null || !ss.waitUntilBuilt()) {
+ ITmfStateSystem ss = threadEntry.getStateSystem();
+ if (ss == null) {
+ continue;
+ }
+ ss.waitUntilBuilt();
+ if (ss.isCancelled()) {
continue;
}
long queryTime = Math.max(ss.getStartTime(), Math.min(ss.getCurrentEndTime(), time));
String name = ""; //$NON-NLS-1$
try {
if (nameValue.getType() == Type.STRING) {
- name = nameValue.unboxStr();
+ String address = nameValue.unboxStr();
+ name = getFunctionName(address);
} else if (nameValue.getType() == Type.INTEGER) {
name = "0x" + Integer.toHexString(nameValue.unboxInt()); //$NON-NLS-1$
} else if (nameValue.getType() == Type.LONG) {
callStackEntry.setEndTime(stackLevelInterval.getEndTime() + 1);
}
} catch (AttributeNotFoundException e) {
- e.printStackTrace();
+ Activator.getDefault().logError("Error querying state system", e); //$NON-NLS-1$
} catch (TimeRangeException e) {
- e.printStackTrace();
+ Activator.getDefault().logError("Error querying state system", e); //$NON-NLS-1$
} catch (StateSystemDisposedException e) {
- e.printStackTrace();
+ Activator.getDefault().logError("Error querying state system", e); //$NON-NLS-1$
}
}
}
fTimeGraphCombo.refresh();
- fTimeGraphCombo.getTimeGraphViewer().setSelectedTime(time, true);
}
private void refresh() {
synchronized (fEntryListMap) {
fEntryList = fEntryListMap.get(fTrace);
if (fEntryList == null) {
- fEntryList = new ArrayList<ThreadEntry>();
+ fEntryList = new ArrayList<>();
}
entries = fEntryList.toArray(new ITimeGraphEntry[0]);
}
fTimeGraphCombo.setInput(entries);
fTimeGraphCombo.getTimeGraphViewer().setTimeBounds(fStartTime, fEndTime);
- long timestamp = fTrace == null ? 0 : fTraceManager.getCurrentTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue();
+ long selectionBeginTime = fTrace == null ? 0 : fTraceManager.getSelectionBeginTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue();
+ long selectionEndTime = fTrace == null ? 0 : fTraceManager.getSelectionEndTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue();
long startTime = fTrace == null ? 0 : fTraceManager.getCurrentRange().getStartTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue();
long endTime = fTrace == null ? 0 : fTraceManager.getCurrentRange().getEndTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue();
startTime = Math.max(startTime, fStartTime);
endTime = Math.min(endTime, fEndTime);
- selectTime(timestamp);
+ fTimeGraphCombo.getTimeGraphViewer().setSelectionRange(selectionBeginTime, selectionEndTime);
+ selectTime(selectionBeginTime);
fTimeGraphCombo.getTimeGraphViewer().setStartFinishTime(startTime, endTime);
startZoomThread(startTime, endTime);
}
fPinAction.addPropertyChangeListener(new IPropertyChangeListener(){
@Override
public void propertyChange(PropertyChangeEvent event) {
- if (IAction.CHECKED.equals(event.getProperty())) {
- if (!isPinned()) {
- if (fSavedRangeSyncSignal != null) {
- synchToRange(fSavedRangeSyncSignal);
- fSavedRangeSyncSignal = null;
- }
+ if (IAction.CHECKED.equals(event.getProperty()) && !isPinned()) {
+ if (fSavedRangeSyncSignal != null) {
+ synchToRange(fSavedRangeSyncSignal);
+ fSavedRangeSyncSignal = null;
+ }
- if (fSavedTimeSyncSignal != null) {
- synchToTime(fSavedTimeSyncSignal);
- fSavedTimeSyncSignal = null;
- }
+ if (fSavedTimeSyncSignal != null) {
+ synchToTime(fSavedTimeSyncSignal);
+ fSavedTimeSyncSignal = null;
}
}
}
}
private void fillLocalToolBar(IToolBarManager manager) {
+ manager.add(getImportMappingAction());
manager.add(fTimeGraphCombo.getTimeGraphViewer().getResetScaleAction());
manager.add(getPreviousEventAction());
manager.add(getNextEventAction());
try {
CallStackEntry callStackEntry = (CallStackEntry) entry;
ITmfTrace trace = callStackEntry.getTrace();
- ITmfStateSystem ss = trace.getStateSystems().get(CallStackStateProvider.ID);
- long time = Math.max(ss.getStartTime(), Math.min(ss.getCurrentEndTime(), viewer.getSelectedTime()));
+ ITmfStateSystem ss = getCallStackStateSystem(trace);
+ if (ss == null) {
+ return;
+ }
+ long time = Math.max(ss.getStartTime(), Math.min(ss.getCurrentEndTime(), viewer.getSelectionBegin()));
ThreadEntry threadEntry = (ThreadEntry) callStackEntry.getParent();
int quark = ss.getQuarkRelative(threadEntry.getThreadQuark(), CallStackStateProvider.CALL_STACK);
ITmfStateInterval stackInterval = ss.querySingleState(time, quark);
fTimeGraphCombo.setSelection(selectedEntry);
viewer.getTimeGraphControl().fireSelectionChanged();
startZoomThread(viewer.getTime0(), viewer.getTime1());
+
} catch (AttributeNotFoundException e) {
- e.printStackTrace();
+ Activator.getDefault().logError("Error querying state system", e); //$NON-NLS-1$
} catch (TimeRangeException e) {
- e.printStackTrace();
+ Activator.getDefault().logError("Error querying state system", e); //$NON-NLS-1$
} catch (StateSystemDisposedException e) {
- e.printStackTrace();
+ Activator.getDefault().logError("Error querying state system", e); //$NON-NLS-1$
} catch (StateValueTypeException e) {
- e.printStackTrace();
+ Activator.getDefault().logError("Error querying state system", e); //$NON-NLS-1$
}
}
}
try {
CallStackEntry callStackEntry = (CallStackEntry) entry;
ITmfTrace trace = callStackEntry.getTrace();
- ITmfStateSystem ss = trace.getStateSystems().get(CallStackStateProvider.ID);
- long time = Math.max(ss.getStartTime(), Math.min(ss.getCurrentEndTime(), viewer.getSelectedTime()));
+ ITmfStateSystem ss = getCallStackStateSystem(trace);
+ if (ss == null) {
+ return;
+ }
+ long time = Math.max(ss.getStartTime(), Math.min(ss.getCurrentEndTime(), viewer.getSelectionBegin()));
ThreadEntry threadEntry = (ThreadEntry) callStackEntry.getParent();
int quark = ss.getQuarkRelative(threadEntry.getThreadQuark(), CallStackStateProvider.CALL_STACK);
ITmfStateInterval stackInterval = ss.querySingleState(time, quark);
fTimeGraphCombo.setSelection(selectedEntry);
viewer.getTimeGraphControl().fireSelectionChanged();
startZoomThread(viewer.getTime0(), viewer.getTime1());
+
} catch (AttributeNotFoundException e) {
- e.printStackTrace();
+ Activator.getDefault().logError("Error querying state system", e); //$NON-NLS-1$
} catch (TimeRangeException e) {
- e.printStackTrace();
+ Activator.getDefault().logError("Error querying state system", e); //$NON-NLS-1$
} catch (StateSystemDisposedException e) {
- e.printStackTrace();
+ Activator.getDefault().logError("Error querying state system", e); //$NON-NLS-1$
} catch (StateValueTypeException e) {
- e.printStackTrace();
+ Activator.getDefault().logError("Error querying state system", e); //$NON-NLS-1$
}
}
}
return fPrevEventAction;
}
+ @Nullable
+ static ITmfStateSystem getCallStackStateSystem(ITmfTrace trace) {
+ /*
+ * Since we cannot know the exact analysis ID (in separate plugins), we
+ * will search using the analysis type.
+ */
+ Iterable<AbstractCallStackAnalysis> modules =
+ trace.getAnalysisModulesOfClass(AbstractCallStackAnalysis.class);
+ Iterator<AbstractCallStackAnalysis> it = modules.iterator();
+ if (!it.hasNext()) {
+ /* This trace does not provide a call-stack analysis */
+ return null;
+ }
+
+ /*
+ * We only look at the first module we find.
+ *
+ * TODO Handle the advanced case where one trace provides more than one
+ * call-stack analysis.
+ */
+ AbstractCallStackAnalysis module = it.next();
+ /* This analysis is not automatic, we need to schedule it on-demand */
+ module.schedule();
+ module.waitForInitialization();
+ ITmfStateSystem ss = module.getStateSystem();
+ if (ss == null) {
+ /* If we've waited for initialization, 'ss' should not be null */
+ throw new IllegalStateException();
+ }
+ return ss;
+ }
+
+ // ------------------------------------------------------------------------
+ // Methods related to function name mapping
+ // ------------------------------------------------------------------------
+
+ /**
+ * Toolbar icon to import the function address-to-name mapping file.
+ */
+ private Action getImportMappingAction() {
+ if (fImportMappingAction != null) {
+ return fImportMappingAction;
+ }
+ fImportMappingAction = new Action() {
+ @Override
+ public void run() {
+ FileDialog dialog = new FileDialog(getViewSite().getShell());
+ dialog.setText(Messages.CallStackView_ImportMappingDialogTitle);
+ String filePath = dialog.open();
+ if (filePath == null) {
+ /* No file was selected, don't change anything */
+ return;
+ }
+ /*
+ * Start the mapping import in a separate thread (we do not want
+ * to UI thread to do this).
+ */
+ Job job = new ImportMappingJob(new File(filePath));
+ job.schedule();
+ }
+ };
+
+ fImportMappingAction.setText(Messages.CallStackView_ImportMappingButtonText);
+ fImportMappingAction.setToolTipText(Messages.CallStackView_ImportMappingButtonTooltip);
+ fImportMappingAction.setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(IMPORT_MAPPING_ICON_PATH));
+
+ return fImportMappingAction;
+ }
+
+ private class ImportMappingJob extends Job {
+ private final File fMappingFile;
+
+ public ImportMappingJob(File mappingFile) {
+ super(Messages.CallStackView_ImportMappingJobName);
+ fMappingFile = mappingFile;
+ }
+
+ @Override
+ public IStatus run(IProgressMonitor monitor) {
+ fNameMapping = FunctionNameMapper.mapFromNmTextFile(fMappingFile);
+
+ /* Refresh the time graph and the list of entries */
+ buildThreadList(fTrace, new NullProgressMonitor());
+ redraw();
+
+ return Status.OK_STATUS;
+ }
+ }
+
+ String getFunctionName(String address) {
+ if (fNameMapping == null) {
+ /* No mapping available, just print the addresses */
+ return address;
+ }
+ String ret = fNameMapping.get(address);
+ if (ret == null) {
+ /* We didn't find this address in the mapping file, just use the address */
+ return address;
+ }
+ return ret;
+ }
+
}