2729e6e0a47436c7b5b90ff30c95629a024ded97
[deliverable/tracecompass.git] / lttng / org.eclipse.tracecompass.lttng2.ust.core / src / org / eclipse / tracecompass / internal / lttng2 / ust / core / callstack / LttngUstCallStackProvider.java
1 /*******************************************************************************
2 * Copyright (c) 2013, 2015 Ericsson
3 *
4 * All rights reserved. This program and the accompanying materials are
5 * made available under the terms of the Eclipse Public License v1.0 which
6 * accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
8 *
9 * Contributors:
10 * Alexandre Montplaisir - Initial API and implementation
11 * Patrick Tasse - Add support for thread id
12 *******************************************************************************/
13
14 package org.eclipse.tracecompass.internal.lttng2.ust.core.callstack;
15
16 import java.util.Set;
17
18 import org.eclipse.jdt.annotation.NonNull;
19 import org.eclipse.jdt.annotation.NonNullByDefault;
20 import org.eclipse.jdt.annotation.Nullable;
21 import org.eclipse.tracecompass.internal.lttng2.ust.core.trace.layout.LttngUst20EventLayout;
22 import org.eclipse.tracecompass.lttng2.ust.core.trace.LttngUstTrace;
23 import org.eclipse.tracecompass.lttng2.ust.core.trace.layout.ILttngUstEventLayout;
24 import org.eclipse.tracecompass.tmf.core.callstack.CallStackStateProvider;
25 import org.eclipse.tracecompass.tmf.core.event.ITmfEvent;
26 import org.eclipse.tracecompass.tmf.core.event.ITmfEventField;
27 import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
28 import org.eclipse.tracecompass.tmf.ctf.core.event.CtfTmfEvent;
29
30 import com.google.common.collect.ImmutableSet;
31
32 /**
33 * Callstack provider for LTTng-UST traces.
34 *
35 * If the traces contains 'func_entry' and 'func_exit' event (see the
36 * lttng-ust-cyg-profile manpage), AND contains vtid and procname contexts, we
37 * can use this information to populate the TMF Callstack View.
38 *
39 * Granted, most UST traces will not contain this information. In this case,
40 * this will simply build an empty state system, and the view will remain
41 * unavailable.
42 *
43 * @author Alexandre Montplaisir
44 */
45 @NonNullByDefault
46 public class LttngUstCallStackProvider extends CallStackStateProvider {
47
48 /**
49 * Version number of this state provider. Please bump this if you modify
50 * the contents of the generated state history in some way.
51 */
52 private static final int VERSION = 3;
53
54 /** Event names indicating function entry */
55 private final Set<String> funcEntryEvents;
56
57 /** Event names indicating function exit */
58 private final Set<String> funcExitEvents;
59
60 private final ILttngUstEventLayout fLayout;
61
62 // ------------------------------------------------------------------------
63 // Constructor
64 // ------------------------------------------------------------------------
65
66 /**
67 * Constructor
68 *
69 * @param trace
70 * The UST trace
71 */
72 public LttngUstCallStackProvider(ITmfTrace trace) {
73 super(trace);
74
75 if (trace instanceof LttngUstTrace) {
76 fLayout = ((LttngUstTrace) trace).getEventLayout();
77 } else {
78 /* For impostor trace types, assume they use the LTTng 2.0 layout */
79 fLayout = LttngUst20EventLayout.getInstance();
80 }
81
82 funcEntryEvents = ImmutableSet.of(
83 fLayout.eventCygProfileFuncEntry(),
84 fLayout.eventCygProfileFastFuncEntry());
85
86 funcExitEvents = ImmutableSet.of(
87 fLayout.eventCygProfileFuncExit(),
88 fLayout.eventCygProfileFastFuncExit());
89 }
90
91 // ------------------------------------------------------------------------
92 // Methods from AbstractTmfStateProvider
93 // ------------------------------------------------------------------------
94
95 @Override
96 public LttngUstCallStackProvider getNewInstance() {
97 return new LttngUstCallStackProvider(getTrace());
98 }
99
100 @Override
101 public int getVersion() {
102 return VERSION;
103 }
104
105 // ------------------------------------------------------------------------
106 // Methods from CallStackStateProvider
107 // ------------------------------------------------------------------------
108
109 /**
110 * Check that this event contains the required information we need to be
111 * used in the call stack view. We need at least the "procname" and "vtid"
112 * contexts.
113 *
114 * The "vpid" is useful too, but optional.
115 */
116 @Override
117 protected boolean considerEvent(ITmfEvent event) {
118 if (!(event instanceof CtfTmfEvent)) {
119 return false;
120 }
121 ITmfEventField content = ((CtfTmfEvent) event).getContent();
122 if (content.getField(fLayout.contextVtid()) == null ||
123 content.getField(fLayout.contextProcname()) == null) {
124 return false;
125 }
126 return true;
127 }
128
129 @Override
130 public @Nullable String functionEntry(ITmfEvent event) {
131 String eventName = event.getName();
132 if (!funcEntryEvents.contains(eventName)) {
133 return null;
134 }
135 Long address = (Long) event.getContent().getField(fLayout.fieldAddr()).getValue();
136 return Long.toHexString(address);
137 }
138
139 @Override
140 public @Nullable String functionExit(ITmfEvent event) {
141 String eventName = event.getName();
142 if (!funcExitEvents.contains(eventName)) {
143 return null;
144 }
145 /*
146 * The 'addr' field may or may not be present in func_exit events,
147 * depending on if cyg-profile.so or cyg-profile-fast.so was used.
148 */
149 ITmfEventField field = event.getContent().getField(fLayout.fieldAddr());
150 if (field == null) {
151 return CallStackStateProvider.UNDEFINED;
152 }
153 Long address = (Long) field.getValue();
154 return Long.toHexString(address);
155 }
156
157 @Override
158 protected int getProcessId(@NonNull ITmfEvent event) {
159 /* The "vpid" context may not be present! We need to check */
160 ITmfEventField content = event.getContent();
161 ITmfEventField vpidContextField = content.getField(fLayout.contextVpid());
162 if (vpidContextField == null) {
163 return UNDEFINED_PID;
164 }
165 return ((Long) vpidContextField.getValue()).intValue();
166 }
167
168 @Override
169 protected long getThreadId(ITmfEvent event) {
170 /* We checked earlier that the "vtid" context is present */
171 ITmfEventField content = event.getContent();
172 return ((Long) content.getField(fLayout.contextVtid()).getValue()).longValue();
173 }
174
175 @Override
176 public String getThreadName(ITmfEvent event) {
177 /* We checked earlier that the "procname" context is present */
178 ITmfEventField content = event.getContent();
179 String procName = (String) content.getField(fLayout.contextProcname()).getValue();
180 long vtid = getThreadId(event);
181 return (procName + '-' + Long.toString(vtid));
182 }
183 }
This page took 0.03373 seconds and 4 git commands to generate.