tmf: Introduce the notion of PID to the Callstack analysis
[deliverable/tracecompass.git] / tmf / org.eclipse.tracecompass.tmf.ui / src / org / eclipse / tracecompass / tmf / ui / views / callstack / CallStackView.java
index cbf738f5931b23d0933224c33a41871b2ad2ae03..229f8746d8aa4ced72e9afaa537336c907ece74f 100644 (file)
@@ -14,7 +14,6 @@
 
 package org.eclipse.tracecompass.tmf.ui.views.callstack;
 
-import java.io.File;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Comparator;
@@ -24,17 +23,15 @@ 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.Status;
-import org.eclipse.core.runtime.jobs.Job;
 import org.eclipse.jdt.annotation.NonNull;
 import org.eclipse.jdt.annotation.Nullable;
 import org.eclipse.jface.action.Action;
 import org.eclipse.jface.action.GroupMarker;
 import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.action.IMenuManager;
 import org.eclipse.jface.action.IToolBarManager;
-import org.eclipse.jface.action.MenuManager;
 import org.eclipse.jface.action.Separator;
+import org.eclipse.jface.dialogs.IDialogConstants;
 import org.eclipse.jface.dialogs.IDialogSettings;
 import org.eclipse.jface.resource.ImageDescriptor;
 import org.eclipse.jface.util.IPropertyChangeListener;
@@ -43,17 +40,12 @@ import org.eclipse.jface.viewers.DoubleClickEvent;
 import org.eclipse.jface.viewers.IDoubleClickListener;
 import org.eclipse.jface.viewers.ISelection;
 import org.eclipse.jface.viewers.IStructuredSelection;
-import org.eclipse.jface.viewers.TreeViewer;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.events.MouseAdapter;
 import org.eclipse.swt.events.MouseEvent;
 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.swt.widgets.Menu;
-import org.eclipse.swt.widgets.Tree;
-import org.eclipse.tracecompass.internal.tmf.core.callstack.FunctionNameMapper;
 import org.eclipse.tracecompass.internal.tmf.ui.Activator;
 import org.eclipse.tracecompass.internal.tmf.ui.ITmfImageConstants;
 import org.eclipse.tracecompass.internal.tmf.ui.Messages;
@@ -68,16 +60,20 @@ import org.eclipse.tracecompass.statesystem.core.statevalue.ITmfStateValue;
 import org.eclipse.tracecompass.statesystem.core.statevalue.ITmfStateValue.Type;
 import org.eclipse.tracecompass.tmf.core.signal.TmfSelectionRangeUpdatedSignal;
 import org.eclipse.tracecompass.tmf.core.signal.TmfSignalHandler;
+import org.eclipse.tracecompass.tmf.core.signal.TmfTraceClosedSignal;
 import org.eclipse.tracecompass.tmf.core.signal.TmfTraceSelectedSignal;
 import org.eclipse.tracecompass.tmf.core.signal.TmfWindowRangeUpdatedSignal;
 import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp;
-import org.eclipse.tracecompass.tmf.core.timestamp.TmfNanoTimestamp;
 import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimeRange;
-import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp;
 import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestampDelta;
+import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp;
 import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
 import org.eclipse.tracecompass.tmf.core.trace.TmfTraceUtils;
 import org.eclipse.tracecompass.tmf.ui.editors.ITmfTraceEditor;
+import org.eclipse.tracecompass.tmf.ui.symbols.ISymbolProvider;
+import org.eclipse.tracecompass.tmf.ui.symbols.ISymbolProviderPreferencePage;
+import org.eclipse.tracecompass.tmf.ui.symbols.SymbolProviderConfigDialog;
+import org.eclipse.tracecompass.tmf.ui.symbols.SymbolProviderManager;
 import org.eclipse.tracecompass.tmf.ui.views.timegraph.AbstractTimeGraphView;
 import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.ITimeGraphTimeListener;
 import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.TimeGraphContentProvider;
@@ -128,7 +124,6 @@ public class CallStackView extends AbstractTimeGraphView {
     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$
     private static final String IMPORT_BINARY_ICON_PATH = "icons/obj16/binaries_obj.gif"; //$NON-NLS-1$
 
     private static final ImageDescriptor SORT_BY_NAME_ICON = Activator.getDefault().getImageDescripterFromPath("icons/etool16/sort_alpha.gif"); //$NON-NLS-1$
@@ -153,8 +148,7 @@ public class CallStackView extends AbstractTimeGraphView {
     // Fields
     // ------------------------------------------------------------------------
 
-    /** The map to map function addresses to function names */
-    private Map<String, String> fNameMapping;
+    private final Map<ITmfTrace, ISymbolProvider> fSymbolProviders = new HashMap<>();
 
     // The next event action
     private Action fNextEventAction;
@@ -168,11 +162,8 @@ public class CallStackView extends AbstractTimeGraphView {
     // The previous item action
     private Action fPreviousItemAction;
 
-    // The action to import a function-name mapping file
-    private Action fImportMappingAction;
-
     // The action to import a binary file mapping */
-    private Action fImportBinaryFileMappingAction;
+    private Action fConfigureSymbolsAction;
 
     // The saved time sync. signal used when switching off the pinning of a view
     private TmfSelectionRangeUpdatedSignal fSavedTimeSyncSignal;
@@ -196,6 +187,18 @@ public class CallStackView extends AbstractTimeGraphView {
         }
     }
 
+    private static class ProcessEntry extends TimeGraphEntry {
+
+        public ProcessEntry(String name, long startTime, long endTime) {
+            super(name, startTime, endTime);
+        }
+
+        @Override
+        public boolean hasTimeEvents() {
+            return false;
+        }
+    }
+
     private static class ThreadEntry extends TimeGraphEntry {
         // The call stack quark
         private final int fCallStackQuark;
@@ -311,10 +314,10 @@ public class CallStackView extends AbstractTimeGraphView {
                     int depth = entry.getStackLevel();
                     return Integer.toString(depth);
                 } else if (columnIndex == 2 && entry.getFunctionName().length() > 0) {
-                    ITmfTimestamp ts = new TmfTimestamp(entry.getFunctionEntryTime(), ITmfTimestamp.NANOSECOND_SCALE);
+                    ITmfTimestamp ts = TmfTimestamp.fromNanos(entry.getFunctionEntryTime());
                     return ts.toString();
                 } else if (columnIndex == 3 && entry.getFunctionName().length() > 0) {
-                    ITmfTimestamp ts = new TmfTimestamp(entry.getFunctionExitTime(), ITmfTimestamp.NANOSECOND_SCALE);
+                    ITmfTimestamp ts = TmfTimestamp.fromNanos(entry.getFunctionExitTime());
                     return ts.toString();
                 } else if (columnIndex == 4 && entry.getFunctionName().length() > 0) {
                     ITmfTimestamp ts = new TmfTimestampDelta(entry.getFunctionExitTime() - entry.getFunctionEntryTime(), ITmfTimestamp.NANOSECOND_SCALE);
@@ -393,7 +396,7 @@ public class CallStackView extends AbstractTimeGraphView {
                         long spacingTime = (long) ((exitTime - entryTime) * SPACING_RATIO);
                         entryTime -= spacingTime;
                         exitTime += spacingTime;
-                        TmfTimeRange range = new TmfTimeRange(new TmfNanoTimestamp(entryTime), new TmfNanoTimestamp(exitTime));
+                        TmfTimeRange range = new TmfTimeRange(TmfTimestamp.fromNanos(entryTime), TmfTimestamp.fromNanos(exitTime));
                         broadcast(new TmfWindowRangeUpdatedSignal(CallStackView.this, range));
                         getTimeGraphViewer().setStartFinishTime(entryTime, exitTime);
                         startZoomThread(entryTime, exitTime);
@@ -416,7 +419,7 @@ public class CallStackView extends AbstractTimeGraphView {
                         long spacingTime = (long) ((endTime - startTime) * SPACING_RATIO);
                         startTime -= spacingTime;
                         endTime += spacingTime;
-                        TmfTimeRange range = new TmfTimeRange(new TmfNanoTimestamp(startTime), new TmfNanoTimestamp(endTime));
+                        TmfTimeRange range = new TmfTimeRange(TmfTimestamp.fromNanos(startTime), TmfTimestamp.fromNanos(endTime));
                         broadcast(new TmfWindowRangeUpdatedSignal(CallStackView.this, range));
                         getTimeGraphViewer().setStartFinishTime(startTime, endTime);
                         startZoomThread(startTime, endTime);
@@ -426,7 +429,6 @@ public class CallStackView extends AbstractTimeGraphView {
         });
 
         contributeToActionBars();
-        createContextMenu();
         loadSortOption();
 
         IEditorPart editor = getSite().getPage().getActiveEditor();
@@ -469,35 +471,56 @@ public class CallStackView extends AbstractTimeGraphView {
                 }
                 synchingToTime(beginTime);
                 startZoomThread(getTimeGraphViewer().getTime0(), getTimeGraphViewer().getTime1());
-                List<TimeGraphEntry> entryList = getEntryList(getTrace());
-                if (entryList == null) {
+                List<TimeGraphEntry> traceEntries = getEntryList(getTrace());
+                if (traceEntries == null) {
                     return;
                 }
                 TimeGraphViewer viewer = getTimeGraphViewer();
-                for (TimeGraphEntry traceEntry : entryList) {
-                    for (ITimeGraphEntry child : traceEntry.getChildren()) {
-                        ThreadEntry threadEntry = (ThreadEntry) child;
-                        ITmfStateSystem ss = threadEntry.getStateSystem();
-                        if (ss == null || beginTime < ss.getStartTime() || beginTime > ss.getCurrentEndTime()) {
-                            continue;
-                        }
-                        try {
-                            int quark = threadEntry.getCallStackQuark();
-                            ITmfStateInterval stackInterval = ss.querySingleState(beginTime, quark);
-                            if (beginTime == stackInterval.getStartTime()) {
-                                int stackLevel = stackInterval.getStateValue().unboxInt();
-                                ITimeGraphEntry selectedEntry = threadEntry.getChildren().get(Math.max(0, stackLevel - 1));
-                                getTimeGraphCombo().setSelection(selectedEntry);
-                                viewer.getTimeGraphControl().fireSelectionChanged();
-                                break;
+                for (TimeGraphEntry traceEntry : traceEntries) {
+                    for (ITimeGraphEntry processEntry : traceEntry.getChildren()) {
+                        for (ITimeGraphEntry aThreadEntry : processEntry.getChildren()) {
+                            ThreadEntry threadEntry = (ThreadEntry) aThreadEntry;
+                            ITmfStateSystem ss = threadEntry.getStateSystem();
+                            if (ss == null || beginTime < ss.getStartTime() || beginTime > ss.getCurrentEndTime()) {
+                                continue;
+                            }
+                            try {
+                                int quark = threadEntry.getCallStackQuark();
+                                ITmfStateInterval stackInterval = ss.querySingleState(beginTime, quark);
+                                if (beginTime == stackInterval.getStartTime()) {
+                                    int stackLevel = stackInterval.getStateValue().unboxInt();
+                                    ITimeGraphEntry selectedEntry = threadEntry.getChildren().get(Math.max(0, stackLevel - 1));
+                                    getTimeGraphCombo().setSelection(selectedEntry);
+                                    viewer.getTimeGraphControl().fireSelectionChanged();
+                                    break;
+                                }
+                            } catch (AttributeNotFoundException | TimeRangeException | StateSystemDisposedException | StateValueTypeException e) {
+                                Activator.getDefault().logError("Error querying state system", e); //$NON-NLS-1$
                             }
-                        } catch (AttributeNotFoundException | TimeRangeException | StateSystemDisposedException | StateValueTypeException e) {
-                            Activator.getDefault().logError("Error querying state system", e); //$NON-NLS-1$
                         }
                     }
                 }
             }
         });
+
+    }
+
+    /**
+     * @since 2.0
+     */
+    @Override
+    @TmfSignalHandler
+    public void windowRangeUpdated(final TmfWindowRangeUpdatedSignal signal) {
+
+        if (isPinned()) {
+            fSavedRangeSyncSignal = new TmfWindowRangeUpdatedSignal(signal.getSource(), signal.getCurrentRange());
+            fSavedTimeSyncSignal = null;
+        }
+
+        if ((signal.getSource() == this) || isPinned()) {
+            return;
+        }
+        super.windowRangeUpdated(signal);
     }
 
     // ------------------------------------------------------------------------
@@ -505,7 +528,27 @@ public class CallStackView extends AbstractTimeGraphView {
     // ------------------------------------------------------------------------
 
     @Override
-    protected void buildEventList(final ITmfTrace trace, final ITmfTrace parentTrace, final IProgressMonitor monitor) {
+    @TmfSignalHandler
+    public void traceClosed(TmfTraceClosedSignal signal) {
+        super.traceClosed(signal);
+        synchronized(fSymbolProviders){
+            for(ITmfTrace trace : getTracesToBuild(signal.getTrace())){
+                fSymbolProviders.remove(trace);
+            }
+        }
+    }
+
+    /**
+     * @since 2.0
+     */
+    @Override
+    protected void refresh() {
+        super.refresh();
+        updateConfigureSymbolsAction();
+    }
+
+    @Override
+    protected void buildEntryList(final ITmfTrace trace, final ITmfTrace parentTrace, final IProgressMonitor monitor) {
         if (monitor.isCanceled()) {
             return;
         }
@@ -521,8 +564,8 @@ public class CallStackView extends AbstractTimeGraphView {
         }
 
         Map<ITmfTrace, TraceEntry> traceEntryMap = new HashMap<>();
+        Map<Integer, ProcessEntry> processEntryMap = new HashMap<>();
         Map<Integer, ThreadEntry> threadEntryMap = new HashMap<>();
-        String[] threadPaths = module.getThreadsPattern();
 
         long start = ss.getStartTime();
 
@@ -539,7 +582,17 @@ public class CallStackView extends AbstractTimeGraphView {
             if (start == end && !complete) { // when complete execute one last time regardless of end time
                 continue;
             }
-            List<Integer> threadQuarks = ss.getQuarks(threadPaths);
+
+            ISymbolProvider provider = fSymbolProviders.get(trace);
+            if (provider == null) {
+                provider = SymbolProviderManager.getInstance().getSymbolProvider(trace);
+                provider.loadConfiguration(monitor);
+                fSymbolProviders.put(trace, provider);
+            }
+
+            getConfigureSymbolsAction().setEnabled(true);
+
+
             TraceEntry traceEntry = traceEntryMap.get(trace);
             if (traceEntry == null) {
                 traceEntry = new TraceEntry(trace.getName(), start, end + 1);
@@ -549,41 +602,69 @@ public class CallStackView extends AbstractTimeGraphView {
             } else {
                 traceEntry.updateEndTime(end);
             }
-            for (int i = 0; i < threadQuarks.size(); i++) {
-                if (monitor.isCanceled()) {
-                    return;
-                }
-                int threadQuark = threadQuarks.get(i);
+
+            List<Integer> processQuarks = ss.getQuarks(module.getProcessesPattern());
+            for (Integer processQuark : processQuarks) {
+
+                /* Create the entry for the process */
+                ProcessEntry processEntry = processEntryMap.get(processQuark);
+                if (processEntry == null) {
+                    String name = ss.getAttributeName(processQuark.intValue());
+                    processEntry = new ProcessEntry(name, start, end);
+                    processEntryMap.put(processQuark, processEntry);
+                    traceEntry.addChild(processEntry);
+                } else {
+                    processEntry.updateEndTime(end);
+                  }
+
+                /* Create the threads under the process */
                 try {
-                    String[] callStackPath = module.getCallStackPath();
-                    int callStackQuark = ss.getQuarkRelative(threadQuark, callStackPath);
-                    String threadName = ss.getAttributeName(threadQuark);
-                    long threadEnd = end + 1;
-                    ITmfStateInterval endInterval = ss.querySingleState(ss.getCurrentEndTime(), callStackQuark);
-                    if (endInterval.getStateValue().isNull() && endInterval.getStartTime() != ss.getStartTime()) {
-                        threadEnd = endInterval.getStartTime();
-                    }
-                    ThreadEntry threadEntry = threadEntryMap.get(threadQuark);
-                    if (threadEntry == null) {
-                        long threadId = ss.querySingleState(ss.getCurrentEndTime(), threadQuark).getStateValue().unboxLong();
-                        long threadStart = start;
-                        ITmfStateInterval startInterval = ss.querySingleState(start, callStackQuark);
-                        if (startInterval.getStateValue().isNull()) {
-                            threadStart = Math.min(startInterval.getEndTime() + 1, end + 1);
+                    List<Integer> threadQuarks = ss.getSubAttributes(processQuark, false, module.getThreadsForProcessPattern());
+
+                    /*
+                     * Only query startStates if necessary (threadEntry == null)
+                     */
+                    List<ITmfStateInterval> startStates = null;
+                    List<ITmfStateInterval> endStates = ss.queryFullState(ss.getCurrentEndTime());
+                    for (int i = 0; i < threadQuarks.size(); i++) {
+                        if (monitor.isCanceled()) {
+                            return;
                         }
-                        threadEntry = new ThreadEntry(ss, threadName, threadId, callStackQuark, threadStart, threadEnd);
-                        threadEntryMap.put(threadQuark, threadEntry);
-                        traceEntry.addChild(threadEntry);
-                    } else {
-                        threadEntry.updateEndTime(threadEnd);
-                    }
-                    int level = 1;
-                    for (int stackLevelQuark : ss.getSubAttributes(callStackQuark, false)) {
-                        if (level > threadEntry.getChildren().size()) {
-                            CallStackEntry callStackEntry = new CallStackEntry(threadName, stackLevelQuark, level, trace, ss);
-                            threadEntry.addChild(callStackEntry);
+                        int threadQuark = threadQuarks.get(i);
+
+                        String[] callStackPath = module.getCallStackPathForThread();
+                        int callStackQuark = ss.getQuarkRelative(threadQuark, callStackPath);
+                        String threadName = ss.getAttributeName(threadQuark);
+                        long threadEnd = end + 1;
+                        ITmfStateInterval endInterval = endStates.get(callStackQuark);
+                        if (endInterval.getStateValue().isNull() && endInterval.getStartTime() != ss.getStartTime()) {
+                            threadEnd = endInterval.getStartTime();
+                        }
+                        ThreadEntry threadEntry = threadEntryMap.get(threadQuark);
+                        if (threadEntry == null) {
+                            if (startStates == null) {
+                                startStates = ss.queryFullState(ss.getStartTime());
+                            }
+                            long threadId = endInterval.getStateValue().unboxLong();
+                            long threadStart = start;
+                            ITmfStateInterval startInterval = startStates.get(callStackQuark);
+                            if (startInterval.getStateValue().isNull()) {
+                                threadStart = Math.min(startInterval.getEndTime() + 1, end + 1);
+                            }
+                            threadEntry = new ThreadEntry(ss, threadName, threadId, callStackQuark, threadStart, threadEnd);
+                            threadEntryMap.put(threadQuark, threadEntry);
+                            processEntry.addChild(threadEntry);
+                        } else {
+                            threadEntry.updateEndTime(threadEnd);
+                        }
+                        int level = 1;
+                        for (int stackLevelQuark : ss.getSubAttributes(callStackQuark, false)) {
+                            if (level > threadEntry.getChildren().size()) {
+                                CallStackEntry callStackEntry = new CallStackEntry(threadName, stackLevelQuark, level, trace, ss);
+                                threadEntry.addChild(callStackEntry);
+                            }
+                            level++;
                         }
-                        level++;
                     }
                 } catch (AttributeNotFoundException e) {
                     Activator.getDefault().logError("Error querying state system", e); //$NON-NLS-1$
@@ -591,6 +672,7 @@ public class CallStackView extends AbstractTimeGraphView {
                     /* Ignored */
                 }
             }
+
             if (parentTrace == getTrace()) {
                 synchronized (this) {
                     setStartTime(getStartTime() == SWT.DEFAULT ? start : Math.min(getStartTime(), start));
@@ -599,12 +681,15 @@ public class CallStackView extends AbstractTimeGraphView {
                 synchingToTime(getTimeGraphViewer().getSelectionBegin());
                 refresh();
             }
-            for (ITimeGraphEntry threadEntry : traceEntry.getChildren()) {
-                for (ITimeGraphEntry callStackEntry : threadEntry.getChildren()) {
-                    if (monitor.isCanceled()) {
-                        return;
+
+            for (ITimeGraphEntry processEntry : traceEntry.getChildren()) {
+                for (ITimeGraphEntry threadEntry : processEntry.getChildren()) {
+                    for (ITimeGraphEntry callStackEntry : threadEntry.getChildren()) {
+                        if (monitor.isCanceled()) {
+                            return;
+                        }
+                        buildStatusEvents(parentTrace, (CallStackEntry) callStackEntry, monitor, ss.getStartTime(), end);
                     }
-                    buildStatusEvents(parentTrace, (CallStackEntry) callStackEntry, monitor, start, end);
                 }
             }
             start = end;
@@ -625,9 +710,7 @@ public class CallStackView extends AbstractTimeGraphView {
         long resolution = Math.max(1, (end - ss.getStartTime()) / getDisplayWidth());
         List<ITimeEvent> eventList = getEventList(entry, start, end + 1, resolution, monitor);
         if (eventList != null) {
-            for (ITimeEvent event : eventList) {
-                entry.addEvent(event);
-            }
+            entry.setEventList(eventList);
         }
         if (trace == getTrace()) {
             redraw();
@@ -649,6 +732,7 @@ public class CallStackView extends AbstractTimeGraphView {
         if (end <= start) {
             return null;
         }
+        boolean isZoomThread = Thread.currentThread() instanceof ZoomThread;
         List<ITimeEvent> eventList = null;
         try {
             List<ITmfStateInterval> stackIntervals = StateSystemUtils.queryHistoryRange(ss, entry.getQuark(), start, end - 1, resolution, monitor);
@@ -667,7 +751,7 @@ public class CallStackView extends AbstractTimeGraphView {
                     eventList.add(new CallStackEvent(entry, time, duration, value));
                     lastIsNull = false;
                 } else {
-                    if (lastEndTime == -1) {
+                    if (lastEndTime == -1 && isZoomThread) {
                         // add null event if it intersects the start time
                         eventList.add(new NullTimeEvent(entry, time, duration));
                     } else {
@@ -675,7 +759,7 @@ public class CallStackView extends AbstractTimeGraphView {
                             // add unknown event if between two null states
                             eventList.add(new TimeEvent(entry, lastEndTime, time - lastEndTime));
                         }
-                        if (time + duration >= endTime) {
+                        if (time + duration >= endTime && isZoomThread) {
                             // add null event if it intersects the end time
                             eventList.add(new NullTimeEvent(entry, time, duration));
                         }
@@ -704,43 +788,35 @@ public class CallStackView extends AbstractTimeGraphView {
             return;
         }
         for (TimeGraphEntry traceEntry : entryList) {
-            for (ITimeGraphEntry threadEntry : traceEntry.getChildren()) {
-                ITmfStateSystem ss = ((ThreadEntry) threadEntry).getStateSystem();
-                if (ss == null) {
-                    continue;
-                }
-                if (ss.isCancelled()) {
-                    continue;
-                }
-                if (time < ss.getStartTime() || time > ss.getCurrentEndTime()) {
-                    continue;
-                }
-                for (ITimeGraphEntry child : threadEntry.getChildren()) {
-                    CallStackEntry callStackEntry = (CallStackEntry) child;
-                    try {
-                        ITmfStateInterval stackLevelInterval = ss.querySingleState(time, callStackEntry.getQuark());
-                        ITmfStateValue nameValue = stackLevelInterval.getStateValue();
-                        String name = ""; //$NON-NLS-1$
+            for (ITimeGraphEntry processEntry : traceEntry.getChildren()) {
+                for (ITimeGraphEntry threadEntry : processEntry.getChildren()) {
+                    ITmfStateSystem ss = ((ThreadEntry) threadEntry).getStateSystem();
+                    if (ss == null) {
+                        continue;
+                    }
+                    if (ss.isCancelled()) {
+                        continue;
+                    }
+                    if (time < ss.getStartTime() || time > ss.getCurrentEndTime()) {
+                        continue;
+                    }
+                    for (ITimeGraphEntry child : threadEntry.getChildren()) {
+                        CallStackEntry callStackEntry = (CallStackEntry) child;
+                        ITmfTrace trace = callStackEntry.getTrace();
                         try {
-                            if (nameValue.getType() == Type.STRING) {
-                                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) {
-                                name = "0x" + Long.toHexString(nameValue.unboxLong()); //$NON-NLS-1$
+                            ITmfStateInterval stackLevelInterval = ss.querySingleState(time, callStackEntry.getQuark());
+                            ITmfStateValue nameValue = stackLevelInterval.getStateValue();
+                            String name = getFunctionName(trace, nameValue);
+                            callStackEntry.setFunctionName(name);
+                            if (name.length() > 0) {
+                                callStackEntry.setFunctionEntryTime(stackLevelInterval.getStartTime());
+                                callStackEntry.setFunctionExitTime(stackLevelInterval.getEndTime() + 1);
                             }
-                        } catch (StateValueTypeException e) {
-                        }
-                        callStackEntry.setFunctionName(name);
-                        if (name.length() > 0) {
-                            callStackEntry.setFunctionEntryTime(stackLevelInterval.getStartTime());
-                            callStackEntry.setFunctionExitTime(stackLevelInterval.getEndTime() + 1);
+                        } catch (AttributeNotFoundException e) {
+                            Activator.getDefault().logError("Error querying state system", e); //$NON-NLS-1$
+                        } catch (StateSystemDisposedException e) {
+                            /* Ignored */
                         }
-                    } catch (AttributeNotFoundException e) {
-                        Activator.getDefault().logError("Error querying state system", e); //$NON-NLS-1$
-                    } catch (StateSystemDisposedException e) {
-                        /* Ignored */
                     }
                 }
             }
@@ -750,6 +826,38 @@ public class CallStackView extends AbstractTimeGraphView {
         }
     }
 
+    String getFunctionName(ITmfTrace trace, ITmfStateValue nameValue) {
+        long address = Long.MAX_VALUE;
+        String name = ""; //$NON-NLS-1$
+        try {
+            if (nameValue.getType() == Type.STRING) {
+                name = nameValue.unboxStr();
+                try {
+                    address = Long.parseLong(name, 16);
+                } catch (NumberFormatException e) {
+                    // ignore
+                }
+            } else if (nameValue.getType() == Type.INTEGER) {
+                name = "0x" + Integer.toHexString(nameValue.unboxInt()); //$NON-NLS-1$
+                address = nameValue.unboxInt();
+            } else if (nameValue.getType() == Type.LONG) {
+                name = "0x" + Long.toHexString(nameValue.unboxLong()); //$NON-NLS-1$
+                address = nameValue.unboxLong();
+            }
+        } catch (StateValueTypeException e) {
+        }
+        if (address != Long.MAX_VALUE) {
+            ISymbolProvider provider = fSymbolProviders.get(trace);
+            if (provider != null) {
+                String symbol = provider.getSymbolText(address);
+                if (symbol != null) {
+                    name = symbol;
+                }
+            }
+        }
+        return name;
+    }
+
     private void makeActions() {
         fPreviousItemAction = getTimeGraphViewer().getPreviousItemAction();
         fPreviousItemAction.setText(Messages.TmfTimeGraphViewer_PreviousItemActionNameText);
@@ -786,8 +894,7 @@ public class CallStackView extends AbstractTimeGraphView {
     @Override
     protected void fillLocalToolBar(IToolBarManager manager) {
         makeActions();
-        manager.add(getImportBinaryAction());
-        manager.add(getImportMappingAction());
+        manager.add(getConfigureSymbolsAction());
         manager.add(new Separator());
         manager.add(getSortByNameAction());
         manager.add(getSortByIdAction());
@@ -809,19 +916,15 @@ public class CallStackView extends AbstractTimeGraphView {
         manager.add(getTimeGraphViewer().getZoomOutAction());
     }
 
-    private void createContextMenu() {
-        final MenuManager contextMenu = new MenuManager();
+    /**
+     * @since 2.0
+     */
+    @Override
+    protected void fillTimeGraphEntryContextMenu(IMenuManager contextMenu) {
         contextMenu.add(new GroupMarker(IWorkbenchActionConstants.GROUP_REORGANIZE));
         contextMenu.add(getSortByNameAction());
         contextMenu.add(getSortByIdAction());
         contextMenu.add(getSortByTimeAction());
-        contextMenu.add(new GroupMarker(IWorkbenchActionConstants.MB_ADDITIONS));
-
-        TreeViewer treeViewer = getTimeGraphCombo().getTreeViewer();
-        Tree tree = treeViewer.getTree();
-        Menu menu = contextMenu.createContextMenu(tree);
-        tree.setMenu(menu);
-        getSite().registerContextMenu(contextMenu, treeViewer);
     }
 
     /**
@@ -946,72 +1049,6 @@ public class CallStackView extends AbstractTimeGraphView {
     // Methods related to function name mapping
     // ------------------------------------------------------------------------
 
-    /**
-     * Common code for all import file mapping actions
-     */
-    private abstract class AbstractImportFileMappingAction extends Action {
-        private final String fDialogTitle;
-
-        private AbstractImportFileMappingAction(String dialogTitle) {
-            fDialogTitle = dialogTitle;
-        }
-
-        @Override
-        public void run() {
-            FileDialog dialog = new FileDialog(getViewSite().getShell());
-            dialog.setText(fDialogTitle);
-            final 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 Job(Messages.CallStackView_ImportMappingJobName) {
-                @Override
-                public IStatus run(IProgressMonitor monitor) {
-                    fNameMapping = doMapping(new File(filePath));
-
-                    /* Refresh call stack entries and event labels */
-                    Display.getDefault().asyncExec(new Runnable() {
-                        @Override
-                        public void run() {
-                            synchingToTime(getTimeGraphViewer().getSelectionBegin());
-                        }
-                    });
-                    return Status.OK_STATUS;
-                }
-            };
-            job.schedule();
-        }
-
-        abstract Map<String, String> doMapping(File file);
-    }
-
-    /**
-     * Toolbar icon to import the function address-to-name mapping file.
-     */
-    private Action getImportMappingAction() {
-        if (fImportMappingAction != null) {
-            return fImportMappingAction;
-        }
-        fImportMappingAction = new AbstractImportFileMappingAction(Messages.CallStackView_ImportMappingDialogTitle) {
-            @Override
-            Map<String, String> doMapping(File file) {
-                return FunctionNameMapper.mapFromNmTextFile(file);
-            }
-        };
-
-        fImportMappingAction.setText(Messages.CallStackView_ImportMappingButtonText);
-        fImportMappingAction.setToolTipText(Messages.CallStackView_ImportMappingButtonTooltip);
-        fImportMappingAction.setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(IMPORT_MAPPING_ICON_PATH));
-
-        return fImportMappingAction;
-    }
-
     private Action getSortByNameAction() {
         if (fSortByNameAction == null) {
             fSortByNameAction = new Action(Messages.CallStackView_SortByThreadName, IAction.AS_CHECK_BOX) {
@@ -1133,42 +1170,55 @@ public class CallStackView extends AbstractTimeGraphView {
         refresh();
     }
 
-    /**
-     * Toolbar icon to import the function address-to-name mapping binary file.
-     */
-    private Action getImportBinaryAction() {
-        if (fImportBinaryFileMappingAction != null) {
-            return fImportBinaryFileMappingAction;
+    private Action getConfigureSymbolsAction() {
+        if (fConfigureSymbolsAction != null) {
+            return fConfigureSymbolsAction;
         }
 
-        fImportBinaryFileMappingAction = new AbstractImportFileMappingAction(Messages.CallStackView_ImportBinaryFileDialogTitle) {
+        fConfigureSymbolsAction = new Action(Messages.CallStackView_ConfigureSymbolProvidersText) {
             @Override
-            Map<String, String> doMapping(File file) {
-                return FunctionNameMapper.mapFromBinaryFile(file);
+            public void run() {
+                SymbolProviderConfigDialog dialog = new SymbolProviderConfigDialog(getSite().getShell(), getProviderPages());
+                if (dialog.open() == IDialogConstants.OK_ID) {
+                    refresh();
+                }
             }
         };
 
-        fImportBinaryFileMappingAction.setText(Messages.CallStackView_ImportBinaryFileButtonText);
-        fImportBinaryFileMappingAction.setToolTipText(Messages.CallStackView_ImportBinaryFileButtonTooltip);
-        fImportBinaryFileMappingAction.setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(IMPORT_BINARY_ICON_PATH));
+        fConfigureSymbolsAction.setToolTipText(Messages.CallStackView_ConfigureSymbolProvidersTooltip);
+        fConfigureSymbolsAction.setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(IMPORT_BINARY_ICON_PATH));
+        fConfigureSymbolsAction.setEnabled(false);
 
-        return fImportBinaryFileMappingAction;
+        return fConfigureSymbolsAction;
     }
 
-    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 an array of {@link ISymbolProviderPreferencePage} that will
+     *         configure the current traces
+     */
+    private ISymbolProviderPreferencePage[] getProviderPages() {
+        List<ISymbolProviderPreferencePage> pages = new ArrayList<>();
+        ITmfTrace trace = getTrace();
+        if (trace != null) {
+            for (ITmfTrace subTrace : getTracesToBuild(trace)) {
+                ISymbolProvider provider = fSymbolProviders.get(subTrace);
+                if (provider != null) {
+                    ISymbolProviderPreferencePage page = provider.createPreferencePage();
+                    if (page != null) {
+                        pages.add(page);
+                    }
+                }
+            }
         }
-        return ret;
+        return pages.toArray(new ISymbolProviderPreferencePage[pages.size()]);
+    }
+
+    /**
+     * Update the enable status of the configure symbols action
+     */
+    private void updateConfigureSymbolsAction() {
+        ISymbolProviderPreferencePage[] providerPages = getProviderPages();
+        getConfigureSymbolsAction().setEnabled(providerPages.length > 0);
     }
 
 }
This page took 0.03615 seconds and 5 git commands to generate.