Commit | Line | Data |
---|---|---|
ef7f180d AM |
1 | /******************************************************************************* |
2 | * Copyright (c) 2015 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.nullToEmptyString; | |
13 | ||
522dff53 AM |
14 | import java.io.File; |
15 | ||
ef7f180d | 16 | import org.eclipse.jdt.annotation.Nullable; |
522dff53 | 17 | import org.eclipse.tracecompass.internal.lttng2.ust.core.analysis.debuginfo.FileOffsetMapper; |
ef7f180d | 18 | import org.eclipse.tracecompass.lttng2.ust.core.trace.LttngUstTrace; |
ef7f180d | 19 | import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; |
ef7f180d AM |
20 | import org.eclipse.tracecompass.tmf.core.event.aspect.ITmfEventAspect; |
21 | import org.eclipse.tracecompass.tmf.core.event.lookup.TmfCallsite; | |
ef7f180d | 22 | |
522dff53 AM |
23 | import com.google.common.collect.Iterables; |
24 | ||
ef7f180d AM |
25 | /** |
26 | * Event aspect of UST traces to generate a {@link TmfCallsite} using the debug | |
27 | * info analysis and the IP (instruction pointer) context. | |
28 | * | |
29 | * @author Alexandre Montplaisir | |
30 | * @since 2.0 | |
31 | */ | |
ec48d248 | 32 | public class UstDebugInfoSourceAspect implements ITmfEventAspect<TmfCallsite> { |
ef7f180d AM |
33 | |
34 | /** Singleton instance */ | |
a103fe67 | 35 | public static final UstDebugInfoSourceAspect INSTANCE = new UstDebugInfoSourceAspect(); |
ef7f180d | 36 | |
a103fe67 | 37 | private UstDebugInfoSourceAspect() {} |
ef7f180d AM |
38 | |
39 | @Override | |
40 | public String getName() { | |
df993132 | 41 | return nullToEmptyString(Messages.UstDebugInfoAnalysis_SourceAspectName); |
ef7f180d AM |
42 | } |
43 | ||
44 | @Override | |
45 | public String getHelpText() { | |
df993132 | 46 | return nullToEmptyString(Messages.UstDebugInfoAnalysis_SourceAspectHelpText); |
ef7f180d AM |
47 | } |
48 | ||
ef7f180d | 49 | @Override |
522dff53 | 50 | public @Nullable TmfCallsite resolve(ITmfEvent event) { |
ef7f180d AM |
51 | /* This aspect only supports UST traces */ |
52 | if (!(event.getTrace() instanceof LttngUstTrace)) { | |
53 | return null; | |
54 | } | |
cb2b5e56 | 55 | LttngUstTrace trace = (LttngUstTrace) event.getTrace(); |
ef7f180d | 56 | |
ef7f180d | 57 | /* |
df993132 AM |
58 | * Resolve the binary callsite first, from there we can use the file's |
59 | * debug information if it is present. | |
ef7f180d | 60 | */ |
df993132 AM |
61 | BinaryCallsite bc = UstDebugInfoBinaryAspect.INSTANCE.resolve(event); |
62 | if (bc == null) { | |
522dff53 AM |
63 | return null; |
64 | } | |
65 | ||
cb2b5e56 AM |
66 | return getSourceCallsite(trace, bc); |
67 | } | |
68 | ||
69 | /** | |
70 | * Get the source callsite (the full {@link TmfCallsite} information) from a | |
71 | * binary callsite. | |
72 | * | |
73 | * @param trace | |
74 | * The trace, which may contain trace-specific configuration | |
75 | * @param bc | |
76 | * The binary callsite | |
77 | * @return The source callsite, which sould include file name, function name | |
78 | * and line number | |
79 | */ | |
80 | public static @Nullable TmfCallsite getSourceCallsite(LttngUstTrace trace, BinaryCallsite bc) { | |
c84cc3cc AM |
81 | Iterable<TmfCallsite> callsites = FileOffsetMapper.getCallsiteFromOffset( |
82 | new File(bc.getBinaryFilePath()), | |
83 | bc.getBuildId(), | |
84 | bc.getOffset()); | |
522dff53 AM |
85 | |
86 | if (callsites == null || Iterables.isEmpty(callsites)) { | |
87 | return null; | |
88 | } | |
89 | /* | |
90 | * TMF only supports the notion of one callsite per event at the moment. | |
91 | * We will take the "deepest" one in the stack, which should refer to | |
92 | * the initial, non-inlined location. | |
93 | */ | |
cb2b5e56 AM |
94 | TmfCallsite callsite = Iterables.getLast(callsites); |
95 | ||
96 | /* | |
97 | * Apply the path prefix again, this time on the path given from | |
98 | * addr2line. If applicable. | |
99 | */ | |
100 | String pathPrefix = trace.getSymbolProviderConfig().getActualRootDirPath(); | |
101 | if (pathPrefix.isEmpty()) { | |
102 | return callsite; | |
103 | } | |
104 | ||
105 | String fullFileName = (pathPrefix + callsite.getFileName()); | |
106 | return new TmfCallsite(fullFileName, callsite.getFunctionName(), callsite.getLineNumber()); | |
522dff53 | 107 | } |
ef7f180d | 108 | } |