/**********************************************************************
* Copyright (c) 2013, 2014 Ericsson
*
* 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
*
* Contributors:
* Matthew Khouzam - Initial API and implementation
* Alexandre Montplaisir - Add UST callstack state system
* Marc-Andre Laperle - Handle BufferOverflowException (Bug 420203)
**********************************************************************/
package org.eclipse.tracecompass.lttng2.ust.core.trace;
import java.util.Collection;
import java.util.Map;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.tracecompass.internal.lttng2.ust.core.Activator;
import org.eclipse.tracecompass.internal.lttng2.ust.core.trace.layout.LttngUst20EventLayout;
import org.eclipse.tracecompass.internal.lttng2.ust.core.trace.layout.LttngUst27EventLayout;
import org.eclipse.tracecompass.internal.lttng2.ust.core.trace.layout.LttngUst28EventLayout;
import org.eclipse.tracecompass.internal.lttng2.ust.core.trace.layout.LttngUst29EventLayout;
import org.eclipse.tracecompass.lttng2.ust.core.analysis.debuginfo.UstDebugInfoBinaryAspect;
import org.eclipse.tracecompass.lttng2.ust.core.analysis.debuginfo.UstDebugInfoFunctionAspect;
import org.eclipse.tracecompass.lttng2.ust.core.analysis.debuginfo.UstDebugInfoSourceAspect;
import org.eclipse.tracecompass.lttng2.ust.core.trace.layout.ILttngUstEventLayout;
import org.eclipse.tracecompass.tmf.core.event.ITmfEvent;
import org.eclipse.tracecompass.tmf.core.event.aspect.ITmfEventAspect;
import org.eclipse.tracecompass.tmf.core.exceptions.TmfTraceException;
import org.eclipse.tracecompass.tmf.core.trace.TraceValidationStatus;
import org.eclipse.tracecompass.tmf.ctf.core.trace.CtfTmfTrace;
import org.eclipse.tracecompass.tmf.ctf.core.trace.CtfTraceValidationStatus;
import org.eclipse.tracecompass.tmf.ctf.core.trace.CtfUtils;
import com.google.common.collect.ImmutableSet;
/**
* Class to contain LTTng-UST traces
*
* @author Matthew Khouzam
*/
public class LttngUstTrace extends CtfTmfTrace {
/**
* Name of the tracer that generates this trace type, as found in the CTF
* metadata.
*
* @since 2.0
*/
public static final String TRACER_NAME = "lttng-ust"; //$NON-NLS-1$
private static final int CONFIDENCE = 100;
private static final @NonNull Collection<ITmfEventAspect<?>> LTTNG_UST_ASPECTS;
static {
ImmutableSet.Builder<ITmfEventAspect<?>> builder = ImmutableSet.builder();
builder.addAll(CtfTmfTrace.CTF_ASPECTS);
builder.add(UstDebugInfoBinaryAspect.INSTANCE);
builder.add(UstDebugInfoFunctionAspect.INSTANCE);
builder.add(UstDebugInfoSourceAspect.INSTANCE);
LTTNG_UST_ASPECTS = builder.build();
}
private @Nullable ILttngUstEventLayout fLayout = null;
/**
* Default constructor
*/
public LttngUstTrace() {
super(LttngUstEventFactory.instance());
}
/**
* Get the event layout to use with this trace. This normally depends on the
* tracer's version.
*
* @return The event layout
* @since 2.0
*/
public @NonNull ILttngUstEventLayout getEventLayout() {
ILttngUstEventLayout layout = fLayout;
if (layout == null) {
throw new IllegalStateException("Cannot get the layout of a non-initialized trace!"); //$NON-NLS-1$
}
return layout;
}
@Override
public void initTrace(IResource resource, String path,
Class<? extends ITmfEvent> eventType) throws TmfTraceException {
super.initTrace(resource, path, eventType);
/* Determine the event layout to use from the tracer's version */
fLayout = getLayoutFromEnv();
}
private @NonNull ILttngUstEventLayout getLayoutFromEnv() {
String tracerName = CtfUtils.getTracerName(this);
int tracerMajor = CtfUtils.getTracerMajorVersion(this);
int tracerMinor = CtfUtils.getTracerMinorVersion(this);
if (TRACER_NAME.equals(tracerName)) {
if (tracerMajor >= 2) {
if (tracerMinor >= 9) {
return LttngUst29EventLayout.getInstance();
} else if (tracerMinor >= 8) {
return LttngUst28EventLayout.getInstance();
} else if (tracerMinor >= 7) {
return LttngUst27EventLayout.getInstance();
}
return LttngUst20EventLayout.getInstance();
}
}
/* Fallback to the UST 2.0 layout and hope for the best */
return LttngUst20EventLayout.getInstance();
}
@Override
public Iterable<ITmfEventAspect<?>> getEventAspects() {
return LTTNG_UST_ASPECTS;
}
/**
* {@inheritDoc}
* <p>
* This implementation sets the confidence to 100 if the trace is a valid
* CTF trace in the "ust" domain.
*/
@Override
public IStatus validate(final IProject project, final String path) {
IStatus status = super.validate(project, path);
if (status instanceof CtfTraceValidationStatus) {
Map<String, String> environment = ((CtfTraceValidationStatus) status).getEnvironment();
/* Make sure the domain is "ust" in the trace's env vars */
String domain = environment.get("domain"); //$NON-NLS-1$
if (domain == null || !domain.equals("\"ust\"")) { //$NON-NLS-1$
return new Status(IStatus.ERROR, Activator.PLUGIN_ID, Messages.LttngUstTrace_DomainError);
}
return new TraceValidationStatus(CONFIDENCE, Activator.PLUGIN_ID);
}
return status;
}
// ------------------------------------------------------------------------
// Fields/methods bridging the Debug-info symbol provider
// ------------------------------------------------------------------------
/*
* FIXME Once the symbol provider is split in core/ui components, the
* UstDebugInfoSymbolProvider should be moved to the core plugin, and this
* here can be removed.
*/
/**
* Configuration of the symbol provider.
*
* @since 2.0
*/
public static class SymbolProviderConfig {
private final boolean fUseCustomRootDir;
private final @NonNull String fCustomRootDirPath;
/**
* Constructor
*
* Note that a path can be specified even if 'useCustomRootDir' is
* false. This will keep the setting in the text field even when it is
* grayed out.
*
* @param useCustomRootDir
* Should a custom directory be used
* @param rootDirPath
* Custom directory path
*/
public SymbolProviderConfig(boolean useCustomRootDir, @NonNull String rootDirPath) {
fUseCustomRootDir = useCustomRootDir;
fCustomRootDirPath = rootDirPath;
}
/**
* @return Should a custom directory be used
*/
public boolean useCustomRootDir() {
return fUseCustomRootDir;
}
/**
* @return The configured root directory
*/
public String getCustomRootDirPath() {
return fCustomRootDirPath;
}
/**
* Return the "real" path to use for symbol resolution. This is a
* convenience method that avoids having to check the state of
* {@link #useCustomRootDir()} separately.
*
* @return The actual root directory to use
*/
public String getActualRootDirPath() {
if (fUseCustomRootDir) {
return fCustomRootDirPath;
}
return ""; //$NON-NLS-1$
}
}
private @NonNull SymbolProviderConfig fCurrentProviderConfig =
/* Default settings for new traces */
new SymbolProviderConfig(false, ""); //$NON-NLS-1$
/**
* Get the current symbol provider configuration for this trace.
*
* @return The current symbol provider configuration
* @since 2.0
*/
public @NonNull SymbolProviderConfig getSymbolProviderConfig() {
return fCurrentProviderConfig;
}
/**
* Set the symbol provider configuration for this trace.
*
* @param config
* The new symbol provider configuration to use
* @since 2.0
*/
public void setSymbolProviderConfig(@NonNull SymbolProviderConfig config) {
fCurrentProviderConfig = config;
}
}