import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
* register a trace to that type in the TmfEventTypeManager
*/
try (CtfIterator iter = fIteratorManager.getIterator(ctx)) {
+ Set<@NonNull ITmfEventField> streamContextNames = new HashSet<>();
for (IEventDeclaration ied : iter.getEventDeclarations()) {
CtfTmfEventType ctfTmfEventType = fContainedEventTypes.get(ied.getName());
if (ctfTmfEventType == null) {
List<ITmfEventField> content = new ArrayList<>();
+
/* Should only return null the first time */
final StructDeclaration fields = ied.getFields();
if (fields != null) {
for (String fieldName : fields.getFieldsList()) {
content.add(new TmfEventField(checkNotNull(fieldName), null, null));
}
+ }
+
+ /* Add stream contexts */
+ final StructDeclaration streamContexts = ied.getStream().getEventContextDecl();
+ if (streamContextNames.isEmpty()) {
+ if (streamContexts != null) {
+ for (String fieldName : streamContexts.getFieldsList()) {
+ streamContextNames.add(new TmfEventField(checkNotNull(CtfConstants.CONTEXT_FIELD_PREFIX + fieldName), null, null));
+ }
+ }
+ }
+ content.addAll(streamContextNames);
+
+ if (!content.isEmpty()) {
ITmfEventField contentTree = new TmfEventField(
ITmfEventField.ROOT_FIELD_ID,
null,
org.eclipse.ui,
org.eclipse.core.resources,
org.eclipse.core.runtime,
- org.eclipse.tracecompass.lttng2.ust.ui
+ org.eclipse.tracecompass.lttng2.ust.ui,
+ org.eclipse.tracecompass.tmf.core;bundle-version="2.0.0",
+ org.eclipse.tracecompass.tmf.core.tests,
+ org.eclipse.tracecompass.lttng2.ust.core;bundle-version="2.0.0",
+ org.eclipse.tracecompass.tmf.ctf.core;bundle-version="2.0.0"
Export-Package: org.eclipse.tracecompass.lttng2.ust.ui.tests
+Import-Package: com.google.common.collect,
+ com.google.common.primitives
+
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2016 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
+ *******************************************************************************/
+
+package org.eclipse.tracecompass.lttng2.ust.ui.tests.analysis.callstack;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Set;
+
+import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.tracecompass.internal.lttng2.ust.ui.analysis.callstack.LttngUstCallStackAnalysisRequirement;
+import org.eclipse.tracecompass.lttng2.ust.core.trace.LttngUstTrace;
+import org.eclipse.tracecompass.lttng2.ust.core.trace.layout.ILttngUstEventLayout;
+import org.eclipse.tracecompass.tmf.core.event.ITmfEventField;
+import org.eclipse.tracecompass.tmf.core.trace.TmfTrace;
+import org.eclipse.tracecompass.tmf.ctf.core.event.CtfTmfEventType;
+import org.junit.Test;
+
+import com.google.common.collect.ImmutableSet;
+
+/**
+ * Test the {@link LttngUstCallStackAnalysisRequirement} class
+ *
+ * @author Bernd Hufmann
+ */
+public class LTTngUstCallStackAnalysisRequirementTest {
+
+ private static final @NonNull String FUNC_EXIT_FAST = "lttng_ust_cyg_profile_fast:func_exit";
+ private static final @NonNull String FUNC_EXIT = "lttng_ust_cyg_profile:func_exit";
+ private static final @NonNull String FUNC_ENTRY_FAST = "lttng_ust_cyg_profile_fast:func_entry";
+ private static final @NonNull String FUNC_ENTRY = "lttng_ust_cyg_profile:func_entry";
+ private static final @NonNull String OTHER_EVENT = "OTHER";
+
+ private static final @NonNull String CONTEXT_VTID = "context._vtid";
+ private static final @NonNull String CONTEXT_PROCNAME = "context._procname";
+ private static final @NonNull String CONTEXT_OTHER = "context._other";
+
+ /* A trace class with pre-defined events with valid events and fields */
+ private static class TraceWithValidEvents extends LttngUstTrace {
+ @Override
+ public @NonNull Set<@NonNull CtfTmfEventType> getContainedEventTypes() {
+ return ImmutableSet.of(
+ new CtfTmfEventType(FUNC_ENTRY, null) {
+
+ @Override
+ public @NonNull String getName() {
+ return FUNC_ENTRY;
+ }
+
+ @Override
+ public ITmfEventField getRootField() {
+ return null;
+ }
+
+ @Override
+ public Collection<String> getFieldNames() {
+ return ImmutableSet.of(CONTEXT_VTID, CONTEXT_PROCNAME);
+ }
+ },
+ new CtfTmfEventType(FUNC_EXIT, null) {
+ @Override
+ public @NonNull String getName() {
+ return FUNC_EXIT;
+ }
+
+ @Override
+ public ITmfEventField getRootField() {
+ return null;
+ }
+
+ @Override
+ public Collection<String> getFieldNames() {
+ return ImmutableSet.of(CONTEXT_VTID, CONTEXT_PROCNAME);
+ }
+ });
+ }
+ }
+
+ /* A trace class with pre-defined events with valid events and fields */
+ private static class TraceWithValidEventsFast extends LttngUstTrace {
+ @Override
+ public @NonNull Set<@NonNull CtfTmfEventType> getContainedEventTypes() {
+ return ImmutableSet.of(
+ new CtfTmfEventType(FUNC_ENTRY_FAST, null) {
+
+ @Override
+ public @NonNull String getName() {
+ return FUNC_ENTRY_FAST;
+ }
+
+ @Override
+ public ITmfEventField getRootField() {
+ return null;
+ }
+
+ @Override
+ public Collection<String> getFieldNames() {
+ return ImmutableSet.of(CONTEXT_VTID, CONTEXT_PROCNAME);
+ }
+ },
+ new CtfTmfEventType(FUNC_EXIT_FAST, null) {
+ @Override
+ public @NonNull String getName() {
+ return FUNC_EXIT_FAST;
+ }
+
+ @Override
+ public ITmfEventField getRootField() {
+ return null;
+ }
+
+ @Override
+ public Collection<String> getFieldNames() {
+ return ImmutableSet.of(CONTEXT_VTID, CONTEXT_PROCNAME);
+ }
+ });
+ }
+ }
+
+ /*
+ * A trace class with pre-defined events with valid events but missing
+ * fields
+ */
+ private static class TraceWithValidEventsMissingFields extends LttngUstTrace {
+ @Override
+ public @NonNull Set<@NonNull CtfTmfEventType> getContainedEventTypes() {
+ return ImmutableSet.of(
+ new CtfTmfEventType(FUNC_ENTRY, null) {
+ @Override
+ public @NonNull String getName() {
+ return FUNC_ENTRY;
+ }
+
+ @Override
+ public ITmfEventField getRootField() {
+ return null;
+ }
+
+ @Override
+ public Collection<String> getFieldNames() {
+ return Collections.EMPTY_LIST;
+ }
+ },
+ new CtfTmfEventType(FUNC_EXIT, null) {
+ @Override
+ public @NonNull String getName() {
+ return FUNC_EXIT;
+ }
+
+ @Override
+ public ITmfEventField getRootField() {
+ return null;
+ }
+
+ @Override
+ public Collection<String> getFieldNames() {
+ return ImmutableSet.of(CONTEXT_VTID, CONTEXT_PROCNAME);
+ }
+ });
+ }
+ }
+
+ /*
+ * A trace class with pre-defined events with valid events but missing
+ * fields
+ */
+ private static class TraceWithValidEventsMissingFieldsFast extends LttngUstTrace {
+ @Override
+ public @NonNull Set<@NonNull CtfTmfEventType> getContainedEventTypes() {
+ return ImmutableSet.of(
+ new CtfTmfEventType(FUNC_ENTRY_FAST, null) {
+ @Override
+ public @NonNull String getName() {
+ return FUNC_ENTRY_FAST;
+ }
+
+ @Override
+ public ITmfEventField getRootField() {
+ return null;
+ }
+
+ @Override
+ public Collection<String> getFieldNames() {
+ return ImmutableSet.of(CONTEXT_VTID, CONTEXT_PROCNAME);
+ }
+ },
+ new CtfTmfEventType(FUNC_EXIT_FAST, null) {
+ @Override
+ public @NonNull String getName() {
+ return FUNC_EXIT_FAST;
+ }
+
+ @Override
+ public ITmfEventField getRootField() {
+ return null;
+ }
+
+ @Override
+ public Collection<String> getFieldNames() {
+ return Collections.EMPTY_LIST;
+ }
+ });
+ }
+ }
+
+ /*
+ * A trace class with pre-defined events with valid events but missing
+ * fields and other fields
+ */
+ private static class TraceWithValidEventsWrongFields extends LttngUstTrace {
+ @Override
+ public @NonNull Set<@NonNull CtfTmfEventType> getContainedEventTypes() {
+ return ImmutableSet.of(
+ new CtfTmfEventType(FUNC_ENTRY, null) {
+ @Override
+ public @NonNull String getName() {
+ return FUNC_ENTRY;
+ }
+
+ @Override
+ public ITmfEventField getRootField() {
+ return null;
+ }
+
+ @Override
+ public Collection<String> getFieldNames() {
+ return ImmutableSet.of(CONTEXT_OTHER, CONTEXT_PROCNAME);
+ }
+ },
+ new CtfTmfEventType(FUNC_EXIT, null) {
+ @Override
+ public @NonNull String getName() {
+ return FUNC_EXIT;
+ }
+
+ @Override
+ public ITmfEventField getRootField() {
+ return null;
+ }
+
+ @Override
+ public Collection<String> getFieldNames() {
+ return ImmutableSet.of(CONTEXT_OTHER, CONTEXT_PROCNAME);
+ }
+ });
+ }
+ }
+
+ /* A trace class with pre-defined events with missing events */
+ private static class TraceWithMissingEvents extends LttngUstTrace {
+ @Override
+ public @NonNull Set<@NonNull CtfTmfEventType> getContainedEventTypes() {
+ return ImmutableSet.of(
+ new CtfTmfEventType(OTHER_EVENT, null) {
+ @Override
+ public @NonNull String getName() {
+ return OTHER_EVENT;
+ }
+
+ @Override
+ public ITmfEventField getRootField() {
+ return null;
+ }
+
+ @Override
+ public Collection<String> getFieldNames() {
+ return ImmutableSet.of(CONTEXT_VTID, CONTEXT_PROCNAME);
+ }
+ },
+ new CtfTmfEventType(FUNC_EXIT_FAST, null) {
+ @Override
+ public @NonNull String getName() {
+ return FUNC_EXIT_FAST;
+ }
+
+ @Override
+ public ITmfEventField getRootField() {
+ return null;
+ }
+
+ @Override
+ public Collection<String> getFieldNames() {
+ return ImmutableSet.of(CONTEXT_VTID, CONTEXT_PROCNAME);
+ }
+ });
+ }
+ }
+
+ private final @NonNull TmfTrace traceValid = new TraceWithValidEvents();
+ private final @NonNull TmfTrace traceValidFast = new TraceWithValidEventsFast();
+ private final @NonNull TmfTrace traceValidMissingFields = new TraceWithValidEventsMissingFields();
+ private final @NonNull TmfTrace traceValidMissingFiledsFast = new TraceWithValidEventsMissingFieldsFast();
+ private final @NonNull TmfTrace traceValidEventsWrongFields = new TraceWithValidEventsWrongFields();
+ private final @NonNull TmfTrace traceMissingEvents = new TraceWithMissingEvents();
+
+ /**
+ * Test with optional requirements
+ */
+ @Test
+ public void testCallStackRequirements() {
+ /* Test optional requirement */
+ LttngUstCallStackAnalysisRequirement req = new LttngUstCallStackAnalysisRequirement(ILttngUstEventLayout.DEFAULT_LAYOUT);
+ assertTrue(req.test(traceValid));
+ assertTrue(req.test(traceValidFast));
+ assertFalse(req.test(traceValidMissingFields));
+ assertFalse(req.test(traceValidMissingFiledsFast));
+ assertFalse(req.test(traceValidEventsWrongFields));
+ assertFalse(req.test(traceMissingEvents));
+ }
+}
org.eclipse.tracecompass.tmf.ui,
org.eclipse.tracecompass.tmf.ctf.core
Export-Package: org.eclipse.tracecompass.internal.lttng2.ust.ui;x-friends:="org.eclipse.tracecompass.lttng2.ust.ui.tests",
+ org.eclipse.tracecompass.internal.lttng2.ust.ui.analysis.callstack;x-friends:="org.eclipse.tracecompass.lttng2.ust.ui.tests",
org.eclipse.tracecompass.internal.lttng2.ust.ui.views.memusage;x-friends:="org.eclipse.tracecompass.lttng2.ust.ui.tests,org.eclipse.tracecompass.lttng2.ust.ui.swtbot.tests",
org.eclipse.tracecompass.lttng2.ust.ui.analysis.callstack
-Import-Package: org.swtchart
+Import-Package: com.google.common.base,
+ com.google.common.collect,
+ org.swtchart
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2016 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
+ *******************************************************************************/
+package org.eclipse.tracecompass.internal.lttng2.ust.ui.analysis.callstack;
+
+import static org.eclipse.tracecompass.common.core.NonNullUtils.nullToEmptyString;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
+import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.tracecompass.lttng2.ust.core.trace.layout.ILttngUstEventLayout;
+import org.eclipse.tracecompass.tmf.core.analysis.requirements.TmfAnalysisEventFieldRequirement;
+import org.eclipse.tracecompass.tmf.core.analysis.requirements.TmfAnalysisRequirement;
+import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
+
+import com.google.common.collect.ImmutableSet;
+
+/**
+ * Analysis requirement implementation for LTTng Call Stack Analysis.
+ *
+ * @author Bernd Hufmann
+ *
+ */
+@NonNullByDefault
+public class LttngUstCallStackAnalysisRequirement extends TmfAnalysisRequirement {
+
+ private static String REQUIRMENT_TYPE = "event & context"; //$NON-NLS-1$
+
+ private List<TmfAnalysisEventFieldRequirement> fEntryRequirements = new ArrayList<>();
+ private List<TmfAnalysisEventFieldRequirement> fExitRequirements = new ArrayList<>();
+ /**
+ * Constructor
+ *
+ * @param layout
+ * The event layout (non-null)
+ */
+ public LttngUstCallStackAnalysisRequirement(ILttngUstEventLayout layout) {
+ super(REQUIRMENT_TYPE);
+
+ Set<@NonNull String> requiredEventsFields = ImmutableSet.of(
+ layout.contextProcname(),
+ layout.contextVtid());
+ TmfAnalysisEventFieldRequirement requirement = new TmfAnalysisEventFieldRequirement(
+ layout.eventCygProfileFuncEntry(),
+ requiredEventsFields,
+ ValuePriorityLevel.MANDATORY);
+ fEntryRequirements.add(requirement);
+
+ requirement = new TmfAnalysisEventFieldRequirement(
+ layout.eventCygProfileFastFuncEntry(),
+ requiredEventsFields,
+ ValuePriorityLevel.MANDATORY);
+ fEntryRequirements.add(requirement);
+
+ requirement = new TmfAnalysisEventFieldRequirement(
+ layout.eventCygProfileFuncExit(),
+ requiredEventsFields,
+ ValuePriorityLevel.MANDATORY);
+ fExitRequirements.add(requirement);
+
+ requirement = new TmfAnalysisEventFieldRequirement(
+ layout.eventCygProfileFastFuncExit(),
+ requiredEventsFields,
+ ValuePriorityLevel.MANDATORY);
+ fExitRequirements.add(requirement);
+
+ // Add mandatory values (event names and context names)
+ addValue(layout.eventCygProfileFuncEntry(), ValuePriorityLevel.MANDATORY);
+ addValue(layout.eventCygProfileFuncExit(), ValuePriorityLevel.MANDATORY);
+ addValues(requiredEventsFields, ValuePriorityLevel.MANDATORY);
+ addInformation(nullToEmptyString(Messages.LttnUstCallStackAnalysisModule_EventsLoadingInformation));
+ }
+
+ @Override
+ public boolean test(ITmfTrace trace) {
+ boolean fullfilled = fEntryRequirements.stream().anyMatch(requirement -> {
+ return requirement.test(trace);
+ });
+
+ if (fullfilled) {
+ fullfilled = fExitRequirements.stream().anyMatch(requirement -> {
+ return requirement.test(trace);
+ });
+ }
+ return fullfilled;
+ }
+}
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2016 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
+ *******************************************************************************/
+package org.eclipse.tracecompass.internal.lttng2.ust.ui.analysis.callstack;
+
+import org.eclipse.osgi.util.NLS;
+
+/**
+ * Message bundle for the ust memory analysis module
+ *
+ * @author Bernd Hufmann
+ */
+public class Messages extends NLS {
+ private static final String BUNDLE_NAME = "org.eclipse.tracecompass.internal.lttng2.ust.ui.analysis.callstack.messages"; //$NON-NLS-1$
+
+ /** Information regarding events loading prior to the analysis execution */
+ public static String LttnUstCallStackAnalysisModule_EventsLoadingInformation;
+
+ static {
+ // initialize resource bundle
+ NLS.initializeMessages(BUNDLE_NAME, Messages.class);
+ }
+
+ private Messages() {
+ }
+}
--- /dev/null
+###############################################################################
+# Copyright (c) 2016 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
+###############################################################################
+LttnUstCallStackAnalysisModule_EventsLoadingInformation=Add the ''vtid'' and ''procname'' contexts to your trace session. \n\
+Preload the ''liblttng-ust-cyg-profile'' library when running your program: \n\
+LD_PRELOAD=/usr/lib/liblttng-ust-cyg-profile.so ./myprogram
+
/*******************************************************************************
- * Copyright (c) 2014, 2015 Ericsson
+ * Copyright (c) 2014, 2016 Ericsson
*
* All rights reserved. This program and the accompanying materials are
* made available under the terms of the Eclipse Public License v1.0 which
*
* Contributors:
* Alexandre Montplaisir - Initial API and implementation
+ * Bernd Hufmann - Added analysis requirements
*******************************************************************************/
package org.eclipse.tracecompass.lttng2.ust.ui.analysis.callstack;
import static org.eclipse.tracecompass.common.core.NonNullUtils.checkNotNull;
+import java.util.Set;
+
+import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.tracecompass.internal.lttng2.ust.core.callstack.LttngUstCallStackProvider;
+import org.eclipse.tracecompass.internal.lttng2.ust.ui.analysis.callstack.LttngUstCallStackAnalysisRequirement;
import org.eclipse.tracecompass.lttng2.ust.core.trace.LttngUstTrace;
+import org.eclipse.tracecompass.lttng2.ust.core.trace.layout.ILttngUstEventLayout;
+import org.eclipse.tracecompass.tmf.core.analysis.requirements.TmfAnalysisRequirement;
import org.eclipse.tracecompass.tmf.core.exceptions.TmfAnalysisException;
import org.eclipse.tracecompass.tmf.core.statesystem.ITmfStateProvider;
import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
import org.eclipse.tracecompass.tmf.ui.views.callstack.AbstractCallStackAnalysis;
+import com.google.common.collect.ImmutableSet;
+
/**
* Call-stack analysis to populate the TMF CallStack View from UST cyg-profile
* events.
*/
public class LttngUstCallStackAnalysis extends AbstractCallStackAnalysis {
+ private @Nullable Set<@NonNull TmfAnalysisRequirement> fAnalysisRequirements = null;
+
/**
* @since 1.0
*/
return new LttngUstCallStackProvider(checkNotNull(getTrace()));
}
+ @Override
+ public @NonNull Iterable<@NonNull TmfAnalysisRequirement> getAnalysisRequirements() {
+
+ Set<@NonNull TmfAnalysisRequirement> requirements = fAnalysisRequirements;
+ if (requirements == null) {
+ LttngUstTrace trace = getTrace();
+ ILttngUstEventLayout layout = ILttngUstEventLayout.DEFAULT_LAYOUT;
+ if (trace != null) {
+ layout = trace.getEventLayout();
+ }
+ requirements = ImmutableSet.of(new LttngUstCallStackAnalysisRequirement(layout));
+ fAnalysisRequirements = requirements;
+ }
+ return requirements;
+ }
+
+
+
}