lttng2.ust: remove deprecated code
[deliverable/tracecompass.git] / lttng / org.eclipse.tracecompass.lttng2.ust.core / src / org / eclipse / tracecompass / lttng2 / ust / core / analysis / debuginfo / UstDebugInfoAnalysisModule.java
1 /*******************************************************************************
2 * Copyright (c) 2015, 2016 EfficiOS Inc., Alexandre Montplaisir
3 *
4 * All rights reserved. This program and the accompanying materials
5 * are made available under the terms of the Eclipse Public License v1.0
6 * which accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
8 *******************************************************************************/
9
10 package org.eclipse.tracecompass.lttng2.ust.core.analysis.debuginfo;
11
12 import static org.eclipse.tracecompass.common.core.NonNullUtils.checkNotNull;
13
14 import java.util.Collection;
15 import java.util.Collections;
16 import java.util.List;
17 import java.util.OptionalLong;
18 import java.util.Set;
19 import java.util.TreeSet;
20
21 import org.eclipse.jdt.annotation.NonNull;
22 import org.eclipse.jdt.annotation.Nullable;
23 import org.eclipse.tracecompass.internal.lttng2.ust.core.analysis.debuginfo.UstDebugInfoStateProvider;
24 import org.eclipse.tracecompass.lttng2.ust.core.trace.LttngUstTrace;
25 import org.eclipse.tracecompass.statesystem.core.ITmfStateSystem;
26 import org.eclipse.tracecompass.statesystem.core.StateSystemUtils;
27 import org.eclipse.tracecompass.statesystem.core.exceptions.AttributeNotFoundException;
28 import org.eclipse.tracecompass.statesystem.core.exceptions.StateSystemDisposedException;
29 import org.eclipse.tracecompass.statesystem.core.exceptions.TimeRangeException;
30 import org.eclipse.tracecompass.statesystem.core.interval.ITmfStateInterval;
31 import org.eclipse.tracecompass.statesystem.core.statevalue.ITmfStateValue;
32 import org.eclipse.tracecompass.tmf.core.analysis.requirements.TmfAbstractAnalysisRequirement;
33 import org.eclipse.tracecompass.tmf.core.exceptions.TmfAnalysisException;
34 import org.eclipse.tracecompass.tmf.core.statesystem.ITmfStateProvider;
35 import org.eclipse.tracecompass.tmf.core.statesystem.TmfStateSystemAnalysisModule;
36 import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
37 import org.eclipse.tracecompass.tmf.ctf.core.trace.CtfUtils;
38
39 import com.google.common.annotations.VisibleForTesting;
40 import com.google.common.collect.ImmutableList;
41
42 /**
43 * Analysis to provide TMF Callsite information by mapping IP (instruction
44 * pointer) contexts to address/line numbers via debug information.
45 *
46 * @author Alexandre Montplaisir
47 * @since 2.0
48 */
49 public class UstDebugInfoAnalysisModule extends TmfStateSystemAnalysisModule {
50
51 /**
52 * Analysis ID, it should match that in the plugin.xml file
53 */
54 public static final String ID = "org.eclipse.linuxtools.lttng2.ust.analysis.debuginfo"; //$NON-NLS-1$
55
56 @Override
57 protected ITmfStateProvider createStateProvider() {
58 return new UstDebugInfoStateProvider(checkNotNull(getTrace()));
59 }
60
61 @Override
62 public boolean setTrace(ITmfTrace trace) throws TmfAnalysisException {
63 if (!(trace instanceof LttngUstTrace)) {
64 return false;
65 }
66 return super.setTrace(trace);
67 }
68
69 /**
70 * @since 3.0
71 */
72 @Override
73 @Nullable
74 public LttngUstTrace getTrace() {
75 return (LttngUstTrace) super.getTrace();
76 }
77
78 @Override
79 public Iterable<TmfAbstractAnalysisRequirement> getAnalysisRequirements() {
80 // TODO specify actual requirements once the requirement-checking is
81 // implemented. This analysis needs "ip" and "vpid" contexts.
82 return Collections.EMPTY_SET;
83 }
84
85 @Override
86 public boolean canExecute(ITmfTrace trace) {
87 /* The analysis can only work with LTTng-UST traces... */
88 if (!(trace instanceof LttngUstTrace)) {
89 return false;
90 }
91 LttngUstTrace ustTrace = (LttngUstTrace) trace;
92 String tracerName = CtfUtils.getTracerName(ustTrace);
93 int majorVersion = CtfUtils.getTracerMajorVersion(ustTrace);
94 int minorVersion = CtfUtils.getTracerMinorVersion(ustTrace);
95
96 /* ... taken with UST >= 2.8 ... */
97 if (!LttngUstTrace.TRACER_NAME.equals(tracerName)) {
98 return false;
99 }
100 if (majorVersion < 2) {
101 return false;
102 }
103 if (majorVersion == 2 && minorVersion < 8) {
104 return false;
105 }
106
107 /* ... that respect the ip/vpid contexts requirements. */
108 return super.canExecute(trace);
109 }
110
111 // ------------------------------------------------------------------------
112 // Class-specific operations
113 // ------------------------------------------------------------------------
114
115 /**
116 * Return all the binaries that were detected in the trace.
117 *
118 * @return The binaries (executables or libraries) referred to in the trace.
119 */
120 public Collection<UstDebugInfoBinaryFile> getAllBinaries() {
121 ITmfStateSystem ss = getStateSystem();
122 if (ss == null) {
123 /* State system might not yet be initialized */
124 return Collections.EMPTY_SET;
125 }
126
127 final @NonNull Set<UstDebugInfoBinaryFile> files = new TreeSet<>();
128 ImmutableList.Builder<Integer> builder = ImmutableList.builder();
129 List<Integer> vpidQuarks = ss.getSubAttributes(ITmfStateSystem.ROOT_ATTRIBUTE, false);
130 for (Integer vpidQuark : vpidQuarks) {
131 builder.addAll(ss.getSubAttributes(vpidQuark, false));
132 }
133 List<Integer> baddrQuarks = builder.build();
134
135 try {
136 for (Integer baddrQuark : baddrQuarks) {
137 int buildIdQuark = ss.getQuarkRelative(baddrQuark, UstDebugInfoStateProvider.BUILD_ID_ATTRIB);
138 int debugLinkQuark = ss.getQuarkRelative(baddrQuark, UstDebugInfoStateProvider.DEBUG_LINK_ATTRIB);
139 int pathQuark = ss.getQuarkRelative(baddrQuark, UstDebugInfoStateProvider.PATH_ATTRIB);
140 int isPICQuark = ss.getQuarkRelative(baddrQuark, UstDebugInfoStateProvider.IS_PIC_ATTRIB);
141 long ts = ss.getStartTime();
142
143 /*
144 * Iterate over each mapping there ever was at this base
145 * address.
146 */
147 ITmfStateInterval interval = StateSystemUtils.queryUntilNonNullValue(ss, baddrQuark, ts, Long.MAX_VALUE);
148 while (interval != null) {
149 ts = interval.getStartTime();
150
151 ITmfStateValue filePathStateValue = ss.querySingleState(ts, pathQuark).getStateValue();
152 String filePath = filePathStateValue.unboxStr();
153
154 ITmfStateValue buildIdStateValue = ss.querySingleState(ts, buildIdQuark).getStateValue();
155 String buildId = unboxStrOrNull(buildIdStateValue);
156
157 ITmfStateValue debuglinkStateValue = ss.querySingleState(ts, debugLinkQuark).getStateValue();
158 String debugLink = unboxStrOrNull(debuglinkStateValue);
159
160 ITmfStateValue isPICStateValue = ss.querySingleState(ts, isPICQuark).getStateValue();
161 Boolean isPIC = isPICStateValue.unboxInt() != 0;
162
163 files.add(new UstDebugInfoBinaryFile(filePath, buildId, debugLink, isPIC));
164
165 /*
166 * Go one past the end of the interval, and perform the
167 * query again to find the next mapping at this address.
168 */
169 ts = interval.getEndTime() + 1;
170 interval = StateSystemUtils.queryUntilNonNullValue(ss, baddrQuark, ts, Long.MAX_VALUE);
171 }
172 }
173 } catch (AttributeNotFoundException | TimeRangeException | StateSystemDisposedException e) {
174 /* Oh well, such is life. */
175 }
176 return files;
177 }
178
179 /**
180 * Get the binary file (executable or library) that corresponds to a given
181 * instruction pointer, at a given time.
182 *
183 * @param ts
184 * The timestamp
185 * @param vpid
186 * The VPID of the process we are querying for
187 * @param ip
188 * The instruction pointer of the trace event. Normally comes
189 * from a 'ip' context.
190 * @return A {@link UstDebugInfoLoadedBinaryFile} object, describing the
191 * binary file and its base address.
192 * @noreference Meant to be used internally by
193 * {@link UstDebugInfoBinaryAspect} only.
194 */
195 @VisibleForTesting
196 public @Nullable UstDebugInfoLoadedBinaryFile getMatchingFile(long ts, long vpid, long ip) {
197 try {
198 final ITmfStateSystem ss = getStateSystem();
199 if (ss == null) {
200 /* State system might not yet be initialized */
201 return null;
202 }
203
204 List<Integer> possibleBaddrQuarks = ss.getQuarks(String.valueOf(vpid), "*"); //$NON-NLS-1$
205 List<ITmfStateInterval> state = ss.queryFullState(ts);
206
207 /* Get the most probable base address from all the known ones */
208 OptionalLong potentialBaddr = possibleBaddrQuarks.stream()
209 .filter(quark -> {
210 /* Keep only currently (at ts) mapped objects. */
211 ITmfStateValue value = state.get(quark).getStateValue();
212 return value.getType() == ITmfStateValue.Type.INTEGER && value.unboxInt() == 1;
213 })
214 .map(quark -> ss.getAttributeName(quark.intValue()))
215 .mapToLong(baddrStr -> Long.parseLong(baddrStr))
216 .filter(baddr -> baddr <= ip)
217 .max();
218
219 if (!potentialBaddr.isPresent()) {
220 return null;
221 }
222
223 long baddr = potentialBaddr.getAsLong();
224 final int baddrQuark = ss.getQuarkAbsolute(String.valueOf(vpid),
225 String.valueOf(baddr));
226
227 final int memszQuark = ss.getQuarkRelative(baddrQuark, UstDebugInfoStateProvider.MEMSZ_ATTRIB);
228 final long memsz = state.get(memszQuark).getStateValue().unboxLong();
229
230 /* Make sure the 'ip' fits the range of this object. */
231 if (!(ip < baddr + memsz)) {
232 /*
233 * Not the correct memory range after all. We do not have
234 * information about the library that was loaded here.
235 */
236 return null;
237 }
238
239 final int pathQuark = ss.getQuarkRelative(baddrQuark, UstDebugInfoStateProvider.PATH_ATTRIB);
240 String filePath = state.get(pathQuark).getStateValue().unboxStr();
241
242 final int buildIdQuark = ss.getQuarkRelative(baddrQuark, UstDebugInfoStateProvider.BUILD_ID_ATTRIB);
243 ITmfStateValue buildIdValue = state.get(buildIdQuark).getStateValue();
244 String buildId = unboxStrOrNull(buildIdValue);
245
246 final int debugLinkQuark = ss.getQuarkRelative(baddrQuark, UstDebugInfoStateProvider.DEBUG_LINK_ATTRIB);
247 ITmfStateValue debugLinkValue = state.get(debugLinkQuark).getStateValue();
248 String debugLink = unboxStrOrNull(debugLinkValue);
249
250 final int isPicQuark = ss.getQuarkRelative(baddrQuark, UstDebugInfoStateProvider.IS_PIC_ATTRIB);
251 boolean isPic = state.get(isPicQuark).getStateValue().unboxInt() != 0;
252
253 return new UstDebugInfoLoadedBinaryFile(baddr, filePath, buildId, debugLink, isPic);
254
255 } catch (AttributeNotFoundException | TimeRangeException | StateSystemDisposedException e) {
256 /* Either the data is not available yet, or incomplete. */
257 return null;
258 }
259 }
260
261 private static @Nullable String unboxStrOrNull(ITmfStateValue value) {
262 return (value.isNull() ? null : value.unboxStr());
263 }
264 }
This page took 0.044715 seconds and 5 git commands to generate.