1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-29 19:45:01 +02:00

Bug 336947: CLI command for DSF-GDB "tdump". And improvement for the IGDBTraceControl interface.

This commit is contained in:
Marc Khouzam 2011-03-02 20:25:35 +00:00
parent e96dfd110a
commit 559736718a
6 changed files with 838 additions and 25 deletions

View file

@ -285,7 +285,7 @@ public class TraceControlView extends ViewPart implements IViewPart, SessionEnde
protected void execute(DataRequestMonitor<Object> rm) { protected void execute(DataRequestMonitor<Object> rm) {
final IGDBTraceControl traceControl = getService(IGDBTraceControl.class); final IGDBTraceControl traceControl = getService(IGDBTraceControl.class);
if (traceControl != null) { if (traceControl != null) {
ITraceRecordDMContext emptyDmc = traceControl.createTraceRecordContext(ctx, -1); ITraceRecordDMContext emptyDmc = traceControl.createTraceRecordContext(ctx, "-1"); //$NON-NLS-1$
traceControl.selectTraceRecord(emptyDmc, rm); traceControl.selectTraceRecord(emptyDmc, rm);
} else { } else {
rm.setData(null); rm.setData(null);

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2010 Ericsson and others. * Copyright (c) 2010, 2011 Ericsson and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -13,6 +13,7 @@ package org.eclipse.cdt.dsf.gdb.service;
import java.util.Hashtable; import java.util.Hashtable;
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor; import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
import org.eclipse.cdt.dsf.concurrent.ImmediateExecutor;
import org.eclipse.cdt.dsf.concurrent.Immutable; import org.eclipse.cdt.dsf.concurrent.Immutable;
import org.eclipse.cdt.dsf.concurrent.RequestMonitor; import org.eclipse.cdt.dsf.concurrent.RequestMonitor;
import org.eclipse.cdt.dsf.datamodel.AbstractDMContext; import org.eclipse.cdt.dsf.datamodel.AbstractDMContext;
@ -31,6 +32,7 @@ import org.eclipse.cdt.dsf.mi.service.IMICommandControl;
import org.eclipse.cdt.dsf.mi.service.IMIProcesses; import org.eclipse.cdt.dsf.mi.service.IMIProcesses;
import org.eclipse.cdt.dsf.mi.service.command.CommandFactory; import org.eclipse.cdt.dsf.mi.service.command.CommandFactory;
import org.eclipse.cdt.dsf.mi.service.command.events.MIEvent; import org.eclipse.cdt.dsf.mi.service.command.events.MIEvent;
import org.eclipse.cdt.dsf.mi.service.command.output.CLITraceDumpInfo;
import org.eclipse.cdt.dsf.mi.service.command.output.MIInfo; import org.eclipse.cdt.dsf.mi.service.command.output.MIInfo;
import org.eclipse.cdt.dsf.mi.service.command.output.MIResultRecord; import org.eclipse.cdt.dsf.mi.service.command.output.MIResultRecord;
import org.eclipse.cdt.dsf.mi.service.command.output.MITraceFindInfo; import org.eclipse.cdt.dsf.mi.service.command.output.MITraceFindInfo;
@ -56,20 +58,22 @@ public class GDBTraceControl_7_2 extends AbstractDsfService implements IGDBTrace
@Immutable @Immutable
protected static final class MITraceRecordDMContext extends AbstractDMContext implements ITraceRecordDMContext { protected static final class MITraceRecordDMContext extends AbstractDMContext implements ITraceRecordDMContext {
// The trace record reference // The trace record GDB reference
private final int fReference; private final String fReference;
/** /**
* @param session the DsfSession for this service * @param session the DsfSession for this service
* @param parents the parent contexts * @param parents the parent contexts
* @param reference the trace record reference * @param reference the trace record reference
* @since 4.0
*/ */
public MITraceRecordDMContext(DsfSession session, ITraceTargetDMContext parent, int reference) { public MITraceRecordDMContext(DsfSession session, ITraceTargetDMContext parent, String reference) {
super(session.getId(), new IDMContext[] { parent }); super(session.getId(), new IDMContext[] { parent });
fReference = reference; fReference = reference;
} }
public int getReference() { /** @since 4.0 */
public String getRecordId() {
return fReference; return fReference;
} }
@ -78,7 +82,8 @@ public class GDBTraceControl_7_2 extends AbstractDsfService implements IGDBTrace
*/ */
@Override @Override
public boolean equals(Object obj) { public boolean equals(Object obj) {
return baseEquals(obj) && (fReference == ((MITraceRecordDMContext) obj).fReference); return baseEquals(obj) && (fReference == null ? ((MITraceRecordDMContext) obj).fReference == null :
(fReference.equals(((MITraceRecordDMContext) obj).fReference)));
} }
/* (non-Javadoc) /* (non-Javadoc)
@ -86,7 +91,7 @@ public class GDBTraceControl_7_2 extends AbstractDsfService implements IGDBTrace
*/ */
@Override @Override
public int hashCode() { public int hashCode() {
return baseHashCode() + fReference; return baseHashCode() ^ (fReference == null ? 0 : fReference.hashCode());
} }
/* (non-Javadoc) /* (non-Javadoc)
@ -113,6 +118,10 @@ public class GDBTraceControl_7_2 extends AbstractDsfService implements IGDBTrace
super(session.getId(), new IDMContext[] { parent }); super(session.getId(), new IDMContext[] { parent });
} }
/** @since 4.0 */
public String getRecordId() {
return null;
}
/* (non-Javadoc) /* (non-Javadoc)
* @see org.eclipse.cdt.dsf.datamodel.AbstractDMContext#equals(java.lang.Object) * @see org.eclipse.cdt.dsf.datamodel.AbstractDMContext#equals(java.lang.Object)
@ -163,6 +172,36 @@ public class GDBTraceControl_7_2 extends AbstractDsfService implements IGDBTrace
} }
} }
private class TraceRecordDMData implements ITraceRecordDMData {
private String fContent;
private String fTracepointNum;
private String fTimestamp;
private String fFrameNumber;
public TraceRecordDMData(String content, String tracepointNum, String frameNumber, String timestamp) {
fContent = content;
fTracepointNum = tracepointNum;
fTimestamp = timestamp;
fFrameNumber = frameNumber;
}
public String getContent() {
return fContent;
}
public String getTracepointNumber() {
return fTracepointNum;
}
public String getRecordId() {
return fFrameNumber;
}
public String getTimestamp() {
return fTimestamp;
}
}
private class TraceStatusDMData implements ITraceStatusDMData { private class TraceStatusDMData implements ITraceStatusDMData {
private int fFreeBufferSize; private int fFreeBufferSize;
private int fTotalBufferSize; private int fTotalBufferSize;
@ -249,7 +288,7 @@ public class GDBTraceControl_7_2 extends AbstractDsfService implements IGDBTrace
if (fCurrentRecordDmc instanceof MITraceRecordDMContext) { if (fCurrentRecordDmc instanceof MITraceRecordDMContext) {
str += "Looking at trace frame " + str += "Looking at trace frame " +
((MITraceRecordDMContext)fCurrentRecordDmc).getReference() + ((MITraceRecordDMContext)fCurrentRecordDmc).getRecordId() +
", tracepoint " + fTracepointIndexForTraceRecord + "\n\n"; ", tracepoint " + fTracepointIndexForTraceRecord + "\n\n";
} else { } else {
str += "Not currently looking at any trace frame\n\n"; str += "Not currently looking at any trace frame\n\n";
@ -645,7 +684,7 @@ public class GDBTraceControl_7_2 extends AbstractDsfService implements IGDBTrace
// Workaround for GDB pre-release where we don't get the details // Workaround for GDB pre-release where we don't get the details
// of the frame when we load a trace file. // of the frame when we load a trace file.
// To get around this, we can force a select of record 0 // To get around this, we can force a select of record 0
ITraceRecordDMContext initialRecord = createTraceRecordContext(context, 0); ITraceRecordDMContext initialRecord = createTraceRecordContext(context, "0"); //$NON-NLS-1$
selectTraceRecord(initialRecord, rm); selectTraceRecord(initialRecord, rm);
} }
}); });
@ -785,19 +824,21 @@ public class GDBTraceControl_7_2 extends AbstractDsfService implements IGDBTrace
/** /**
* Create a trace record context * Create a trace record context
* @since 4.0
*/ */
public ITraceRecordDMContext createTraceRecordContext(ITraceTargetDMContext ctx, int index) { public ITraceRecordDMContext createTraceRecordContext(ITraceTargetDMContext ctx, String recordId) {
return new MITraceRecordDMContext(getSession(), ctx, index); return new MITraceRecordDMContext(getSession(), ctx, recordId);
} }
public ITraceRecordDMContext createNextRecordContext(ITraceRecordDMContext ctx) { public ITraceRecordDMContext createNextRecordContext(ITraceRecordDMContext ctx) {
ITraceTargetDMContext targetDmc = DMContexts.getAncestorOfType(ctx, ITraceTargetDMContext.class); ITraceTargetDMContext targetDmc = DMContexts.getAncestorOfType(ctx, ITraceTargetDMContext.class);
if (ctx instanceof InvalidTraceRecordDMContext) { if (ctx instanceof InvalidTraceRecordDMContext) {
// No specified context, so we return the context for the first // No specified context, so we return the context for the first
return new MITraceRecordDMContext(getSession(), targetDmc, 0); return createTraceRecordContext(targetDmc, "0"); //$NON-NLS-1$
} }
if (ctx instanceof MITraceRecordDMContext) { if (ctx instanceof MITraceRecordDMContext) {
int recordIndex = ((MITraceRecordDMContext)ctx).getReference(); String recordId = ((MITraceRecordDMContext)ctx).getRecordId();
int recordIndex = Integer.parseInt(recordId);
recordIndex++; recordIndex++;
if (recordIndex == fTraceRecordsStored) { if (recordIndex == fTraceRecordsStored) {
// Loop back to the front // Loop back to the front
@ -805,7 +846,7 @@ public class GDBTraceControl_7_2 extends AbstractDsfService implements IGDBTrace
} }
return new MITraceRecordDMContext(getSession(), return new MITraceRecordDMContext(getSession(),
targetDmc, targetDmc,
recordIndex); Integer.toString(recordIndex));
} }
return null; return null;
} }
@ -813,7 +854,8 @@ public class GDBTraceControl_7_2 extends AbstractDsfService implements IGDBTrace
public ITraceRecordDMContext createPrevRecordContext(ITraceRecordDMContext ctx) { public ITraceRecordDMContext createPrevRecordContext(ITraceRecordDMContext ctx) {
if (ctx instanceof MITraceRecordDMContext) { if (ctx instanceof MITraceRecordDMContext) {
ITraceTargetDMContext targetDmc = DMContexts.getAncestorOfType(ctx, ITraceTargetDMContext.class); ITraceTargetDMContext targetDmc = DMContexts.getAncestorOfType(ctx, ITraceTargetDMContext.class);
int recordIndex = ((MITraceRecordDMContext)ctx).getReference(); String recordId = ((MITraceRecordDMContext)ctx).getRecordId();
int recordIndex = Integer.parseInt(recordId);
if (recordIndex == 0) { if (recordIndex == 0) {
// Loop back to the end // Loop back to the end
recordIndex = fTraceRecordsStored; // The last index of a trace record (zero-based) recordIndex = fTraceRecordsStored; // The last index of a trace record (zero-based)
@ -821,7 +863,7 @@ public class GDBTraceControl_7_2 extends AbstractDsfService implements IGDBTrace
recordIndex--; recordIndex--;
return new MITraceRecordDMContext(getSession(), return new MITraceRecordDMContext(getSession(),
targetDmc, targetDmc,
recordIndex); Integer.toString(recordIndex));
} }
return null; return null;
} }
@ -845,7 +887,9 @@ public class GDBTraceControl_7_2 extends AbstractDsfService implements IGDBTrace
if (context instanceof MITraceRecordDMContext) { if (context instanceof MITraceRecordDMContext) {
ITraceTargetDMContext targetDmc = DMContexts.getAncestorOfType(context, ITraceTargetDMContext.class); ITraceTargetDMContext targetDmc = DMContexts.getAncestorOfType(context, ITraceTargetDMContext.class);
final int reference = ((MITraceRecordDMContext)context).getReference(); String recordId = ((MITraceRecordDMContext)context).getRecordId();
final int reference = Integer.parseInt(recordId);
if (reference < 0) { if (reference < 0) {
// This is how we indicate that we want to exit visualization mode // This is how we indicate that we want to exit visualization mode
// We should have a specific call in the IGDBTraceControl interface to do this. // We should have a specific call in the IGDBTraceControl interface to do this.
@ -981,9 +1025,44 @@ public class GDBTraceControl_7_2 extends AbstractDsfService implements IGDBTrace
}); });
} }
public void getTraceRecordData(ITraceRecordDMContext context, DataRequestMonitor<ITraceRecordDMData> rm) { public void getTraceRecordData(final ITraceRecordDMContext context, final DataRequestMonitor<ITraceRecordDMData> rm) {
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, NOT_SUPPORTED, "Not implemented.", null)); //$NON-NLS-1$ if (context instanceof MITraceRecordDMContext) {
rm.done();
RequestMonitor tdumpRm = new RequestMonitor(ImmediateExecutor.getInstance(), rm) {
@Override
protected void handleSuccess() {
fConnection.queueCommand(
fCommandFactory.createCLITraceDump(context),
new DataRequestMonitor<CLITraceDumpInfo>(getExecutor(), rm) {
@Override
protected void handleSuccess() {
TraceRecordDMData data = new TraceRecordDMData(
getData().getContent(),
getData().getTracepointNumber(),
getData().getFrameNumber(),
getData().getTimestamp()
);
rm.setData(data);
rm.done();
}
});
}
};
// If we are pointing to the right context, we can do the tdump right away,
// if not, we should first select the record.
// This is because 'tdump' does not take any parameters to specify
// which record we want to dump.
if (fCurrentRecordDmc.equals(context)) {
tdumpRm.done();
} else {
selectTraceRecord(context, tdumpRm);
}
} else {
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INTERNAL_ERROR, "Invalid trace record context.", null)); //$NON-NLS-1$
rm.done();
}
} }
public void flushCache(IDMContext context) { public void flushCache(IDMContext context) {

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2010 Ericsson and others. * Copyright (c) 2010, 2011 Ericsson and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -39,13 +39,39 @@ public interface IGDBTraceControl extends IDsfService {
* Specific Trace Record context. It describes tracing data. * Specific Trace Record context. It describes tracing data.
*/ */
@Immutable @Immutable
public interface ITraceRecordDMContext extends IDMContext {} public interface ITraceRecordDMContext extends IDMContext {
/**
* Returns the GDB id to the trace record. Can return null
* if the context does not point to a valid trace record.
* @since 4.0
*/
String getRecordId();
}
/** /**
* This is the model data interface that corresponds to ITraceRecordDMContext. * This is the model data interface that corresponds to ITraceRecordDMContext.
* The content of the data is backend-specific and therefore is not specified here.
*/ */
public interface ITraceRecordDMData extends IDMData { public interface ITraceRecordDMData extends IDMData {
/**
* Return the content of the trace record in the form of a string
* @since 4.0
*/
String getContent();
/**
* Return the timestamp of the trace record. Can return null.
* @since 4.0
*/
String getTimestamp();
/**
* Return the GDB tracepoint number
* @since 4.0
*/
String getTracepointNumber();
/**
* Returns the GDB id to the trace record
* @since 4.0
*/
String getRecordId();
} }
/** /**
@ -113,6 +139,9 @@ public interface IGDBTraceControl extends IDsfService {
*/ */
public void selectTraceRecord(ITraceRecordDMContext context, RequestMonitor rm); public void selectTraceRecord(ITraceRecordDMContext context, RequestMonitor rm);
/**
* Get the data associated to current GDB tracepoint record
*/
public void getTraceRecordData(ITraceRecordDMContext context, DataRequestMonitor<ITraceRecordDMData> rm); public void getTraceRecordData(ITraceRecordDMContext context, DataRequestMonitor<ITraceRecordDMData> rm);
///////////////////////////////////////////////// /////////////////////////////////////////////////
@ -161,7 +190,8 @@ public interface IGDBTraceControl extends IDsfService {
*/ */
public void getTraceVariables(ITraceTargetDMContext context, DataRequestMonitor<ITraceVariableDMData[]> rm); public void getTraceVariables(ITraceTargetDMContext context, DataRequestMonitor<ITraceVariableDMData[]> rm);
public ITraceRecordDMContext createTraceRecordContext(ITraceTargetDMContext ctx, int index); /** @since 4.0 */
public ITraceRecordDMContext createTraceRecordContext(ITraceTargetDMContext ctx, String recordId);
public void getCurrentTraceRecordContext(ITraceTargetDMContext context, DataRequestMonitor<ITraceRecordDMContext> drm); public void getCurrentTraceRecordContext(ITraceTargetDMContext context, DataRequestMonitor<ITraceRecordDMContext> drm);
public ITraceRecordDMContext createNextRecordContext(ITraceRecordDMContext ctx); public ITraceRecordDMContext createNextRecordContext(ITraceRecordDMContext ctx);
public ITraceRecordDMContext createPrevRecordContext(ITraceRecordDMContext ctx); public ITraceRecordDMContext createPrevRecordContext(ITraceRecordDMContext ctx);

View file

@ -29,6 +29,7 @@ import org.eclipse.cdt.dsf.debug.service.IRunControl.IExecutionDMContext;
import org.eclipse.cdt.dsf.debug.service.IStack.IFrameDMContext; import org.eclipse.cdt.dsf.debug.service.IStack.IFrameDMContext;
import org.eclipse.cdt.dsf.debug.service.command.ICommand; import org.eclipse.cdt.dsf.debug.service.command.ICommand;
import org.eclipse.cdt.dsf.debug.service.command.ICommandControlService.ICommandControlDMContext; import org.eclipse.cdt.dsf.debug.service.command.ICommandControlService.ICommandControlDMContext;
import org.eclipse.cdt.dsf.gdb.service.IGDBTraceControl.ITraceRecordDMContext;
import org.eclipse.cdt.dsf.gdb.service.IGDBTraceControl.ITraceTargetDMContext; import org.eclipse.cdt.dsf.gdb.service.IGDBTraceControl.ITraceTargetDMContext;
import org.eclipse.cdt.dsf.mi.service.IMIContainerDMContext; import org.eclipse.cdt.dsf.mi.service.IMIContainerDMContext;
import org.eclipse.cdt.dsf.mi.service.IMIExecutionDMContext; import org.eclipse.cdt.dsf.mi.service.IMIExecutionDMContext;
@ -46,6 +47,7 @@ import org.eclipse.cdt.dsf.mi.service.command.commands.CLIRecord;
import org.eclipse.cdt.dsf.mi.service.command.commands.CLISource; import org.eclipse.cdt.dsf.mi.service.command.commands.CLISource;
import org.eclipse.cdt.dsf.mi.service.command.commands.CLIThread; import org.eclipse.cdt.dsf.mi.service.command.commands.CLIThread;
import org.eclipse.cdt.dsf.mi.service.command.commands.CLITrace; import org.eclipse.cdt.dsf.mi.service.command.commands.CLITrace;
import org.eclipse.cdt.dsf.mi.service.command.commands.CLITraceDump;
import org.eclipse.cdt.dsf.mi.service.command.commands.CLIUnsetEnv; import org.eclipse.cdt.dsf.mi.service.command.commands.CLIUnsetEnv;
import org.eclipse.cdt.dsf.mi.service.command.commands.MIAddInferior; import org.eclipse.cdt.dsf.mi.service.command.commands.MIAddInferior;
import org.eclipse.cdt.dsf.mi.service.command.commands.MIBreakAfter; import org.eclipse.cdt.dsf.mi.service.command.commands.MIBreakAfter;
@ -150,6 +152,7 @@ import org.eclipse.cdt.dsf.mi.service.command.output.CLIInfoProgramInfo;
import org.eclipse.cdt.dsf.mi.service.command.output.CLIInfoSharedLibraryInfo; import org.eclipse.cdt.dsf.mi.service.command.output.CLIInfoSharedLibraryInfo;
import org.eclipse.cdt.dsf.mi.service.command.output.CLIInfoThreadsInfo; import org.eclipse.cdt.dsf.mi.service.command.output.CLIInfoThreadsInfo;
import org.eclipse.cdt.dsf.mi.service.command.output.CLIThreadInfo; import org.eclipse.cdt.dsf.mi.service.command.output.CLIThreadInfo;
import org.eclipse.cdt.dsf.mi.service.command.output.CLITraceDumpInfo;
import org.eclipse.cdt.dsf.mi.service.command.output.CLITraceInfo; import org.eclipse.cdt.dsf.mi.service.command.output.CLITraceInfo;
import org.eclipse.cdt.dsf.mi.service.command.output.MIAddInferiorInfo; import org.eclipse.cdt.dsf.mi.service.command.output.MIAddInferiorInfo;
import org.eclipse.cdt.dsf.mi.service.command.output.MIBreakInsertInfo; import org.eclipse.cdt.dsf.mi.service.command.output.MIBreakInsertInfo;
@ -267,6 +270,11 @@ public class CommandFactory {
return new CLITrace(ctx, location, condition); return new CLITrace(ctx, location, condition);
} }
/** @since 4.0 */
public ICommand<CLITraceDumpInfo> createCLITraceDump(ITraceRecordDMContext ctx) {
return new CLITraceDump(ctx);
}
public ICommand<MIInfo> createCLIUnsetEnv(ICommandControlDMContext ctx) { public ICommand<MIInfo> createCLIUnsetEnv(ICommandControlDMContext ctx) {
return new CLIUnsetEnv(ctx); return new CLIUnsetEnv(ctx);
} }

View file

@ -0,0 +1,36 @@
/*******************************************************************************
* Copyright (c) 2011 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:
* Ericsson - Initial implementation
*******************************************************************************/
package org.eclipse.cdt.dsf.mi.service.command.commands;
import org.eclipse.cdt.dsf.gdb.service.IGDBTraceControl.ITraceRecordDMContext;
import org.eclipse.cdt.dsf.mi.service.command.output.MIOutput;
import org.eclipse.cdt.dsf.mi.service.command.output.CLITraceDumpInfo;
/**
* GDB tdump CLI command.
* @since 4.0
*
*/
public class CLITraceDump extends CLICommand<CLITraceDumpInfo> {
/**
* @param ctx trace context
*/
public CLITraceDump(ITraceRecordDMContext ctx) {
super(ctx, "tdump"); //$NON-NLS-1$
}
@Override
public CLITraceDumpInfo getResult(MIOutput out) {
return new CLITraceDumpInfo(out);
}
}

View file

@ -0,0 +1,660 @@
/*******************************************************************************
* Copyright (c) 2011 Ericsson and others
* 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:
* Ericsson - Initial implementation
*******************************************************************************/
package org.eclipse.cdt.dsf.mi.service.command.output;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* Parses the GDB "tdump" command printout, as returned by GDB, to make it a
* bit more human-friendly.
* <p>
* See bottom of this file for a raw example of what is
* returned by "tdump"
* @since 4.0
*/
public class CLITraceDumpInfo extends MIInfo {
// Here is what this pattern looks-for - the first line of the tdump printout:
//~"Data collected at tracepoint 2, trace frame 555:\n"
private static final Pattern RESULT_PATTERN_TPINFO = Pattern.compile(
"Data collected at tracepoint (\\d+), trace frame (\\d+)", Pattern.CASE_INSENSITIVE); //$NON-NLS-1$
// raw output of command
private String fOutput = null;
private String fParsedOutput = null;
// tdump parsed info
private String fTracepointNum = null;
private String fTraceFrameNumber = null;
/*
* Timestamp, if present in tracepoint frame data
* Note: not yet available in printout of command
* "tdump" -> revisit when it is.
*/
private String timestamp = null;
// keep the tdump header in parsed result or not - by default we keep
private static final boolean KEEP_HEADER = true;
/**
* Constructor.
* @param out the output of the tdump printout
*/
public CLITraceDumpInfo(MIOutput out) {
super(out);
parse(KEEP_HEADER);
}
/**
* Alternative constructor. Use this one to have control if the tdump
* header is kept or not in the result.
* @param out the output of the tdump printout
* @param keepHeader keep the tdump header in result or not
*/
public CLITraceDumpInfo(MIOutput out, boolean keepHeader) {
super(out);
parse(keepHeader);
}
/**
* Do a quick parse of the tdump printout. The tdump command printout is
* split in short pieces (records), each one wrapped like this:
* <p>
* ~"eax 0x10"
* <p>
* Also, tabs and newlines are represented by symbols: \n and \t .
* <p>
* In this method, we strip the wrapping off each record and translate the
* symbols to their value. The resulting string is not parsed further.
* <p>
* See an example of a tdump printout at the end of this file.
*/
private void parse(boolean keepHeader) {
final Pattern RESULT_PATTERN_UNWRAPRECORD = Pattern.compile("~\"(.*)\"", Pattern.CANON_EQ); //$NON-NLS-1$
StringBuffer buf = new StringBuffer();
String unwrapped;
if (isDone()) {
MIOutput out = getMIOutput();
// save raw output of command
fOutput = out.toString();
MIOOBRecord[] oobs = out.getMIOOBRecords();
for (MIOOBRecord oob : oobs) {
if (oob instanceof MIConsoleStreamOutput) {
Matcher matcher = RESULT_PATTERN_UNWRAPRECORD.matcher(oob.toString());
if (matcher.find()) {
unwrapped = matcher.group(1);
// accumulate the records into a buffer
buf.append(unwrapped);
}
}
}
// convert buffer into string
fParsedOutput = buf.toString();
// extract the tracepoint and frame numbers
Matcher matcher = RESULT_PATTERN_TPINFO.matcher(fParsedOutput);
if (matcher.find()) {
fTracepointNum = matcher.group(1).trim();
fTraceFrameNumber = matcher.group(2).trim();
}
// command result has the substrings "\n" and "\t" in it.
// replace them by their actual meaning (real newline and tab)
fParsedOutput = fParsedOutput.replaceAll("\\\\n", "\n"); //$NON-NLS-1$ //$NON-NLS-2$
fParsedOutput = fParsedOutput.replaceAll("\\\\t+", "\t"); //$NON-NLS-1$ //$NON-NLS-2$
// Optionaly remove the header line from tdump printout
if(!keepHeader) {
fParsedOutput = fParsedOutput.replaceFirst("Data collected at tracepoint \\d+, trace frame \\d+:\\n", ""); //$NON-NLS-1$ //$NON-NLS-2$
}
}
}
/**
* @return the raw output of tdump.
*/
public String getOutput() {
return fOutput;
}
/**
* @return a String containing the semi-parsed
* register and local variables, as listed by
* tdump.
*/
public String getContent() {
return fParsedOutput;
}
/**
* @return the tracepoint number
*/
public String getTracepointNumber() {
return fTracepointNum;
}
/**
* @return the trace's frame number
*/
public String getFrameNumber() {
return fTraceFrameNumber;
}
/**
* @return the timestamp of the tracepoint frame
*/
public String getTimestamp() {
return timestamp;
}
}
/*
* Example of raw output from command tdump:
&"tdump\n"
~"Data collected at tracepoint 2, trace frame 555:\n"
~"eax 0x10"
~"\t16"
~"\n"
~"ecx 0x0"
~"\t0"
~"\n"
~"edx 0x0"
~"\t0"
~"\n"
~"ebx 0x11"
~"\t17"
~"\n"
~"esp 0xbfec14c0"
~"\t0xbfec14c0\n"
~"ebp 0xbfec1508"
~"\t0xbfec1508\n"
~"esi 0x0"
~"\t0"
~"\n"
~"edi 0x0"
~"\t0"
~"\n"
~"eip 0x8048520"
~"\t0x8048520 <factorial1(unsigned long long)+45>\n"
~"eflags 0x216"
~"\t[ PF AF IF ]"
~"\n"
~"cs 0x73"
~"\t115"
~"\n"
~"ss 0x7b"
~"\t123"
~"\n"
~"ds 0x7b"
~"\t123"
~"\n"
~"es 0x7b"
~"\t123"
~"\n"
~"fs 0x0"
~"\t0"
~"\n"
~"gs 0x33"
~"\t51"
~"\n"
~"st0 0"
~"\t(raw 0x00000000000000000000)\n"
~"st1 0"
~"\t(raw 0x00000000000000000000)\n"
~"st2 0"
~"\t(raw 0x00000000000000000000)\n"
~"st3 0"
~"\t(raw 0x00000000000000000000)\n"
~"st4 0"
~"\t(raw 0x00000000000000000000)\n"
~"st5 0"
~"\t(raw 0x00000000000000000000)\n"
~"st6 0"
~"\t(raw 0x00000000000000000000)\n"
~"st7 0"
~"\t(raw 0x00000000000000000000)\n"
~"fctrl 0x37f"
~"\t895"
~"\n"
~"fstat 0x0"
~"\t0"
~"\n"
~"ftag 0xffff"
~"\t65535"
~"\n"
~"fiseg 0x73"
~"\t115"
~"\n"
~"fioff 0x718d9c"
~"\t7441820"
~"\n"
~"foseg 0x7b"
~"\t123"
~"\n"
~"fooff 0x754928"
~"\t7686440"
~"\n"
~"fop 0x599"
~"\t1433"
~"\n"
~"xmm0 {v4_float = {0x0"
~", 0x0"
~", 0x0"
~", 0x0"
~"}"
~", v2_double = {0x0"
~", 0x0"
~"}"
~", v16_int8 = {0x0"
~" <repeats 16 times>}"
~", v8_int16 = {0x0"
~", 0x0"
~", 0x0"
~", 0x0"
~", 0x0"
~", 0x0"
~", 0x0"
~", 0x0"
~"}"
~", v4_int32 = {0x0"
~", 0x0"
~", 0x0"
~", 0x0"
~"}"
~", v2_int64 = {0x0"
~", 0x0"
~"}"
~", uint128 = 0x00000000000000000000000000000000"
~"}"
~"\n"
~"xmm1 {v4_float = {0x0"
~", 0x0"
~", 0x0"
~", 0x0"
~"}"
~", v2_double = {0x0"
~", 0x0"
~"}"
~", v16_int8 = {0x0"
~" <repeats 16 times>}"
~", v8_int16 = {0x0"
~", 0x0"
~", 0x0"
~", 0x0"
~", 0x0"
~", 0x0"
~", 0x0"
~", 0x0"
~"}"
~", v4_int32 = {0x0"
~", 0x0"
~", 0x0"
~", 0x0"
~"}"
~", v2_int64 = {0x0"
~", 0x0"
~"}"
~", uint128 = 0x00000000000000000000000000000000"
~"}"
~"\n"
~"xmm2 {v4_float = {0x0"
~", 0x0"
~", 0x0"
~", 0x0"
~"}"
~", v2_double = {0x0"
~", 0x0"
~"}"
~", v16_int8 = {0x0"
~" <repeats 16 times>}"
~", v8_int16 = {0x0"
~", 0x0"
~", 0x0"
~", 0x0"
~", 0x0"
~", 0x0"
~", 0x0"
~", 0x0"
~"}"
~", v4_int32 = {0x0"
~", 0x0"
~", 0x0"
~", 0x0"
~"}"
~", v2_int64 = {0x0"
~", 0x0"
~"}"
~", uint128 = 0x00000000000000000000000000000000"
~"}"
~"\n"
~"xmm3 {v4_float = {0x0"
~", 0x0"
~", 0x0"
~", 0x0"
~"}"
~", v2_double = {0x0"
~", 0x0"
~"}"
~", v16_int8 = {0x0"
~" <repeats 16 times>}"
~", v8_int16 = {0x0"
~", 0x0"
~", 0x0"
~", 0x0"
~", 0x0"
~", 0x0"
~", 0x0"
~", 0x0"
~"}"
~", v4_int32 = {0x0"
~", 0x0"
~", 0x0"
~", 0x0"
~"}"
~", v2_int64 = {0x0"
~", 0x0"
~"}"
~", uint128 = 0x00000000000000000000000000000000"
~"}"
~"\n"
~"xmm4 {v4_float = {0x0"
~", 0x0"
~", 0x0"
~", 0x0"
~"}"
~", v2_double = {0x0"
~", 0x0"
~"}"
~", v16_int8 = {0x0"
~" <repeats 16 times>}"
~", v8_int16 = {0x0"
~", 0x0"
~", 0x0"
~", 0x0"
~", 0x0"
~", 0x0"
~", 0x0"
~", 0x0"
~"}"
~", v4_int32 = {0x0"
~", 0x0"
~", 0x0"
~", 0x0"
~"}"
~", v2_int64 = {0x0"
~", 0x0"
~"}"
~", uint128 = 0x00000000000000000000000000000000"
~"}"
~"\n"
~"xmm5 {v4_float = {0x0"
~", 0x0"
~", 0x0"
~", 0x0"
~"}"
~", v2_double = {0x0"
~", 0x0"
~"}"
~", v16_int8 = {0x0"
~" <repeats 16 times>}"
~", v8_int16 = {0x0"
~", 0x0"
~", 0x0"
~", 0x0"
~", 0x0"
~", 0x0"
~", 0x0"
~", 0x0"
~"}"
~", v4_int32 = {0x0"
~", 0x0"
~", 0x0"
~", 0x0"
~"}"
~", v2_int64 = {0x0"
~", 0x0"
~"}"
~", uint128 = 0x00000000000000000000000000000000"
~"}"
~"\n"
~"xmm6 {v4_float = {0x0"
~", 0x0"
~", 0x0"
~", 0x0"
~"}"
~", v2_double = {0x0"
~", 0x0"
~"}"
~", v16_int8 = {0x0"
~" <repeats 16 times>}"
~", v8_int16 = {0x0"
~", 0x0"
~", 0x0"
~", 0x0"
~", 0x0"
~", 0x0"
~", 0x0"
~", 0x0"
~"}"
~", v4_int32 = {0x0"
~", 0x0"
~", 0x0"
~", 0x0"
~"}"
~", v2_int64 = {0x0"
~", 0x0"
~"}"
~", uint128 = 0x00000000000000000000000000000000"
~"}"
~"\n"
~"xmm7 {v4_float = {0x0"
~", 0x0"
~", 0x0"
~", 0x0"
~"}"
~", v2_double = {0x0"
~", 0x0"
~"}"
~", v16_int8 = {0x0"
~" <repeats 16 times>}"
~", v8_int16 = {0x0"
~", 0x0"
~", 0x0"
~", 0x0"
~", 0x0"
~", 0x0"
~", 0x0"
~", 0x0"
~"}"
~", v4_int32 = {0x0"
~", 0x0"
~", 0x0"
~", 0x0"
~"}"
~", v2_int64 = {0x0"
~", 0x0"
~"}"
~", uint128 = 0x00000000000000000000000000000000"
~"}"
~"\n"
~"mxcsr 0x1f80"
~"\t[ IM DM ZM OM UM PM ]"
~"\n"
~"mm0 {uint64 = 0x0"
~", v2_int32 = {0x0"
~", 0x0"
~"}"
~", v4_int16 = {0x0"
~", 0x0"
~", 0x0"
~", 0x0"
~"}"
~", v8_int8 = {0x0"
~", 0x0"
~", 0x0"
~", 0x0"
~", 0x0"
~", 0x0"
~", 0x0"
~", 0x0"
~"}"
~"}"
~"\n"
~"mm1 {uint64 = 0x0"
~", v2_int32 = {0x0"
~", 0x0"
~"}"
~", v4_int16 = {0x0"
~", 0x0"
~", 0x0"
~", 0x0"
~"}"
~", v8_int8 = {0x0"
~", 0x0"
~", 0x0"
~", 0x0"
~", 0x0"
~", 0x0"
~", 0x0"
~", 0x0"
~"}"
~"}"
~"\n"
~"mm2 {uint64 = 0x0"
~", v2_int32 = {0x0"
~", 0x0"
~"}"
~", v4_int16 = {0x0"
~", 0x0"
~", 0x0"
~", 0x0"
~"}"
~", v8_int8 = {0x0"
~", 0x0"
~", 0x0"
~", 0x0"
~", 0x0"
~", 0x0"
~", 0x0"
~", 0x0"
~"}"
~"}"
~"\n"
~"mm3 {uint64 = 0x0"
~", v2_int32 = {0x0"
~", 0x0"
~"}"
~", v4_int16 = {0x0"
~", 0x0"
~", 0x0"
~", 0x0"
~"}"
~", v8_int8 = {0x0"
~", 0x0"
~", 0x0"
~", 0x0"
~", 0x0"
~", 0x0"
~", 0x0"
~", 0x0"
~"}"
~"}"
~"\n"
~"mm4 {uint64 = 0x0"
~", v2_int32 = {0x0"
~", 0x0"
~"}"
~", v4_int16 = {0x0"
~", 0x0"
~", 0x0"
~", 0x0"
~"}"
~", v8_int8 = {0x0"
~", 0x0"
~", 0x0"
~", 0x0"
~", 0x0"
~", 0x0"
~", 0x0"
~", 0x0"
~"}"
~"}"
~"\n"
~"mm5 {uint64 = 0x0"
~", v2_int32 = {0x0"
~", 0x0"
~"}"
~", v4_int16 = {0x0"
~", 0x0"
~", 0x0"
~", 0x0"
~"}"
~", v8_int8 = {0x0"
~", 0x0"
~", 0x0"
~", 0x0"
~", 0x0"
~", 0x0"
~", 0x0"
~", 0x0"
~"}"
~"}"
~"\n"
~"mm6 {uint64 = 0x0"
~", v2_int32 = {0x0"
~", 0x0"
~"}"
~", v4_int16 = {0x0"
~", 0x0"
~", 0x0"
~", 0x0"
~"}"
~", v8_int8 = {0x0"
~", 0x0"
~", 0x0"
~", 0x0"
~", 0x0"
~", 0x0"
~", 0x0"
~", 0x0"
~"}"
~"}"
~"\n"
~"mm7 {uint64 = 0x0"
~", v2_int32 = {0x0"
~", 0x0"
~"}"
~", v4_int16 = {0x0"
~", 0x0"
~", 0x0"
~", 0x0"
~"}"
~", v8_int8 = {0x0"
~", 0x0"
~", 0x0"
~", 0x0"
~", 0x0"
~", 0x0"
~", 0x0"
~", 0x0"
~"}"
~"}"
~"\n"
~"a = 16"
~"\n"
27^done
*/