/******************************************************************************* * Copyright (c) 2015 EfficiOS Inc., Alexandre Montplaisir * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html *******************************************************************************/ package org.eclipse.tracecompass.lttng2.ust.core.analysis.debuginfo; import static org.eclipse.tracecompass.common.core.NonNullUtils.nullToEmptyString; import java.io.File; import org.eclipse.jdt.annotation.Nullable; import org.eclipse.tracecompass.internal.lttng2.ust.core.analysis.debuginfo.FileOffsetMapper; import org.eclipse.tracecompass.lttng2.ust.core.trace.LttngUstTrace; import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; import org.eclipse.tracecompass.tmf.core.event.aspect.ITmfEventAspect; import org.eclipse.tracecompass.tmf.core.event.lookup.TmfCallsite; /** * Event aspect of UST traces to generate a {@link TmfCallsite} using the debug * info analysis and the IP (instruction pointer) context. * * @author Alexandre Montplaisir * @since 2.0 */ public class UstDebugInfoSourceAspect implements ITmfEventAspect<TmfCallsite> { /** Singleton instance */ public static final UstDebugInfoSourceAspect INSTANCE = new UstDebugInfoSourceAspect(); private UstDebugInfoSourceAspect() {} @Override public String getName() { return nullToEmptyString(Messages.UstDebugInfoAnalysis_SourceAspectName); } @Override public String getHelpText() { return nullToEmptyString(Messages.UstDebugInfoAnalysis_SourceAspectHelpText); } /** * @since 2.1 */ @Override public @Nullable TmfCallsite resolve(ITmfEvent event) { /* This aspect only supports UST traces */ if (!(event.getTrace() instanceof LttngUstTrace)) { return null; } LttngUstTrace trace = (LttngUstTrace) event.getTrace(); /* * Resolve the binary callsite first, from there we can use the file's * debug information if it is present. */ BinaryCallsite bc = UstDebugInfoBinaryAspect.INSTANCE.resolve(event); if (bc == null) { return null; } TmfCallsite callsite = FileOffsetMapper.getCallsiteFromOffset( new File(bc.getBinaryFilePath()), bc.getBuildId(), bc.getOffset()); if (callsite == null) { return null; } /* * Apply the path prefix again, this time on the path given from * addr2line. If applicable. */ String pathPrefix = trace.getSymbolProviderConfig().getActualRootDirPath(); if (pathPrefix.isEmpty()) { return callsite; } String fullFileName = (pathPrefix + callsite.getFileName()); return new TmfCallsite(fullFileName, callsite.getLineNo()); } /** * Get the source callsite (the full {@link TmfCallsite} information) from a * binary callsite. * * @param trace * The trace, which may contain trace-specific configuration * @param bc * The binary callsite * @return The source callsite, which sould include file name, function name * and line number * @since 2.0 * @deprecated Should not be needed anymore, call aspects's resolve() method * directly. The SourceAspect does not include the function name * anymore. */ @Deprecated public static @Nullable SourceCallsite getSourceCallsite(LttngUstTrace trace, BinaryCallsite bc) { TmfCallsite callsite = FileOffsetMapper.getCallsiteFromOffset( new File(bc.getBinaryFilePath()), bc.getBuildId(), bc.getOffset()); if (callsite == null) { return null; } Long callsiteLineNo = callsite.getLineNo(); long lineNo = (callsiteLineNo == null ? -1 : callsiteLineNo.longValue()); /* * Apply the path prefix again, this time on the path given from * addr2line. If applicable. */ String pathPrefix = trace.getSymbolProviderConfig().getActualRootDirPath(); if (pathPrefix.isEmpty()) { return new SourceCallsite(callsite.getFileName(), null, lineNo); } String fullFileName = (pathPrefix + callsite.getFileName()); return new SourceCallsite(fullFileName, null, lineNo); } }