timing: Bug 500592: fix symbols for with debug info of Lttng 2.8
authorBernd Hufmann <Bernd.Hufmann@ericsson.com>
Wed, 31 Aug 2016 20:27:11 +0000 (16:27 -0400)
committerBernd Hufmann <bernd.hufmann@ericsson.com>
Tue, 6 Sep 2016 14:04:44 +0000 (10:04 -0400)
The process ID of the trace application is propagated so that it can
be used for the Function Duration Density view and Flame Graph view.

For the Flame Graph it uses the the timestamp of the maximum segment to
get the symbol name from the LTTng UST symbol provider.

For the Function density view it takes the start time of the segment.

Change-Id: Id3eb817f156e30b9be4996b732de05bc335418b9
Signed-off-by: Bernd Hufmann <Bernd.Hufmann@ericsson.com>
Reviewed-on: https://git.eclipse.org/r/80298
Reviewed-by: Hudson CI
Reviewed-by: Matthew Khouzam <matthew.khouzam@ericsson.com>
Tested-by: Matthew Khouzam <matthew.khouzam@ericsson.com>
analysis/org.eclipse.tracecompass.analysis.timing.core/src/org/eclipse/tracecompass/internal/analysis/timing/core/callgraph/AbstractCalledFunction.java
analysis/org.eclipse.tracecompass.analysis.timing.core/src/org/eclipse/tracecompass/internal/analysis/timing/core/callgraph/AggregatedCalledFunction.java
analysis/org.eclipse.tracecompass.analysis.timing.core/src/org/eclipse/tracecompass/internal/analysis/timing/core/callgraph/CallGraphAnalysis.java
analysis/org.eclipse.tracecompass.analysis.timing.core/src/org/eclipse/tracecompass/internal/analysis/timing/core/callgraph/CalledFunction.java
analysis/org.eclipse.tracecompass.analysis.timing.core/src/org/eclipse/tracecompass/internal/analysis/timing/core/callgraph/CalledFunctionFactory.java
analysis/org.eclipse.tracecompass.analysis.timing.core/src/org/eclipse/tracecompass/internal/analysis/timing/core/callgraph/CalledStringFunction.java
analysis/org.eclipse.tracecompass.analysis.timing.core/src/org/eclipse/tracecompass/internal/analysis/timing/core/callgraph/ICalledFunction.java
analysis/org.eclipse.tracecompass.analysis.timing.ui/src/org/eclipse/tracecompass/internal/analysis/timing/ui/callgraph/SymbolAspect.java
analysis/org.eclipse.tracecompass.analysis.timing.ui/src/org/eclipse/tracecompass/internal/analysis/timing/ui/flamegraph/FlameGraphPresentationProvider.java
analysis/org.eclipse.tracecompass.analysis.timing.ui/src/org/eclipse/tracecompass/internal/analysis/timing/ui/flamegraph/FlamegraphEvent.java

index 0cf4b70392bb4d3c9ffb0e78d589c86c57dc589e..a3138d0df08ab9c82dac4ea7322357d3eafe7c44 100644 (file)
@@ -52,8 +52,9 @@ abstract class AbstractCalledFunction implements ICalledFunction {
     private final List<ICalledFunction> fChildren = new ArrayList<>();
     private final @Nullable ICalledFunction fParent;
     protected long fSelfTime = 0;
+    private final int fProcessId;
 
-    public AbstractCalledFunction(long start, long end, int depth, @Nullable ICalledFunction parent) {
+    public AbstractCalledFunction(long start, long end, int depth, int processId, @Nullable ICalledFunction parent) {
         if (start > end) {
             throw new IllegalArgumentException(Messages.TimeError + "[" + start + "," + end + "]"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
         }
@@ -63,6 +64,7 @@ abstract class AbstractCalledFunction implements ICalledFunction {
         fParent = parent;
         // It'll be modified once we add a child to it
         fSelfTime = fEnd - fStart;
+        fProcessId = processId;
     }
 
     @Override
@@ -121,6 +123,11 @@ abstract class AbstractCalledFunction implements ICalledFunction {
         return fDepth;
     }
 
+    @Override
+    public int getProcessId() {
+        return fProcessId;
+    }
+
     @Override
     public int compareTo(@Nullable ISegment o) {
         if (o == null) {
index 719f7e45fab6d8241acee28e9720dc5d5441f6bb..51f4f834a62e7b8d4d679c1be9729da71224a2eb 100644 (file)
@@ -45,6 +45,7 @@ public class AggregatedCalledFunction {
     private final AggregatedCalledFunctionStatistics fStatistics;
     private long fDuration;
     private long fSelfTime;
+    private final int fProcessId;
 
     /**
      * Constructor, parent is not null
@@ -60,6 +61,7 @@ public class AggregatedCalledFunction {
         fDuration = calledFunction.getLength();
         fSelfTime = calledFunction.getLength();
         fDepth = calledFunction.getDepth();
+        fProcessId = calledFunction.getProcessId();
         fMaxDepth = parent.getMaxDepth();
         fParent = parent;
         fStatistics = new AggregatedCalledFunctionStatistics(calledFunction, calledFunction);
@@ -78,6 +80,7 @@ public class AggregatedCalledFunction {
         fDuration = calledFunction.getLength();
         fSelfTime = calledFunction.getLength();
         fDepth = calledFunction.getDepth();
+        fProcessId = calledFunction.getProcessId();
         fMaxDepth = maxDepth;
         fParent = null;
         fStatistics = new AggregatedCalledFunctionStatistics(calledFunction, calledFunction);
@@ -236,6 +239,14 @@ public class AggregatedCalledFunction {
         fSelfTime += selfTime;
     }
 
+    /**
+     * The process ID of the trace application.
+     * @return The process Id
+     */
+    public int getProcessId() {
+        return fProcessId;
+    }
+
     /**
      * Returns whether the function has callees.
      *
index fab4c6a40c3d3508df3cf1f1e42978af25b1e6fb..e679508037e666aa05b9400d7ed5e7ab0a095158 100644 (file)
@@ -180,8 +180,9 @@ public abstract class CallGraphAnalysis extends TmfAbstractAnalysisModule implem
         }
         List<Integer> processQuarks = ss.getQuarks(processesPattern);
         for (int processQuark : processQuarks) {
+            int processId = getProcessId(ss, processQuark, ss.getCurrentEndTime());
             for (int threadQuark : ss.getQuarks(processQuark, threadsPattern)) {
-                if (!iterateOverQuark(ss, threadQuark, callStackPath, monitor)) {
+                if (!iterateOverQuark(ss, processId, threadQuark, callStackPath, monitor)) {
                     return false;
                 }
             }
@@ -196,20 +197,22 @@ public abstract class CallGraphAnalysis extends TmfAbstractAnalysisModule implem
      *
      * @param stateSystem
      *            The state system
-     * @param quark
-     *            The quark
+     * @param processId
+     *            The process ID of the traced application
+     * @param threadQuark
+     *            The thread quark
      * @param subAttributePath
      *            sub-Attributes path
      * @param monitor
      *            The monitor
      * @return Boolean
      */
-    private boolean iterateOverQuark(ITmfStateSystem stateSystem, int quark, String[] subAttributePath, IProgressMonitor monitor) {
-        String threadName = stateSystem.getAttributeName(quark);
+    private boolean iterateOverQuark(ITmfStateSystem stateSystem, int processId, int threadQuark, String[] subAttributePath, IProgressMonitor monitor) {
+        String threadName = stateSystem.getAttributeName(threadQuark);
         long threadId = -1;
         ITmfStateInterval interval = null;
         try {
-            interval = stateSystem.querySingleState(stateSystem.getStartTime(), quark);
+            interval = stateSystem.querySingleState(stateSystem.getStartTime(), threadQuark);
             ITmfStateValue threadStateValue = interval.getStateValue();
             if (threadStateValue.getType() == Type.LONG || threadStateValue.getType() == Type.INTEGER) {
                 threadId = threadStateValue.unboxLong();
@@ -226,13 +229,13 @@ public abstract class CallGraphAnalysis extends TmfAbstractAnalysisModule implem
         try {
             long curTime = stateSystem.getStartTime();
             long limit = stateSystem.getCurrentEndTime();
-            AbstractCalledFunction initSegment = CalledFunctionFactory.create(0, 0, 0, threadName, null);
+            AbstractCalledFunction initSegment = CalledFunctionFactory.create(0, 0, 0, threadName, processId, null);
             ThreadNode init = new ThreadNode(initSegment, 0, threadId);
             while (curTime < limit) {
                 if (monitor.isCanceled()) {
                     return false;
                 }
-                int callStackQuark = stateSystem.getQuarkRelative(quark, subAttributePath);
+                int callStackQuark = stateSystem.getQuarkRelative(threadQuark, subAttributePath);
                 fCurrentQuarks = stateSystem.getSubAttributes(callStackQuark, false);
                 if (fCurrentQuarks.isEmpty()) {
                     return false;
@@ -246,10 +249,10 @@ public abstract class CallGraphAnalysis extends TmfAbstractAnalysisModule implem
                     long intervalStart = interval.getStartTime();
                     long intervalEnd = interval.getEndTime();
                     // Create the segment for the first call event.
-                    AbstractCalledFunction segment = CalledFunctionFactory.create(intervalStart, intervalEnd + 1, depth, stateValue, null);
+                    AbstractCalledFunction segment = CalledFunctionFactory.create(intervalStart, intervalEnd + 1, depth, stateValue, processId, null);
                     fRootFunctions.add(segment);
                     AggregatedCalledFunction firstNode = new AggregatedCalledFunction(segment, fCurrentQuarks.size());
-                    if (!findChildren(segment, depth, stateSystem, fCurrentQuarks.size() + fCurrentQuarks.get(depth), firstNode, monitor)) {
+                    if (!findChildren(segment, depth, stateSystem, fCurrentQuarks.size() + fCurrentQuarks.get(depth), firstNode, processId, monitor)) {
                         return false;
                     }
                     init.addChild(firstNode);
@@ -278,13 +281,15 @@ public abstract class CallGraphAnalysis extends TmfAbstractAnalysisModule implem
      *            The quark of the segment parent ss The actual state system
      * @param maxQuark
      *            The last quark in the state system
-     * @param AggregatedCalledFunction
+     * @param aggregatedCalledFunction
      *            A node in the aggregation tree
+     * @param processId
+     *            The process ID of the traced application
      * @param monitor
      *            The progress monitor The progress monitor TODO: if stack size
      *            is an issue, convert to a stack instead of recursive function
      */
-    private boolean findChildren(AbstractCalledFunction node, int depth, ITmfStateSystem ss, int maxQuark, AggregatedCalledFunction aggregatedCalledFunction, IProgressMonitor monitor) {
+    private boolean findChildren(AbstractCalledFunction node, int depth, ITmfStateSystem ss, int maxQuark, AggregatedCalledFunction aggregatedCalledFunction, int processId, IProgressMonitor monitor) {
         fStore.add(node);
         long curTime = node.getStart();
         long limit = node.getEnd();
@@ -310,10 +315,10 @@ public abstract class CallGraphAnalysis extends TmfAbstractAnalysisModule implem
                 if (intervalStart < node.getStart() || intervalEnd > limit) {
                     return true;
                 }
-                AbstractCalledFunction segment = CalledFunctionFactory.create(intervalStart, intervalEnd + 1, node.getDepth() + 1, stateValue, node);
+                AbstractCalledFunction segment = CalledFunctionFactory.create(intervalStart, intervalEnd + 1, node.getDepth() + 1, stateValue, processId, node);
                 AggregatedCalledFunction childNode = new AggregatedCalledFunction(segment, aggregatedCalledFunction);
                 // Search for the children with the next quark.
-                findChildren(segment, depth + 1, ss, maxQuark, childNode, monitor);
+                findChildren(segment, depth + 1, ss, maxQuark, childNode, processId, monitor);
                 aggregatedCalledFunction.addChild(childNode);
                 node.addChild(segment);
             }
@@ -383,4 +388,26 @@ public abstract class CallGraphAnalysis extends TmfAbstractAnalysisModule implem
         return ImmutableList.copyOf(fThreadNodes);
     }
 
+    private static int getProcessId(ITmfStateSystem ss, int processQuark, long curTime) {
+        int processId = -1;
+        if (processQuark != ITmfStateSystem.ROOT_ATTRIBUTE) {
+            try {
+                ITmfStateInterval interval = ss.querySingleState(curTime, processQuark);
+                String processName = ss.getAttributeName(processQuark);
+                ITmfStateValue processStateValue = interval.getStateValue();
+                if (processStateValue.getType() == Type.INTEGER) {
+                    processId = processStateValue.unboxInt();
+                } else {
+                    try {
+                        processId = Integer.parseInt(processName);
+                    } catch (NumberFormatException e) {
+                        /* use default processId */
+                    }
+                }
+            } catch (StateSystemDisposedException e) {
+                // ignore
+            }
+        }
+        return processId;
+    }
 }
\ No newline at end of file
index 3764581bd93c0e24901d0770f2b869b2c0a93e39..b7417fb6c59e5399413c6f973cbdab951c0abd5e 100644 (file)
@@ -39,11 +39,13 @@ public class CalledFunction extends AbstractCalledFunction {
      *            The symbol of the call stack function
      * @param depth
      *            The depth in the call stack of a function
+     * @param processId
+     *            The process ID of the traced application
      * @param parent
      *            The caller, can be null for root elements
      */
-    protected CalledFunction(long start, long end, long symbol, int depth, @Nullable ICalledFunction parent) {
-        super(start, end, depth, parent);
+    protected CalledFunction(long start, long end, long symbol, int depth, int processId, @Nullable ICalledFunction parent) {
+        super(start, end, depth, processId, parent);
         fSymbol = symbol;
     }
 
index 26e93958bf12dcd5cfe6fe8411f1261f44f5d801..6f91b59a4bcadc4b785011cce80e930d8bbe4710 100644 (file)
@@ -37,24 +37,26 @@ public class CalledFunctionFactory {
      *            the depth
      * @param stateValue
      *            the symbol
+     * @param processId
+     *            The process ID of the traced application
      * @param parent
      *            the parent node
-     * @return an ICalledFunction with the specified propertiess
+     * @return an ICalledFunction with the specified properties
      */
-    public static AbstractCalledFunction create(long start, long end, int depth, ITmfStateValue stateValue, @Nullable ICalledFunction parent) {
+    public static AbstractCalledFunction create(long start, long end, int depth, ITmfStateValue stateValue, int processId, @Nullable ICalledFunction parent) {
         switch (stateValue.getType()) {
         case CUSTOM:
             throw new IllegalArgumentException(ERROR_MSG + stateValue.getType() + SEPARATOR + stateValue.toString());
         case DOUBLE:
             throw new IllegalArgumentException(ERROR_MSG + stateValue.getType() + SEPARATOR + stateValue.toString());
         case INTEGER:
-            return create(start, end, depth, stateValue.unboxInt(), parent);
+            return create(start, end, depth, stateValue.unboxInt(), processId, parent);
         case LONG:
-            return create(start, end, depth, stateValue.unboxLong(), parent);
+            return create(start, end, depth, stateValue.unboxLong(), processId, parent);
         case NULL:
             throw new IllegalArgumentException(ERROR_MSG + stateValue.getType() + SEPARATOR + stateValue.toString());
         case STRING:
-            return create(start, end, depth, stateValue.unboxStr(), parent);
+            return create(start, end, depth, stateValue.unboxStr(), processId, parent);
         default:
             throw new IllegalArgumentException(ERROR_MSG + stateValue.getType() + SEPARATOR + stateValue.toString());
         }
@@ -72,15 +74,17 @@ public class CalledFunctionFactory {
      *            the depth
      * @param value
      *            the symbol
+     * @param processId
+     *            The process ID of the traced application
      * @param parent
      *            the parent node
      * @return an ICalledFunction with the specified propertiess
      */
-    private static CalledFunction create(long start, long end, int depth, long value, @Nullable ICalledFunction parent) {
+    private static CalledFunction create(long start, long end, int depth, long value, int processId, @Nullable ICalledFunction parent) {
         if (start > end) {
             throw new IllegalArgumentException(Messages.TimeError + '[' + start + ',' + end + ']');
         }
-        return new CalledFunction(start, end, value, depth, parent);
+        return new CalledFunction(start, end, value, depth, processId, parent);
     }
 
     /**
@@ -95,14 +99,16 @@ public class CalledFunctionFactory {
      *            the depth
      * @param value
      *            the symbol
+     * @param processId
+     *            The process ID of the traced application
      * @param parent
      *            the parent node
      * @return an ICalledFunction with the specified properties
      */
-    public static CalledStringFunction create(long start, long end, int depth, String value, @Nullable ICalledFunction parent) {
+    public static CalledStringFunction create(long start, long end, int depth, String value, int processId,  @Nullable ICalledFunction parent) {
         if (start > end) {
             throw new IllegalArgumentException(Messages.TimeError + '[' + start + ',' + end + ']');
         }
-        return new CalledStringFunction(start, end, value, depth, parent);
+        return new CalledStringFunction(start, end, value, depth, processId, parent);
     }
 }
index d6ea018953e67cde7bb45cd4524332b1a69db3c0..96756dba6a4b854295b3194372c733dd25083ae4 100644 (file)
@@ -41,11 +41,13 @@ public class CalledStringFunction extends AbstractCalledFunction {
      *            The symbol of the call stack function
      * @param depth
      *            The depth in the call stack of a function
+     * @param processId
+     *            The process ID of the traced application
      * @param parent
      *            The caller, can be null for root elements
      */
-    protected CalledStringFunction(long start, long end, String symbol, int depth, @Nullable ICalledFunction parent) {
-        super(start, end, depth, parent);
+    protected CalledStringFunction(long start, long end, String symbol, int depth, int processId, @Nullable ICalledFunction parent) {
+        super(start, end, depth, processId, parent);
         fSymbol = symbol;
     }
 
index 5fb05ac0cce564a4fa47a7d83aa6d1b6c587b706..e19a61fa642681729692c954848e1565ef2108df 100644 (file)
@@ -61,4 +61,11 @@ public interface ICalledFunction extends ISegment {
      */
     int getDepth();
 
+    /**
+     * The process ID of the traced application
+     *
+     * @return The process ID
+     */
+    int getProcessId();
+
 }
\ No newline at end of file
index 0ac537e0f8d88049ec363b30aaf8bb721cf000dc..0f7631d0ff6bf3a6cd59619230f5f03e3d61beaa 100644 (file)
@@ -79,6 +79,15 @@ public final class SymbolAspect implements ISegmentAspect {
                     if (symbolText == null) {
                         return "0x" + Long.toHexString(longAddress); //$NON-NLS-1$
                     }
+                    // take the start time in the query for the symbol name
+                    long time = segment.getStart();
+                    int pid = calledFunction.getProcessId();
+                    if (pid > 0) {
+                        String text = provider.getSymbolText(pid, time, longAddress);
+                        if (text != null) {
+                            return text;
+                        }
+                    }
                     return symbolText;
                 }
                 return String.valueOf(symbol);
index 70330e0888a99a078dc1cfa7f334d720b36806c6..8b70648c18a2b465c3aae12bd084923fb61b2d60 100644 (file)
@@ -134,6 +134,15 @@ public class FlameGraphPresentationProvider extends TimeGraphPresentationProvide
             if (funcSymbol == null) {
                 return "0x" + Long.toHexString(longAddress); //$NON-NLS-1$
             }
+            // take time of max segment for time a query the symbol name
+            long time = event.getStatistics().getMaxSegment().getStart();
+            int pid = event.getProcessId();
+            if (pid > 0) {
+                String text = symbolProvider.getSymbolText(pid, time, longAddress);
+                if (text != null) {
+                    return text;
+                }
+            }
         } else {
             return event.getSymbol().toString();
         }
index 59d52d20fc3b68b552f1613bafb2b328f67d4b6d..c393f486b1f09ea433a2b066eef9be0b8bdd3ec8 100644 (file)
@@ -27,6 +27,7 @@ public class FlamegraphEvent extends TimeEvent {
 
     private final Object fSymbol;
     private final long fSelfTime;
+    private final int fProcessId;
     private final AggregatedCalledFunctionStatistics fStatistics;
 
     /**
@@ -43,6 +44,7 @@ public class FlamegraphEvent extends TimeEvent {
         super(source, beginTime, aggregatedFunction.getDuration(), String.valueOf(aggregatedFunction.getSymbol()).hashCode() % MODULO + MODULO);
         fSymbol = aggregatedFunction.getSymbol();
         fStatistics = aggregatedFunction.getFunctionStatistics();
+        fProcessId = aggregatedFunction.getProcessId();
         fSelfTime = aggregatedFunction.getSelfTime();
     }
 
@@ -72,4 +74,13 @@ public class FlamegraphEvent extends TimeEvent {
     public long getSelfTime() {
         return fSelfTime;
     }
+
+    /**
+     * The process ID of the traced application
+     *
+     * @return process id
+     */
+    public int getProcessId() {
+        return fProcessId;
+    }
 }
This page took 0.034066 seconds and 5 git commands to generate.