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