From 50659279e26898d8b23b1a4719cbe0b7ddb9af26 Mon Sep 17 00:00:00 2001 From: Alexandre Montplaisir Date: Fri, 7 Feb 2014 16:28:30 -0500 Subject: [PATCH] lttng: Migrate LTTng-UST CallStack to the analysis framework Reworked the tests a bit for less copy-paste. Change-Id: Ibd8587dfd41464e9f5e54fbaa3f6dd22cfabadfe Signed-off-by: Alexandre Montplaisir Reviewed-on: https://git.eclipse.org/r/21788 Reviewed-by: Genevieve Bastien IP-Clean: Genevieve Bastien --- .../trace/callstack/AbstractProviderTest.java | 287 ++++++++++++++++++ .../LttngUstCallStackProviderFastTest.java | 148 +-------- .../LttngUstCallStackProviderTest.java | 182 +---------- .../core/tests/trace/callstack/TestUtils.java | 93 ------ .../META-INF/MANIFEST.MF | 2 +- .../callstack/LttngUstCallStackProvider.java | 9 +- .../lttng2/ust/core/trace/LttngUstTrace.java | 33 -- .../META-INF/MANIFEST.MF | 1 + .../plugin.properties | 2 + .../plugin.xml | 13 + .../callstack/LttngUstCallStackAnalysis.java | 49 +++ .../callstack/CallStackStateProvider.java | 4 +- .../callstack/AbstractCallStackAnalysis.java | 41 +++ .../CallStackPresentationProvider.java | 11 +- .../tmf/ui/views/callstack/CallStackView.java | 80 ++++- 15 files changed, 500 insertions(+), 455 deletions(-) create mode 100644 org.eclipse.linuxtools.lttng2.ust.core.tests/src/org/eclipse/linuxtools/lttng2/ust/core/tests/trace/callstack/AbstractProviderTest.java delete mode 100644 org.eclipse.linuxtools.lttng2.ust.core.tests/src/org/eclipse/linuxtools/lttng2/ust/core/tests/trace/callstack/TestUtils.java create mode 100644 org.eclipse.linuxtools.lttng2.ust.ui/src/org/eclipse/linuxtools/lttng2/ust/ui/analysis/callstack/LttngUstCallStackAnalysis.java create mode 100644 org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/callstack/AbstractCallStackAnalysis.java diff --git a/org.eclipse.linuxtools.lttng2.ust.core.tests/src/org/eclipse/linuxtools/lttng2/ust/core/tests/trace/callstack/AbstractProviderTest.java b/org.eclipse.linuxtools.lttng2.ust.core.tests/src/org/eclipse/linuxtools/lttng2/ust/core/tests/trace/callstack/AbstractProviderTest.java new file mode 100644 index 0000000000..07f5518e48 --- /dev/null +++ b/org.eclipse.linuxtools.lttng2.ust.core.tests/src/org/eclipse/linuxtools/lttng2/ust/core/tests/trace/callstack/AbstractProviderTest.java @@ -0,0 +1,287 @@ +/******************************************************************************* + * Copyright (c) 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: + * Alexandre Montplaisir - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.linuxtools.lttng2.ust.core.tests.trace.callstack; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; +import static org.junit.Assume.assumeTrue; + +import java.io.File; +import java.util.List; + +import org.eclipse.linuxtools.internal.lttng2.ust.core.trace.callstack.LttngUstCallStackProvider; +import org.eclipse.linuxtools.tmf.core.ctfadaptor.CtfTmfTrace; +import org.eclipse.linuxtools.tmf.core.exceptions.AttributeNotFoundException; +import org.eclipse.linuxtools.tmf.core.exceptions.StateSystemDisposedException; +import org.eclipse.linuxtools.tmf.core.exceptions.TmfAnalysisException; +import org.eclipse.linuxtools.tmf.core.interval.ITmfStateInterval; +import org.eclipse.linuxtools.tmf.core.statesystem.ITmfStateProvider; +import org.eclipse.linuxtools.tmf.core.statesystem.ITmfStateSystem; +import org.eclipse.linuxtools.tmf.core.statesystem.TmfStateSystemAnalysisModule; +import org.eclipse.linuxtools.tmf.core.statevalue.ITmfStateValue; +import org.eclipse.linuxtools.tmf.core.tests.shared.CtfTmfTestTrace; +import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp; +import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; +import org.eclipse.linuxtools.tmf.core.trace.TmfTraceManager; +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TestRule; +import org.junit.rules.Timeout; + +/** + * Base class for the UST callstack state provider tests. + * + * @author Alexandre Montplaisir + */ +public abstract class AbstractProviderTest { + + /** Time-out tests after 20 seconds */ + @Rule public TestRule globalTimeout= new Timeout(20000); + + // ------------------------------------------------------------------------ + // Attributes + // ------------------------------------------------------------------------ + + private static final CtfTmfTestTrace otherUstTrace = CtfTmfTestTrace.HELLO_LOST; + + private CtfTmfTrace fTrace = null; + private ITmfStateSystem fSS = null; + + // ------------------------------------------------------------------------ + // Abstract methods + // ------------------------------------------------------------------------ + + /** + * @return The test trace to use for this test + */ + protected abstract CtfTmfTestTrace getTestTrace(); + + /** + * @return The name of the executable process in that particular trace + */ + protected abstract String getProcName(); + + /** + * Get the list of timestamps to query in that trace. + * + * @param index + * Which of the test timestamps? + * @return That particular timestamp + */ + protected abstract long getTestTimestamp(int index); + + // ------------------------------------------------------------------------ + // Maintenance + // ------------------------------------------------------------------------ + + /** + * Perform pre-class initialization. + */ + @Before + public void setUp() { + CtfTmfTestTrace testTrace = getTestTrace(); + assumeTrue(testTrace.exists()); + + fTrace = testTrace.getTrace(); + TestLttngCallStackModule module = new TestLttngCallStackModule(); + try { + module.setTrace(fTrace); + } catch (TmfAnalysisException e) { + fail(); + } + module.schedule(); + assertTrue(module.waitForCompletion()); + + fSS = module.getStateSystem(); + assertNotNull(fSS); + } + + /** + * Perform post-class clean-up. + */ + @After + public void tearDown() { + if (fTrace != null) { + fTrace.dispose(); + File suppDir = new File(TmfTraceManager.getSupplementaryFileDir(fTrace)); + deleteDirectory(suppDir); + } + } + + // ------------------------------------------------------------------------ + // Test methods + // ------------------------------------------------------------------------ + + /** + * Test the handling of generic UST traces who do not contain the required + * information. + */ + @Test + public void testOtherUstTrace() { + /* Initialize the trace and analysis module */ + final ITmfTrace ustTrace = otherUstTrace.getTrace(); + TestLttngCallStackModule module = new TestLttngCallStackModule(); + try { + module.setTrace(ustTrace); + } catch (TmfAnalysisException e) { + fail(); + } + module.schedule(); + assertTrue(module.waitForCompletion()); + + /* Make sure the generated state system exists, but is empty */ + ITmfStateSystem ss = module.getStateSystem(); + assertNotNull(ss); + assertTrue(ss.getStartTime() >= ustTrace.getStartTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue()); + assertEquals(0, ss.getNbAttributes()); + + /* Dispose the trace */ + ustTrace.dispose(); + File suppDir = new File(TmfTraceManager.getSupplementaryFileDir(ustTrace)); + deleteDirectory(suppDir); + assertFalse(suppDir.exists()); + } + + /** + * Test that the callstack state system is there and contains data. + */ + @Test + public void testConstruction() { + assertNotNull(fSS); + assertTrue(fSS.getNbAttributes() > 0); + } + + /** + * Test the callstack at the beginning of the state system. + */ + @Test + public void testCallStackBegin() { + long start = fSS.getStartTime(); + String[] cs = getCallStack(fSS, getProcName(), start); + assertEquals(1, cs.length); + + assertEquals("40472b", cs[0]); + } + + /** + * Test the callstack somewhere in the trace. + */ + @Test + public void testCallStack1() { + String[] cs = getCallStack(fSS, getProcName(), getTestTimestamp(0)); + assertEquals(2, cs.length); + + assertEquals("40472b", cs[0]); + assertEquals("403d60", cs[1]); + } + + /** + * Test the callstack somewhere in the trace. + */ + @Test + public void testCallStack2() { + String[] cs = getCallStack(fSS, getProcName(), getTestTimestamp(1)); + assertEquals(3, cs.length); + + assertEquals("40472b", cs[0]); + assertEquals("403b14", cs[1]); + assertEquals("401b23", cs[2]); + } + + /** + * Test the callstack somewhere in the trace. + */ + @Test + public void testCallStack3() { + String[] cs = getCallStack(fSS, getProcName(), getTestTimestamp(2)); + assertEquals(4, cs.length); + + assertEquals("40472b", cs[0]); + assertEquals("4045c8", cs[1]); + assertEquals("403760", cs[2]); + assertEquals("401aac", cs[3]); + } + + /** + * Test the callstack at the end of the trace/state system. + */ + @Test + public void testCallStackEnd() { + long end = fSS.getCurrentEndTime(); + String[] cs = getCallStack(fSS, getProcName(), end); + assertEquals(3, cs.length); + + assertEquals("40472b", cs[0]); + assertEquals("4045c8", cs[1]); + assertEquals("403760", cs[2]); + } + + // ------------------------------------------------------------------------ + // Utility methods + // ------------------------------------------------------------------------ + + /** Empty and delete a directory */ + private static void deleteDirectory(File dir) { + /* Assuming the dir only contains file or empty directories */ + for (File file : dir.listFiles()) { + file.delete(); + } + dir.delete(); + } + + /** Get the callstack for the given timestamp, for this particular trace */ + private static String[] getCallStack(ITmfStateSystem ss, String processName, long timestamp) { + try { + int stackAttribute = ss.getQuarkAbsolute("Threads", processName, "CallStack"); + List state = ss.queryFullState(timestamp); + int depth = state.get(stackAttribute).getStateValue().unboxInt(); + + int stackTop = ss.getQuarkRelative(stackAttribute, String.valueOf(depth)); + ITmfStateValue top = state.get(stackTop).getStateValue(); + assertEquals(top, ss.querySingleStackTop(timestamp, stackAttribute).getStateValue()); + + String[] ret = new String[depth]; + for (int i = 0; i < depth; i++) { + int quark = ss.getQuarkRelative(stackAttribute, String.valueOf(i + 1)); + ret[i] = state.get(quark).getStateValue().unboxStr(); + } + return ret; + + } catch (AttributeNotFoundException e) { + fail(e.getMessage()); + } catch (StateSystemDisposedException e) { + fail(e.getMessage()); + } + fail(); + return null; + } + + private class TestLttngCallStackModule extends TmfStateSystemAnalysisModule { + + @Override + protected ITmfStateProvider createStateProvider() { + return new LttngUstCallStackProvider(getTrace()); + } + + @Override + protected StateSystemBackendType getBackendType() { + return StateSystemBackendType.FULL; + } + + } +} diff --git a/org.eclipse.linuxtools.lttng2.ust.core.tests/src/org/eclipse/linuxtools/lttng2/ust/core/tests/trace/callstack/LttngUstCallStackProviderFastTest.java b/org.eclipse.linuxtools.lttng2.ust.core.tests/src/org/eclipse/linuxtools/lttng2/ust/core/tests/trace/callstack/LttngUstCallStackProviderFastTest.java index 06a2196566..c4403bda19 100644 --- a/org.eclipse.linuxtools.lttng2.ust.core.tests/src/org/eclipse/linuxtools/lttng2/ust/core/tests/trace/callstack/LttngUstCallStackProviderFastTest.java +++ b/org.eclipse.linuxtools.lttng2.ust.core.tests/src/org/eclipse/linuxtools/lttng2/ust/core/tests/trace/callstack/LttngUstCallStackProviderFastTest.java @@ -12,24 +12,7 @@ package org.eclipse.linuxtools.lttng2.ust.core.tests.trace.callstack; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; -import static org.junit.Assume.assumeTrue; - -import java.io.File; - -import org.eclipse.core.resources.IResource; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.linuxtools.lttng2.ust.core.trace.LttngUstTrace; -import org.eclipse.linuxtools.tmf.core.ctfadaptor.CtfTmfEvent; -import org.eclipse.linuxtools.tmf.core.exceptions.TmfTraceException; -import org.eclipse.linuxtools.tmf.core.statesystem.ITmfStateSystem; import org.eclipse.linuxtools.tmf.core.tests.shared.CtfTmfTestTrace; -import org.eclipse.linuxtools.tmf.core.trace.TmfTraceManager; -import org.junit.AfterClass; -import org.junit.BeforeClass; -import org.junit.Test; /** * Test suite for the UST callstack state provider, using the trace of a program @@ -38,128 +21,25 @@ import org.junit.Test; * * @author Alexandre Montplaisir */ -public class LttngUstCallStackProviderFastTest { - - // ------------------------------------------------------------------------ - // Attributes - // ------------------------------------------------------------------------ - - private static final CtfTmfTestTrace testTrace = CtfTmfTestTrace.CYG_PROFILE_FAST; - - private static final String PROCNAME = "glxgears-29822"; - - private static LttngUstTrace fixture = null; - - // ------------------------------------------------------------------------ - // Class methods - // ------------------------------------------------------------------------ - - /** - * Perform pre-class initialization. - * - * @throws TmfTraceException - * If the test trace is not found - */ - @BeforeClass - public static void setUp() throws TmfTraceException { - assumeTrue(testTrace.exists()); - - /* We init the trace ourselves (we need the specific LttngUstTrace type) */ - fixture = new LttngUstTrace(); - IStatus valid = fixture.validate(null, testTrace.getPath()); - assertTrue(valid.isOK()); - fixture.initTrace((IResource) null, testTrace.getPath(), CtfTmfEvent.class); - TestUtils.openTrace(fixture); - } - - /** - * Perform post-class clean-up. - */ - @AfterClass - public static void tearDown() { - if (fixture != null) { - fixture.dispose(); - File suppDir = new File(TmfTraceManager.getSupplementaryFileDir(fixture)); - TestUtils.deleteDirectory(suppDir); - } - } - - // ------------------------------------------------------------------------ - // Test methods - // ------------------------------------------------------------------------ - - /** - * Test that the callstack state system is there and contains data. - */ - @Test - public void testConstruction() { - ITmfStateSystem ss = fixture.getStateSystems().get(TestUtils.SSID); - assertNotNull(ss); - assertTrue(ss.getNbAttributes() > 0); - } +public class LttngUstCallStackProviderFastTest extends AbstractProviderTest { - /** - * Test the callstack at the beginning of the state system. - */ - @Test - public void testCallStackBegin() { - long start = fixture.getStateSystems().get(TestUtils.SSID).getStartTime(); - String[] cs = TestUtils.getCallStack(fixture, PROCNAME, start); - assertEquals(1, cs.length); + private static final long[] timestamps = { 1379361250310000000L, + 1379361250498400000L, + 1379361250499759000L }; - assertEquals("40472b", cs[0]); + @Override + protected CtfTmfTestTrace getTestTrace() { + return CtfTmfTestTrace.CYG_PROFILE_FAST; } - /** - * Test the callstack somewhere in the trace. - */ - @Test - public void testCallStack1() { - String[] cs = TestUtils.getCallStack(fixture, PROCNAME, 1379361250310000000L); - assertEquals(2, cs.length); - - assertEquals("40472b", cs[0]); - assertEquals("403d60", cs[1]); + @Override + protected String getProcName() { + return "glxgears-29822"; } - /** - * Test the callstack somewhere in the trace. - */ - @Test - public void testCallStack2() { - String[] cs = TestUtils.getCallStack(fixture, PROCNAME, 1379361250498400000L); - assertEquals(3, cs.length); - - assertEquals("40472b", cs[0]); - assertEquals("403b14", cs[1]); - assertEquals("401b23", cs[2]); + @Override + protected long getTestTimestamp(int index) { + return timestamps[index]; } - /** - * Test the callstack somewhere in the trace. - */ - @Test - public void testCallStack3() { - String[] cs = TestUtils.getCallStack(fixture, PROCNAME, 1379361250499759000L); - assertEquals(4, cs.length); - - assertEquals("40472b", cs[0]); - assertEquals("4045c8", cs[1]); - assertEquals("403760", cs[2]); - assertEquals("401aac", cs[3]); - } - - /** - * Test the callstack at the end of the trace/state system. - */ - @Test - public void testCallStackEnd() { - long end = fixture.getStateSystems().get(TestUtils.SSID).getCurrentEndTime(); - String[] cs = TestUtils.getCallStack(fixture, PROCNAME, end); - assertEquals(3, cs.length); - - assertEquals("40472b", cs[0]); - assertEquals("4045c8", cs[1]); - assertEquals("403760", cs[2]); - } -} +} \ No newline at end of file diff --git a/org.eclipse.linuxtools.lttng2.ust.core.tests/src/org/eclipse/linuxtools/lttng2/ust/core/tests/trace/callstack/LttngUstCallStackProviderTest.java b/org.eclipse.linuxtools.lttng2.ust.core.tests/src/org/eclipse/linuxtools/lttng2/ust/core/tests/trace/callstack/LttngUstCallStackProviderTest.java index 8e86fa8cb1..cf0b756724 100644 --- a/org.eclipse.linuxtools.lttng2.ust.core.tests/src/org/eclipse/linuxtools/lttng2/ust/core/tests/trace/callstack/LttngUstCallStackProviderTest.java +++ b/org.eclipse.linuxtools.lttng2.ust.core.tests/src/org/eclipse/linuxtools/lttng2/ust/core/tests/trace/callstack/LttngUstCallStackProviderTest.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2013 Ericsson + * 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 @@ -12,27 +12,7 @@ package org.eclipse.linuxtools.lttng2.ust.core.tests.trace.callstack; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; -import static org.junit.Assume.assumeTrue; - -import java.io.File; - -import org.eclipse.core.resources.IResource; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.linuxtools.lttng2.ust.core.trace.LttngUstTrace; -import org.eclipse.linuxtools.tmf.core.ctfadaptor.CtfTmfEvent; -import org.eclipse.linuxtools.tmf.core.exceptions.TmfTraceException; -import org.eclipse.linuxtools.tmf.core.statesystem.ITmfStateSystem; import org.eclipse.linuxtools.tmf.core.tests.shared.CtfTmfTestTrace; -import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp; -import org.eclipse.linuxtools.tmf.core.trace.TmfTraceManager; -import org.junit.AfterClass; -import org.junit.BeforeClass; -import org.junit.Test; /** * Test suite for the UST callstack state provider, using the trace of a program @@ -40,159 +20,25 @@ import org.junit.Test; * * @author Alexandre Montplaisir */ -public class LttngUstCallStackProviderTest { - - // ------------------------------------------------------------------------ - // Attributes - // ------------------------------------------------------------------------ - - private static final CtfTmfTestTrace testTrace = CtfTmfTestTrace.CYG_PROFILE; - private static final CtfTmfTestTrace otherUstTrace = CtfTmfTestTrace.HELLO_LOST; - - private static final String PROCNAME = "glxgears-16073"; - - private static LttngUstTrace fixture = null; - - // ------------------------------------------------------------------------ - // Class methods - // ------------------------------------------------------------------------ - - /** - * Perform pre-class initialization. - * - * @throws TmfTraceException - * If the test trace is not found - */ - @BeforeClass - public static void setUp() throws TmfTraceException { - assumeTrue(testTrace.exists()); - - /* We init the trace ourselves (we need the specific LttngUstTrace type) */ - fixture = new LttngUstTrace(); - IStatus valid = fixture.validate(null, testTrace.getPath()); - assertTrue(valid.isOK()); - fixture.initTrace((IResource) null, testTrace.getPath(), CtfTmfEvent.class); - TestUtils.openTrace(fixture); - } - - /** - * Perform post-class clean-up. - */ - @AfterClass - public static void tearDown() { - if (fixture != null) { - fixture.dispose(); - File suppDir = new File(TmfTraceManager.getSupplementaryFileDir(fixture)); - TestUtils.deleteDirectory(suppDir); - } - } - - // ------------------------------------------------------------------------ - // Test methods - // ------------------------------------------------------------------------ +public class LttngUstCallStackProviderTest extends AbstractProviderTest { - /** - * Test the handling of generic UST traces who do not contain the required - * information. - */ - @Test - public void testOtherUstTrace() { - /* Initialize the trace */ - final LttngUstTrace ustTrace = new LttngUstTrace(); - IStatus valid = ustTrace.validate(null, otherUstTrace.getPath()); - assertTrue(valid.isOK()); - try { - ustTrace.initTrace((IResource) null, otherUstTrace.getPath(), CtfTmfEvent.class); - } catch (TmfTraceException e) { - fail(e.getMessage()); - } - TestUtils.openTrace(ustTrace); + private static final long[] timestamps = { 1378850463600000000L, + 1378850463770000000L, + 1378850463868753000L }; - /* Make sure the generated state system exists, but is empty */ - ITmfStateSystem ss = ustTrace.getStateSystems().get(TestUtils.SSID); - assertNotNull(ss); - assertTrue(ss.getStartTime() >= ustTrace.getStartTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue()); - assertEquals(0, ss.getNbAttributes()); - - /* Dispose the trace */ - ustTrace.dispose(); - File suppDir = new File(TmfTraceManager.getSupplementaryFileDir(ustTrace)); - TestUtils.deleteDirectory(suppDir); - assertFalse(suppDir.exists()); + @Override + protected CtfTmfTestTrace getTestTrace() { + return CtfTmfTestTrace.CYG_PROFILE; } - /** - * Test that the callstack state system is there and contains data. - */ - @Test - public void testConstruction() { - ITmfStateSystem ss = fixture.getStateSystems().get(TestUtils.SSID); - assertNotNull(ss); - assertTrue(ss.getNbAttributes() > 0); + @Override + protected String getProcName() { + return "glxgears-16073"; } - /** - * Test the callstack at the beginning of the state system. - */ - @Test - public void testCallStackBegin() { - long start = fixture.getStateSystems().get(TestUtils.SSID).getStartTime(); - String[] cs = TestUtils.getCallStack(fixture, PROCNAME, start); - assertEquals(1, cs.length); - - assertEquals("40472b", cs[0]); + @Override + protected long getTestTimestamp(int index) { + return timestamps[index]; } - /** - * Test the callstack somewhere in the trace. - */ - @Test - public void testCallStack1() { - String[] cs = TestUtils.getCallStack(fixture, PROCNAME, 1378850463600000000L); - assertEquals(2, cs.length); - - assertEquals("40472b", cs[0]); - assertEquals("403d60", cs[1]); - } - - /** - * Test the callstack somewhere in the trace. - */ - @Test - public void testCallStack2() { - String[] cs = TestUtils.getCallStack(fixture, PROCNAME, 1378850463770000000L); - assertEquals(3, cs.length); - - assertEquals("40472b", cs[0]); - assertEquals("403b14", cs[1]); - assertEquals("401b23", cs[2]); - } - - /** - * Test the callstack somewhere in the trace. - */ - @Test - public void testCallStack3() { - String[] cs = TestUtils.getCallStack(fixture, PROCNAME, 1378850463868753000L); - assertEquals(4, cs.length); - - assertEquals("40472b", cs[0]); - assertEquals("4045c8", cs[1]); - assertEquals("403760", cs[2]); - assertEquals("401aac", cs[3]); - } - - /** - * Test the callstack at the end of the trace/state system. - */ - @Test - public void testCallStackEnd() { - long end = fixture.getStateSystems().get(TestUtils.SSID).getCurrentEndTime(); - String[] cs = TestUtils.getCallStack(fixture, PROCNAME, end); - assertEquals(3, cs.length); - - assertEquals("40472b", cs[0]); - assertEquals("4045c8", cs[1]); - assertEquals("403760", cs[2]); - } } diff --git a/org.eclipse.linuxtools.lttng2.ust.core.tests/src/org/eclipse/linuxtools/lttng2/ust/core/tests/trace/callstack/TestUtils.java b/org.eclipse.linuxtools.lttng2.ust.core.tests/src/org/eclipse/linuxtools/lttng2/ust/core/tests/trace/callstack/TestUtils.java deleted file mode 100644 index 3b5b23cf68..0000000000 --- a/org.eclipse.linuxtools.lttng2.ust.core.tests/src/org/eclipse/linuxtools/lttng2/ust/core/tests/trace/callstack/TestUtils.java +++ /dev/null @@ -1,93 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 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: - * Alexandre Montplaisir - Initial implementation - *******************************************************************************/ - -package org.eclipse.linuxtools.lttng2.ust.core.tests.trace.callstack; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.fail; - -import java.io.File; -import java.util.List; - -import org.eclipse.linuxtools.lttng2.ust.core.trace.LttngUstTrace; -import org.eclipse.linuxtools.tmf.core.callstack.CallStackStateProvider; -import org.eclipse.linuxtools.tmf.core.exceptions.AttributeNotFoundException; -import org.eclipse.linuxtools.tmf.core.exceptions.StateSystemDisposedException; -import org.eclipse.linuxtools.tmf.core.exceptions.StateValueTypeException; -import org.eclipse.linuxtools.tmf.core.exceptions.TimeRangeException; -import org.eclipse.linuxtools.tmf.core.interval.ITmfStateInterval; -import org.eclipse.linuxtools.tmf.core.signal.TmfSignalManager; -import org.eclipse.linuxtools.tmf.core.signal.TmfTraceOpenedSignal; -import org.eclipse.linuxtools.tmf.core.statesystem.ITmfStateSystem; -import org.eclipse.linuxtools.tmf.core.statevalue.ITmfStateValue; - -/** - * Common methods for LTTng-UST callstack trace tests. - * - * @author Alexandre Montplaisir - */ -final class TestUtils { - - private TestUtils() {} - - /** ID of the generated state systems */ - static final String SSID = CallStackStateProvider.ID; - - /** Empty and delete a directory */ - static void deleteDirectory(File dir) { - /* Assuming the dir only contains file or empty directories */ - for (File file : dir.listFiles()) { - file.delete(); - } - dir.delete(); - } - - /** Simulate a trace being opened (which triggers building the state system) */ - static void openTrace(LttngUstTrace trace) { - trace.indexTrace(true); - TmfSignalManager.dispatchSignal(new TmfTraceOpenedSignal(trace, trace, null)); - trace.getStateSystems().get(SSID).waitUntilBuilt(); - } - - /** Get the callstack for the given timestamp, for this particular trace */ - static String[] getCallStack(LttngUstTrace trace, String processName, long timestamp) { - try { - ITmfStateSystem ss = trace.getStateSystems().get(SSID); - int stackAttribute = ss.getQuarkAbsolute("Threads", processName, "CallStack"); - List state = ss.queryFullState(timestamp); - int depth = state.get(stackAttribute).getStateValue().unboxInt(); - - int stackTop = ss.getQuarkRelative(stackAttribute, String.valueOf(depth)); - ITmfStateValue top = state.get(stackTop).getStateValue(); - assertEquals(top, ss.querySingleStackTop(timestamp, stackAttribute).getStateValue()); - - String[] ret = new String[depth]; - for (int i = 0; i < depth; i++) { - int quark = ss.getQuarkRelative(stackAttribute, String.valueOf(i + 1)); - ret[i] = state.get(quark).getStateValue().unboxStr(); - } - return ret; - - } catch (AttributeNotFoundException e) { - fail(e.getMessage()); - } catch (TimeRangeException e) { - fail(e.getMessage()); - } catch (StateSystemDisposedException e) { - fail(e.getMessage()); - } catch (StateValueTypeException e) { - fail(e.getMessage()); - } - fail(); - return null; - } - -} diff --git a/org.eclipse.linuxtools.lttng2.ust.core/META-INF/MANIFEST.MF b/org.eclipse.linuxtools.lttng2.ust.core/META-INF/MANIFEST.MF index 12f92600f3..156182f69d 100644 --- a/org.eclipse.linuxtools.lttng2.ust.core/META-INF/MANIFEST.MF +++ b/org.eclipse.linuxtools.lttng2.ust.core/META-INF/MANIFEST.MF @@ -10,7 +10,7 @@ Bundle-ActivationPolicy: lazy Bundle-RequiredExecutionEnvironment: JavaSE-1.7 Export-Package: org.eclipse.linuxtools.internal.lttng2.ust.core;x-internal:=true, org.eclipse.linuxtools.internal.lttng2.ust.core.memoryusage;x-friends:="org.eclipse.linuxtools.lttng2.ust.ui", - org.eclipse.linuxtools.internal.lttng2.ust.core.trace.callstack;x-internal:=true, + org.eclipse.linuxtools.internal.lttng2.ust.core.trace.callstack;x-friends:="org.eclipse.linuxtools.lttng2.ust.ui,org.eclipse.linuxtools.lttng2.ust.core.tests", org.eclipse.linuxtools.lttng2.ust.core.trace Require-Bundle: org.eclipse.core.runtime, org.eclipse.core.resources, diff --git a/org.eclipse.linuxtools.lttng2.ust.core/src/org/eclipse/linuxtools/internal/lttng2/ust/core/trace/callstack/LttngUstCallStackProvider.java b/org.eclipse.linuxtools.lttng2.ust.core/src/org/eclipse/linuxtools/internal/lttng2/ust/core/trace/callstack/LttngUstCallStackProvider.java index 72850bd6fc..65a410b4c2 100644 --- a/org.eclipse.linuxtools.lttng2.ust.core/src/org/eclipse/linuxtools/internal/lttng2/ust/core/trace/callstack/LttngUstCallStackProvider.java +++ b/org.eclipse.linuxtools.lttng2.ust.core/src/org/eclipse/linuxtools/internal/lttng2/ust/core/trace/callstack/LttngUstCallStackProvider.java @@ -20,6 +20,7 @@ import org.eclipse.linuxtools.tmf.core.callstack.CallStackStateProvider; import org.eclipse.linuxtools.tmf.core.ctfadaptor.CtfTmfEvent; import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; import org.eclipse.linuxtools.tmf.core.event.ITmfEventField; +import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; /** * Callstack provider for LTTng-UST traces. @@ -80,7 +81,7 @@ public class LttngUstCallStackProvider extends CallStackStateProvider { * @param trace * The UST trace */ - public LttngUstCallStackProvider(LttngUstTrace trace) { + public LttngUstCallStackProvider(ITmfTrace trace) { super(trace); } @@ -88,12 +89,6 @@ public class LttngUstCallStackProvider extends CallStackStateProvider { // Methods from AbstractTmfStateProvider // ------------------------------------------------------------------------ - @Override - public LttngUstTrace getTrace() { - /* Type is enforced by the constructor */ - return (LttngUstTrace) super.getTrace(); - } - @Override public LttngUstCallStackProvider getNewInstance() { return new LttngUstCallStackProvider(getTrace()); diff --git a/org.eclipse.linuxtools.lttng2.ust.core/src/org/eclipse/linuxtools/lttng2/ust/core/trace/LttngUstTrace.java b/org.eclipse.linuxtools.lttng2.ust.core/src/org/eclipse/linuxtools/lttng2/ust/core/trace/LttngUstTrace.java index 8148637634..52200be7fa 100644 --- a/org.eclipse.linuxtools.lttng2.ust.core/src/org/eclipse/linuxtools/lttng2/ust/core/trace/LttngUstTrace.java +++ b/org.eclipse.linuxtools.lttng2.ust.core/src/org/eclipse/linuxtools/lttng2/ust/core/trace/LttngUstTrace.java @@ -14,7 +14,6 @@ package org.eclipse.linuxtools.lttng2.ust.core.trace; -import java.io.File; import java.nio.BufferOverflowException; import org.eclipse.core.resources.IProject; @@ -23,14 +22,7 @@ import org.eclipse.core.runtime.Status; import org.eclipse.linuxtools.ctf.core.trace.CTFReaderException; import org.eclipse.linuxtools.ctf.core.trace.CTFTrace; import org.eclipse.linuxtools.internal.lttng2.ust.core.Activator; -import org.eclipse.linuxtools.internal.lttng2.ust.core.trace.callstack.LttngUstCallStackProvider; -import org.eclipse.linuxtools.tmf.core.callstack.CallStackStateProvider; import org.eclipse.linuxtools.tmf.core.ctfadaptor.CtfTmfTrace; -import org.eclipse.linuxtools.tmf.core.exceptions.TmfTraceException; -import org.eclipse.linuxtools.tmf.core.statesystem.ITmfStateProvider; -import org.eclipse.linuxtools.tmf.core.statesystem.ITmfStateSystem; -import org.eclipse.linuxtools.tmf.core.statesystem.TmfStateSystemFactory; -import org.eclipse.linuxtools.tmf.core.trace.TmfTraceManager; /** * Class to contain LTTng-UST traces @@ -40,9 +32,6 @@ import org.eclipse.linuxtools.tmf.core.trace.TmfTraceManager; */ public class LttngUstTrace extends CtfTmfTrace { - /** Name of the history file for the callstack state system */ - private static final String CALLSTACK_FILENAME = "ust-callstack.ht"; //$NON-NLS-1$ - /** * Default constructor */ @@ -77,26 +66,4 @@ public class LttngUstTrace extends CtfTmfTrace { status = new Status(IStatus.ERROR, Activator.PLUGIN_ID, Messages.LttngUstTrace_DomainError); return status; } - - @Override - public IStatus buildStateSystem() { - super.buildStateSystem(); - - /* - * Build the state system for the UST Callstack (will be empty if the - * required events are not present). - */ - String directory = TmfTraceManager.getSupplementaryFileDir(this); - final File htFile = new File(directory + CALLSTACK_FILENAME); - ITmfStateProvider csInput = new LttngUstCallStackProvider(this); - - try { - ITmfStateSystem ss = TmfStateSystemFactory.newFullHistory(htFile, csInput, false); - registerStateSystem(CallStackStateProvider.ID, ss); - } catch (TmfTraceException e) { - return new Status(IStatus.ERROR, Activator.PLUGIN_ID, e.getMessage(), e); - } - - return Status.OK_STATUS; - } } diff --git a/org.eclipse.linuxtools.lttng2.ust.ui/META-INF/MANIFEST.MF b/org.eclipse.linuxtools.lttng2.ust.ui/META-INF/MANIFEST.MF index a9bb905b00..ac0be4a209 100644 --- a/org.eclipse.linuxtools.lttng2.ust.ui/META-INF/MANIFEST.MF +++ b/org.eclipse.linuxtools.lttng2.ust.ui/META-INF/MANIFEST.MF @@ -16,4 +16,5 @@ Require-Bundle: org.eclipse.core.resources, org.eclipse.linuxtools.tmf.ui Export-Package: org.eclipse.linuxtools.internal.lttng2.ust.ui;x-friends:="org.eclipse.linuxtools.lttng2.ust.ui.tests", org.eclipse.linuxtools.internal.lttng2.ust.ui.views.memusage;x-friends:="org.eclipse.linuxtools.lttng2.ust.ui.tests", + org.eclipse.linuxtools.lttng2.ust.ui.analysis.callstack, org.eclipse.linuxtools.lttng2.ust.ui.analysis.memory diff --git a/org.eclipse.linuxtools.lttng2.ust.ui/plugin.properties b/org.eclipse.linuxtools.lttng2.ust.ui/plugin.properties index b2819377c6..2dca19643d 100644 --- a/org.eclipse.linuxtools.lttng2.ust.ui/plugin.properties +++ b/org.eclipse.linuxtools.lttng2.ust.ui/plugin.properties @@ -16,3 +16,5 @@ Bundle-Name = Linux Tools LTTng Userspace Tracer Analysis UI Plug-in tracetype.type.ust = LTTng UST Trace memoryusage.view.name = UST Memory Usage + +analysis.callstack = LTTng-UST CallStack Analysis \ No newline at end of file diff --git a/org.eclipse.linuxtools.lttng2.ust.ui/plugin.xml b/org.eclipse.linuxtools.lttng2.ust.ui/plugin.xml index 133a5db784..4bdc59e299 100644 --- a/org.eclipse.linuxtools.lttng2.ust.ui/plugin.xml +++ b/org.eclipse.linuxtools.lttng2.ust.ui/plugin.xml @@ -33,4 +33,17 @@ + + + + + + diff --git a/org.eclipse.linuxtools.lttng2.ust.ui/src/org/eclipse/linuxtools/lttng2/ust/ui/analysis/callstack/LttngUstCallStackAnalysis.java b/org.eclipse.linuxtools.lttng2.ust.ui/src/org/eclipse/linuxtools/lttng2/ust/ui/analysis/callstack/LttngUstCallStackAnalysis.java new file mode 100644 index 0000000000..f1b0ec08aa --- /dev/null +++ b/org.eclipse.linuxtools.lttng2.ust.ui/src/org/eclipse/linuxtools/lttng2/ust/ui/analysis/callstack/LttngUstCallStackAnalysis.java @@ -0,0 +1,49 @@ +/******************************************************************************* + * Copyright (c) 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: + * Alexandre Montplaisir - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.linuxtools.lttng2.ust.ui.analysis.callstack; + +import org.eclipse.linuxtools.internal.lttng2.ust.core.trace.callstack.LttngUstCallStackProvider; +import org.eclipse.linuxtools.lttng2.ust.core.trace.LttngUstTrace; +import org.eclipse.linuxtools.tmf.core.exceptions.TmfAnalysisException; +import org.eclipse.linuxtools.tmf.core.statesystem.ITmfStateProvider; +import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; +import org.eclipse.linuxtools.tmf.ui.views.callstack.AbstractCallStackAnalysis; + +/** + * Call-stack analysis to populate the TMF CallStack View from UST cyg-profile + * events. + * + * @author Alexandre Montplaisir + * @since 3.0 + */ +public class LttngUstCallStackAnalysis extends AbstractCallStackAnalysis { + + @Override + public void setTrace(ITmfTrace trace) throws TmfAnalysisException { + if (!(trace instanceof LttngUstTrace)) { + throw new IllegalArgumentException("Trace should be of type LttngUstTrace"); //$NON-NLS-1$ + } + super.setTrace(trace); + } + + @Override + protected LttngUstTrace getTrace() { + return (LttngUstTrace) super.getTrace(); + } + + @Override + protected ITmfStateProvider createStateProvider() { + return new LttngUstCallStackProvider(getTrace()); + } + +} diff --git a/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/callstack/CallStackStateProvider.java b/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/callstack/CallStackStateProvider.java index 18ee1b179d..ca2805e489 100644 --- a/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/callstack/CallStackStateProvider.java +++ b/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/callstack/CallStackStateProvider.java @@ -64,8 +64,6 @@ import org.eclipse.osgi.util.NLS; */ public abstract class CallStackStateProvider extends AbstractTmfStateProvider { - /** CallStack state system ID */ - public static final String ID = "org.eclipse.linuxtools.tmf.callstack"; //$NON-NLS-1$ /** Thread attribute */ public static final String THREADS = "Threads"; //$NON-NLS-1$ /** CallStack stack-attribute */ @@ -73,6 +71,8 @@ public abstract class CallStackStateProvider extends AbstractTmfStateProvider { /** Undefined function exit name */ public static final String UNDEFINED = "UNDEFINED"; //$NON-NLS-1$ + /** CallStack state system ID */ + private static final String ID = "org.eclipse.linuxtools.tmf.callstack"; //$NON-NLS-1$ /** Dummy function name for when no function is expected */ private static final String NO_FUNCTION = "no function"; //$NON-NLS-1$ diff --git a/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/callstack/AbstractCallStackAnalysis.java b/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/callstack/AbstractCallStackAnalysis.java new file mode 100644 index 0000000000..ee03dd4274 --- /dev/null +++ b/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/callstack/AbstractCallStackAnalysis.java @@ -0,0 +1,41 @@ +/******************************************************************************* + * Copyright (c) 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: + * Alexandre Montplaisir - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.linuxtools.tmf.ui.views.callstack; + +import org.eclipse.linuxtools.tmf.core.statesystem.TmfStateSystemAnalysisModule; +import org.eclipse.linuxtools.tmf.ui.analysis.TmfAnalysisViewOutput; + +/** + * The base classes for analyses who want to populate the CallStack View. + * + * @author Alexandre Montplaisir + * @since 3.0 + */ +public abstract class AbstractCallStackAnalysis extends TmfStateSystemAnalysisModule { + + /** + * Abstract constructor (should only be called via the sub-classes' + * constructors. + */ + public AbstractCallStackAnalysis() { + super(); + registerOutput(new TmfAnalysisViewOutput(CallStackView.ID)); + } + + @Override + protected StateSystemBackendType getBackendType() { + /* Full history by default, sub-classes are free to override */ + return StateSystemBackendType.FULL; + } + +} diff --git a/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/callstack/CallStackPresentationProvider.java b/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/callstack/CallStackPresentationProvider.java index 49f55d0b5f..20de0d19fa 100644 --- a/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/callstack/CallStackPresentationProvider.java +++ b/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/callstack/CallStackPresentationProvider.java @@ -13,7 +13,6 @@ package org.eclipse.linuxtools.tmf.ui.views.callstack; import org.eclipse.linuxtools.internal.tmf.ui.Activator; -import org.eclipse.linuxtools.tmf.core.callstack.CallStackStateProvider; import org.eclipse.linuxtools.tmf.core.exceptions.AttributeNotFoundException; import org.eclipse.linuxtools.tmf.core.exceptions.StateSystemDisposedException; import org.eclipse.linuxtools.tmf.core.exceptions.TimeRangeException; @@ -105,7 +104,10 @@ public class CallStackPresentationProvider extends TimeGraphPresentationProvider public String getEventName(ITimeEvent event) { if (event instanceof CallStackEvent) { CallStackEntry entry = (CallStackEntry) event.getEntry(); - ITmfStateSystem ss = entry.getTrace().getStateSystems().get(CallStackStateProvider.ID); + ITmfStateSystem ss = CallStackView.getCallStackStateSystem(entry.getTrace()); + if (ss == null) { + return null; + } try { ITmfStateValue value = ss.querySingleState(event.getTime(), entry.getQuark()).getStateValue(); if (!value.isNull()) { @@ -133,7 +135,10 @@ public class CallStackPresentationProvider extends TimeGraphPresentationProvider return; } CallStackEntry entry = (CallStackEntry) event.getEntry(); - ITmfStateSystem ss = entry.getTrace().getStateSystems().get(CallStackStateProvider.ID); + ITmfStateSystem ss = CallStackView.getCallStackStateSystem(entry.getTrace()); + if (ss == null) { + return; + } try { ITmfStateValue value = ss.querySingleState(event.getTime(), entry.getQuark()).getStateValue(); if (!value.isNull()) { diff --git a/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/callstack/CallStackView.java b/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/callstack/CallStackView.java index ed716ca765..3a03cc24eb 100644 --- a/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/callstack/CallStackView.java +++ b/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/callstack/CallStackView.java @@ -25,6 +25,7 @@ import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.jdt.annotation.Nullable; import org.eclipse.jface.action.Action; import org.eclipse.jface.action.IAction; import org.eclipse.jface.action.IStatusLineManager; @@ -205,8 +206,6 @@ public class CallStackView extends TmfView { // ------------------------------------------------------------------------ private class ThreadEntry implements ITimeGraphEntry { - // The Trace - private final ITmfTrace fThreadTrace; // The start time private final long fTraceStartTime; // The end time @@ -217,14 +216,17 @@ public class CallStackView extends TmfView { private final String fName; // The thread attribute quark private final int fThreadQuark; + // The state system from which this entry comes + private final ITmfStateSystem fSS; public ThreadEntry(ITmfTrace trace, String name, int threadQuark, long startTime, long endTime) { - fThreadTrace = trace; fChildren = new ArrayList<>(); fName = name; fTraceStartTime = startTime; fTraceEndTime = endTime; fThreadQuark = threadQuark; + + fSS = getCallStackStateSystem(trace); } @Override @@ -235,7 +237,10 @@ public class CallStackView extends TmfView { @Override public boolean hasChildren() { if (fChildren == null) { - ITmfStateSystem ss = fThreadTrace.getStateSystems().get(CallStackStateProvider.ID); + ITmfStateSystem ss = getStateSystem(); + if (ss == null) { + return false; + } try { int eventStackQuark = ss.getQuarkRelative(fThreadQuark, CallStackStateProvider.CALL_STACK); ITmfStateInterval eventStackInterval = ss.querySingleState(ss.getStartTime(), eventStackQuark); @@ -290,8 +295,9 @@ public class CallStackView extends TmfView { return fThreadQuark; } - public ITmfTrace getTrace() { - return fThreadTrace; + @Nullable + public ITmfStateSystem getStateSystem() { + return fSS; } public void addChild(CallStackEntry entry) { @@ -442,7 +448,7 @@ public class CallStackView extends TmfView { } long resolution = Math.max(1, (fZoomEndTime - fZoomStartTime) / fDisplayWidth); for (ThreadEntry threadEntry : fZoomEntryList) { - ITmfStateSystem ss = threadEntry.fThreadTrace.getStateSystems().get(CallStackStateProvider.ID); + ITmfStateSystem ss = threadEntry.getStateSystem(); if (ss == null) { continue; } @@ -693,7 +699,7 @@ public class CallStackView extends TmfView { } TimeGraphViewer viewer = fTimeGraphCombo.getTimeGraphViewer(); for (ThreadEntry threadEntry : fEntryList) { - ITmfStateSystem ss = threadEntry.getTrace().getStateSystems().get(CallStackStateProvider.ID); + ITmfStateSystem ss = threadEntry.getStateSystem(); if (ss == null || beginTime < ss.getStartTime() || beginTime > ss.getCurrentEndTime()) { continue; } @@ -793,7 +799,7 @@ public class CallStackView extends TmfView { if (monitor.isCanceled()) { return; } - ITmfStateSystem ss = aTrace.getStateSystems().get(CallStackStateProvider.ID); + ITmfStateSystem ss = getCallStackStateSystem(aTrace); if (ss == null) { addUnavailableEntry(aTrace, entryList); continue; @@ -853,7 +859,10 @@ public class CallStackView extends TmfView { } private void buildStatusEvents(ITmfTrace trace, CallStackEntry entry, IProgressMonitor monitor) { - ITmfStateSystem ss = entry.getTrace().getStateSystems().get(CallStackStateProvider.ID); + ITmfStateSystem ss = getCallStackStateSystem(entry.getTrace()); + if (ss == null) { + return; + } long start = ss.getStartTime(); long end = ss.getCurrentEndTime() + 1; long resolution = Math.max(1, (end - start) / fDisplayWidth); @@ -870,7 +879,10 @@ public class CallStackView extends TmfView { private static List getEventList(CallStackEntry entry, long startTime, long endTime, long resolution, IProgressMonitor monitor) { - ITmfStateSystem ss = entry.getTrace().getStateSystems().get(CallStackStateProvider.ID); + ITmfStateSystem ss = getCallStackStateSystem(entry.getTrace()); + if (ss == null) { + return null; + } long start = Math.max(startTime, ss.getStartTime()); long end = Math.min(endTime, ss.getCurrentEndTime() + 1); if (end <= start) { @@ -926,7 +938,7 @@ public class CallStackView extends TmfView { return; } for (ThreadEntry threadEntry : fEntryList) { - ITmfStateSystem ss = threadEntry.fThreadTrace.getStateSystems().get(CallStackStateProvider.ID); + ITmfStateSystem ss = threadEntry.getStateSystem(); if (ss == null) { continue; } @@ -1098,7 +1110,10 @@ public class CallStackView extends TmfView { try { CallStackEntry callStackEntry = (CallStackEntry) entry; ITmfTrace trace = callStackEntry.getTrace(); - ITmfStateSystem ss = trace.getStateSystems().get(CallStackStateProvider.ID); + ITmfStateSystem ss = getCallStackStateSystem(trace); + if (ss == null) { + return; + } long time = Math.max(ss.getStartTime(), Math.min(ss.getCurrentEndTime(), viewer.getSelectionBegin())); ThreadEntry threadEntry = (ThreadEntry) callStackEntry.getParent(); int quark = ss.getQuarkRelative(threadEntry.getThreadQuark(), CallStackStateProvider.CALL_STACK); @@ -1111,6 +1126,7 @@ public class CallStackView extends TmfView { fTimeGraphCombo.setSelection(selectedEntry); viewer.getTimeGraphControl().fireSelectionChanged(); startZoomThread(viewer.getTime0(), viewer.getTime1()); + } catch (AttributeNotFoundException e) { Activator.getDefault().logError("Error querying state system", e); //$NON-NLS-1$ } catch (TimeRangeException e) { @@ -1148,7 +1164,10 @@ public class CallStackView extends TmfView { try { CallStackEntry callStackEntry = (CallStackEntry) entry; ITmfTrace trace = callStackEntry.getTrace(); - ITmfStateSystem ss = trace.getStateSystems().get(CallStackStateProvider.ID); + ITmfStateSystem ss = getCallStackStateSystem(trace); + if (ss == null) { + return; + } long time = Math.max(ss.getStartTime(), Math.min(ss.getCurrentEndTime(), viewer.getSelectionBegin())); ThreadEntry threadEntry = (ThreadEntry) callStackEntry.getParent(); int quark = ss.getQuarkRelative(threadEntry.getThreadQuark(), CallStackStateProvider.CALL_STACK); @@ -1162,6 +1181,7 @@ public class CallStackView extends TmfView { fTimeGraphCombo.setSelection(selectedEntry); viewer.getTimeGraphControl().fireSelectionChanged(); startZoomThread(viewer.getTime0(), viewer.getTime1()); + } catch (AttributeNotFoundException e) { Activator.getDefault().logError("Error querying state system", e); //$NON-NLS-1$ } catch (TimeRangeException e) { @@ -1183,6 +1203,38 @@ public class CallStackView extends TmfView { return fPrevEventAction; } + @Nullable + static ITmfStateSystem getCallStackStateSystem(ITmfTrace trace) { + /* + * Since we cannot know the exact analysis ID (in separate plugins), we + * will search using the analysis type. + */ + Iterable modules = + trace.getAnalysisModulesOfClass(AbstractCallStackAnalysis.class); + Iterator it = modules.iterator(); + if (!it.hasNext()) { + /* This trace does not provide a call-stack analysis */ + return null; + } + + /* + * We only look at the first module we find. + * + * TODO Handle the advanced case where one trace provides more than one + * call-stack analysis. + */ + AbstractCallStackAnalysis module = it.next(); + /* This analysis is not automatic, we need to schedule it on-demand */ + module.schedule(); + module.waitForInitialization(); + ITmfStateSystem ss = module.getStateSystem(); + if (ss == null) { + /* If we've waited for initialization, 'ss' should not be null */ + throw new IllegalStateException(); + } + return ss; + } + // ------------------------------------------------------------------------ // Methods related to function name mapping // ------------------------------------------------------------------------ -- 2.34.1