import org.eclipse.tracecompass.statesystem.core.interval.ITmfStateInterval;
import org.eclipse.tracecompass.statesystem.core.statevalue.ITmfStateValue;
import org.eclipse.tracecompass.testtraces.ctf.CtfTestTrace;
+import org.eclipse.tracecompass.tmf.core.callstack.CallStackStateProvider;
import org.eclipse.tracecompass.tmf.core.exceptions.TmfAnalysisException;
import org.eclipse.tracecompass.tmf.core.statesystem.ITmfStateProvider;
import org.eclipse.tracecompass.tmf.core.statesystem.TmfStateSystemAnalysisModule;
/** Get the callstack for the given timestamp, for this particular trace */
private static String[] getCallStack(ITmfStateSystem ss, int pid, String threadName, long timestamp) {
try {
- int stackAttribute = ss.getQuarkAbsolute("Processes", Integer.toString(pid), threadName, "CallStack");
+ String processName = (pid == CallStackStateProvider.UNKNOWN_PID) ? CallStackStateProvider.UNKNOWN : Integer.toString(pid);
+ int stackAttribute = ss.getQuarkAbsolute("Processes", processName, threadName, "CallStack");
List<ITmfStateInterval> state = ss.queryFullState(timestamp);
int depth = state.get(stackAttribute).getStateValue().unboxInt();
/*******************************************************************************
- * Copyright (c) 2013, 2015 Ericsson
+ * Copyright (c) 2013, 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
ITmfEventField content = event.getContent();
ITmfEventField vpidContextField = content.getField(fLayout.contextVpid());
if (vpidContextField == null) {
- return UNDEFINED_PID;
+ return UNKNOWN_PID;
}
return ((Long) vpidContextField.getValue()).intValue();
}
}
@Override
- public String getThreadName(ITmfEvent event) {
+ public @Nullable String getThreadName(ITmfEvent event) {
/* We checked earlier that the "procname" context is present */
ITmfEventField content = event.getContent();
String procName = (String) content.getField(fLayout.contextProcname()).getValue();
/*******************************************************************************
- * Copyright (c) 2015 Ericsson
+ * Copyright (c) 2015, 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
@Test
public void testOpenCallstack() {
String node = "glxgears-cyg-profile";
- String pid = "-1";
+ String processName = "UNKNOWN";
String childName = "glxgears-16073";
List<String> expected = ImmutableList.of("0x40472b", "", "", "", "");
viewBot.setFocus();
final SWTBotView viewBot1 = viewBot;
SWTBotTree tree = viewBot1.bot().tree();
- SWTBotTreeItem treeItem = tree.getTreeItem(node).getNode(pid);
+ SWTBotTreeItem treeItem = tree.getTreeItem(node).getNode(processName);
assertEquals(childName, treeItem.getNodes().get(0));
List<String> names = treeItem.getNode(childName).getNodes();
assertEquals(expected, names);
/*******************************************************************************
- * Copyright (c) 2013, 2015 Ericsson
+ * Copyright (c) 2013, 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
*
* where:
* <ul>
- * <li>(PID n) is an attribute name representing a unique process identifier.
- * </li>
+ * <li>(PID n) is an attribute whose name is the display name of the process.
+ * Optionally, its value can be an int representing the process id. Otherwise,
+ * the attribute name can be set to the process id formatted as a string.</li>
* <li>(TID n) is an attribute whose name is the display name of the thread.
- * Optionally, its value is a long representing the thread id, used for sorting.
- * </li>
+ * Optionally, its value can be a long representing the thread id. Otherwise,
+ * the attribute name can be set to the thread id formatted as a string.</li>
* <li>"CallStack" is a stack-attribute whose pushed values are either a string,
* int or long representing the function name or address in the call stack. The
* type of value used must be constant for a particular CallStack.</li>
public static final String CALL_STACK = "CallStack"; //$NON-NLS-1$
/**
- * Undefined process ID
+ * Unknown process ID
*
* @since 2.0
*/
- protected static final int UNDEFINED_PID = -1;
+ public static final int UNKNOWN_PID = -1;
- /** Undefined function exit name */
- protected static final String UNDEFINED = "UNDEFINED"; //$NON-NLS-1$
+ /**
+ * Unknown name
+ *
+ * @since 2.0
+ */
+ public static final String UNKNOWN = "UNKNOWN"; //$NON-NLS-1$
/** CallStack state system ID */
private static final String ID = "org.eclipse.linuxtools.tmf.callstack"; //$NON-NLS-1$
ITmfStateValue functionEntryName = functionEntry(event);
if (functionEntryName != null) {
long timestamp = event.getTimestamp().toNanos();
- int pid = getProcessId(event);
- String threadName = getThreadName(event);
- int threadQuark = ss.getQuarkAbsoluteAndAdd(PROCESSES, Integer.toString(pid), threadName);
+ String processName = getProcessName(event);
+ int processId = getProcessId(event);
+ if (processName == null) {
+ processName = (processId == UNKNOWN_PID) ? UNKNOWN : Integer.toString(processId);
+ }
+ int processQuark = ss.getQuarkAbsoluteAndAdd(PROCESSES, processName);
+ ss.updateOngoingState(TmfStateValue.newValueInt(processId), processQuark);
+
+ String threadName = getThreadName(event);
long threadId = getThreadId(event);
+ if (threadName == null) {
+ threadName = Long.toString(threadId);
+ }
+ int threadQuark = ss.getQuarkRelativeAndAdd(processQuark, threadName);
ss.updateOngoingState(TmfStateValue.newValueLong(threadId), threadQuark);
int callStackQuark = ss.getQuarkRelativeAndAdd(threadQuark, CALL_STACK);
ITmfStateValue functionExitState = functionExit(event);
if (functionExitState != null) {
long timestamp = event.getTimestamp().toNanos();
- int pid = getProcessId(event);
- String thread = getThreadName(event);
- int quark = ss.getQuarkAbsoluteAndAdd(PROCESSES, Integer.toString(pid), thread, CALL_STACK);
+ String processName = getProcessName(event);
+ if (processName == null) {
+ int processId = getProcessId(event);
+ processName = (processId == UNKNOWN_PID) ? UNKNOWN : Integer.toString(processId);
+ }
+ String threadName = getThreadName(event);
+ if (threadName == null) {
+ threadName = Long.toString(getThreadId(event));
+ }
+ int quark = ss.getQuarkAbsoluteAndAdd(PROCESSES, processName, threadName, CALL_STACK);
ITmfStateValue poppedValue = ss.popAttribute(timestamp, quark);
/*
* Verify that the value we are popping matches the one in the
/**
* Return the process ID of a function entry event.
- *
- * Use {@link #UNDEFINED_PID} if it is not known.
+ * <p>
+ * Use {@link #UNKNOWN_PID} if it is not known.
*
* @param event
* The event
*/
protected abstract int getProcessId(ITmfEvent event);
+ /**
+ * Return the process name of a function entry event.
+ *
+ * @param event
+ * The event
+ * @return The process name (as will be shown in the view) or null to use
+ * the process ID formatted as a string (or {@link #UNKNOWN})
+ * @since 2.0
+ */
+ protected @Nullable String getProcessName(ITmfEvent event) {
+ /* Override to provide a process name */
+ return null;
+ }
+
/**
* Return the thread id of a function entry event.
*
*
* @param event
* The event
- * @return The thread name (as will be shown in the view)
+ * @return The thread name (as will be shown in the view) or null to use the
+ * thread id formatted as a string
*/
- protected abstract String getThreadName(ITmfEvent event);
+ protected @Nullable String getThreadName(ITmfEvent event) {
+ /* Override to provide a thread name */
+ return null;
+ }
}
traceEntry.updateEndTime(end);
}
- List<Integer> processQuarks = ss.getQuarks(module.getProcessesPattern());
- for (int processQuark : processQuarks) {
-
- /*
- * Default to trace entry, overwrite if a process entry exists.
- */
- TimeGraphEntry threadParent = traceEntry;
- int processId = -1;
- if (processQuark != ITmfStateSystem.ROOT_ATTRIBUTE) {
- /* Create the entry for the process */
- ProcessEntry processEntry = processEntryMap.get(processQuark);
- if (processEntry == null) {
- String name = ss.getAttributeName(processQuark);
- /* The attribute name should already be parseable to integer */
- processId = Integer.parseInt(name);
- processEntry = new ProcessEntry(name, processId, start, end);
- processEntryMap.put(processQuark, processEntry);
- traceEntry.addChild(processEntry);
- } else {
- processEntry.updateEndTime(end);
+ try {
+ List<ITmfStateInterval> endStates = ss.queryFullState(ss.getCurrentEndTime());
+
+ List<Integer> processQuarks = ss.getQuarks(module.getProcessesPattern());
+ for (int processQuark : processQuarks) {
+
+ /*
+ * Default to trace entry, overwrite if a process entry exists.
+ */
+ TimeGraphEntry threadParent = traceEntry;
+ int processId = -1;
+ if (processQuark != ITmfStateSystem.ROOT_ATTRIBUTE) {
+ /* Create the entry for the process */
+ ProcessEntry processEntry = processEntryMap.get(processQuark);
+ if (processEntry == null) {
+ String processName = ss.getAttributeName(processQuark);
+ ITmfStateValue processStateValue = endStates.get(processQuark).getStateValue();
+ if (processStateValue.getType() == Type.INTEGER) {
+ processId = processStateValue.unboxInt();
+ } else {
+ try {
+ processId = Integer.parseInt(processName);
+ } catch (NumberFormatException e) {
+ /* use default processId */
+ }
+ }
+ processEntry = new ProcessEntry(processName, processId, start, end);
+ processEntryMap.put(processQuark, processEntry);
+ traceEntry.addChild(processEntry);
+ } else {
+ processEntry.updateEndTime(end);
+ }
+ /* The parent of the thread entries will be a process */
+ threadParent = processEntry;
}
- /* The parent of the thread entries will be a process */
- threadParent = processEntry;
- }
- /* Create the threads under the process */
- try {
+ /* Create the threads under the process */
List<Integer> threadQuarks = ss.getQuarks(processQuark, module.getThreadsPattern());
/*
* Only query startStates if necessary (threadEntry == null)
*/
List<ITmfStateInterval> startStates = null;
- List<ITmfStateInterval> endStates = ss.queryFullState(ss.getCurrentEndTime());
for (int threadQuark : threadQuarks) {
if (monitor.isCanceled()) {
return;
if (startStates == null) {
startStates = ss.queryFullState(ss.getStartTime());
}
- long threadId = endStates.get(threadQuark).getStateValue().unboxLong();
+ long threadId = -1;
+ ITmfStateValue threadStateValue = endStates.get(threadQuark).getStateValue();
+ if (threadStateValue.getType() == Type.LONG || threadStateValue.getType() == Type.INTEGER) {
+ threadId = threadStateValue.unboxLong();
+ } else {
+ try {
+ threadId = Long.parseLong(threadName);
+ } catch (NumberFormatException e) {
+ /* use default threadId */
+ }
+ }
long threadStart = start;
ITmfStateInterval startInterval = startStates.get(callStackQuark);
if (startInterval.getStateValue().isNull()) {
level++;
}
}
- } catch (AttributeNotFoundException e) {
- Activator.getDefault().logError("Error querying state system", e); //$NON-NLS-1$
- } catch (StateSystemDisposedException e) {
- /* Ignored */
}
+ } catch (AttributeNotFoundException e) {
+ Activator.getDefault().logError("Error querying state system", e); //$NON-NLS-1$
+ } catch (StateSystemDisposedException e) {
+ /* Ignored */
}
if (parentTrace == getTrace()) {