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:
parent
e96dfd110a
commit
559736718a
6 changed files with 838 additions and 25 deletions
|
@ -285,7 +285,7 @@ public class TraceControlView extends ViewPart implements IViewPart, SessionEnde
|
|||
protected void execute(DataRequestMonitor<Object> rm) {
|
||||
final IGDBTraceControl traceControl = getService(IGDBTraceControl.class);
|
||||
if (traceControl != null) {
|
||||
ITraceRecordDMContext emptyDmc = traceControl.createTraceRecordContext(ctx, -1);
|
||||
ITraceRecordDMContext emptyDmc = traceControl.createTraceRecordContext(ctx, "-1"); //$NON-NLS-1$
|
||||
traceControl.selectTraceRecord(emptyDmc, rm);
|
||||
} else {
|
||||
rm.setData(null);
|
||||
|
|
|
@ -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
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
|
@ -13,6 +13,7 @@ package org.eclipse.cdt.dsf.gdb.service;
|
|||
import java.util.Hashtable;
|
||||
|
||||
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.RequestMonitor;
|
||||
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.command.CommandFactory;
|
||||
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.MIResultRecord;
|
||||
import org.eclipse.cdt.dsf.mi.service.command.output.MITraceFindInfo;
|
||||
|
@ -56,20 +58,22 @@ public class GDBTraceControl_7_2 extends AbstractDsfService implements IGDBTrace
|
|||
@Immutable
|
||||
protected static final class MITraceRecordDMContext extends AbstractDMContext implements ITraceRecordDMContext {
|
||||
|
||||
// The trace record reference
|
||||
private final int fReference;
|
||||
// The trace record GDB reference
|
||||
private final String fReference;
|
||||
|
||||
/**
|
||||
* @param session the DsfSession for this service
|
||||
* @param parents the parent contexts
|
||||
* @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 });
|
||||
fReference = reference;
|
||||
}
|
||||
|
||||
public int getReference() {
|
||||
/** @since 4.0 */
|
||||
public String getRecordId() {
|
||||
return fReference;
|
||||
}
|
||||
|
||||
|
@ -78,7 +82,8 @@ public class GDBTraceControl_7_2 extends AbstractDsfService implements IGDBTrace
|
|||
*/
|
||||
@Override
|
||||
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)
|
||||
|
@ -86,7 +91,7 @@ public class GDBTraceControl_7_2 extends AbstractDsfService implements IGDBTrace
|
|||
*/
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return baseHashCode() + fReference;
|
||||
return baseHashCode() ^ (fReference == null ? 0 : fReference.hashCode());
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
|
@ -113,6 +118,10 @@ public class GDBTraceControl_7_2 extends AbstractDsfService implements IGDBTrace
|
|||
super(session.getId(), new IDMContext[] { parent });
|
||||
}
|
||||
|
||||
/** @since 4.0 */
|
||||
public String getRecordId() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @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 int fFreeBufferSize;
|
||||
private int fTotalBufferSize;
|
||||
|
@ -249,7 +288,7 @@ public class GDBTraceControl_7_2 extends AbstractDsfService implements IGDBTrace
|
|||
|
||||
if (fCurrentRecordDmc instanceof MITraceRecordDMContext) {
|
||||
str += "Looking at trace frame " +
|
||||
((MITraceRecordDMContext)fCurrentRecordDmc).getReference() +
|
||||
((MITraceRecordDMContext)fCurrentRecordDmc).getRecordId() +
|
||||
", tracepoint " + fTracepointIndexForTraceRecord + "\n\n";
|
||||
} else {
|
||||
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
|
||||
// of the frame when we load a trace file.
|
||||
// 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);
|
||||
}
|
||||
});
|
||||
|
@ -785,19 +824,21 @@ public class GDBTraceControl_7_2 extends AbstractDsfService implements IGDBTrace
|
|||
|
||||
/**
|
||||
* Create a trace record context
|
||||
* @since 4.0
|
||||
*/
|
||||
public ITraceRecordDMContext createTraceRecordContext(ITraceTargetDMContext ctx, int index) {
|
||||
return new MITraceRecordDMContext(getSession(), ctx, index);
|
||||
public ITraceRecordDMContext createTraceRecordContext(ITraceTargetDMContext ctx, String recordId) {
|
||||
return new MITraceRecordDMContext(getSession(), ctx, recordId);
|
||||
}
|
||||
|
||||
public ITraceRecordDMContext createNextRecordContext(ITraceRecordDMContext ctx) {
|
||||
ITraceTargetDMContext targetDmc = DMContexts.getAncestorOfType(ctx, ITraceTargetDMContext.class);
|
||||
if (ctx instanceof InvalidTraceRecordDMContext) {
|
||||
// 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) {
|
||||
int recordIndex = ((MITraceRecordDMContext)ctx).getReference();
|
||||
String recordId = ((MITraceRecordDMContext)ctx).getRecordId();
|
||||
int recordIndex = Integer.parseInt(recordId);
|
||||
recordIndex++;
|
||||
if (recordIndex == fTraceRecordsStored) {
|
||||
// Loop back to the front
|
||||
|
@ -805,7 +846,7 @@ public class GDBTraceControl_7_2 extends AbstractDsfService implements IGDBTrace
|
|||
}
|
||||
return new MITraceRecordDMContext(getSession(),
|
||||
targetDmc,
|
||||
recordIndex);
|
||||
Integer.toString(recordIndex));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
@ -813,7 +854,8 @@ public class GDBTraceControl_7_2 extends AbstractDsfService implements IGDBTrace
|
|||
public ITraceRecordDMContext createPrevRecordContext(ITraceRecordDMContext ctx) {
|
||||
if (ctx instanceof MITraceRecordDMContext) {
|
||||
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) {
|
||||
// Loop back to the end
|
||||
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--;
|
||||
return new MITraceRecordDMContext(getSession(),
|
||||
targetDmc,
|
||||
recordIndex);
|
||||
Integer.toString(recordIndex));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
@ -845,7 +887,9 @@ public class GDBTraceControl_7_2 extends AbstractDsfService implements IGDBTrace
|
|||
|
||||
if (context instanceof MITraceRecordDMContext) {
|
||||
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) {
|
||||
// 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.
|
||||
|
@ -981,10 +1025,45 @@ public class GDBTraceControl_7_2 extends AbstractDsfService implements IGDBTrace
|
|||
});
|
||||
}
|
||||
|
||||
public void getTraceRecordData(ITraceRecordDMContext context, DataRequestMonitor<ITraceRecordDMData> rm) {
|
||||
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, NOT_SUPPORTED, "Not implemented.", null)); //$NON-NLS-1$
|
||||
public void getTraceRecordData(final ITraceRecordDMContext context, final DataRequestMonitor<ITraceRecordDMData> rm) {
|
||||
if (context instanceof MITraceRecordDMContext) {
|
||||
|
||||
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) {
|
||||
fTraceCache.reset(context);
|
||||
|
|
|
@ -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
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* 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.
|
||||
*/
|
||||
@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.
|
||||
* The content of the data is backend-specific and therefore is not specified here.
|
||||
*/
|
||||
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);
|
||||
|
||||
/**
|
||||
* Get the data associated to current GDB tracepoint record
|
||||
*/
|
||||
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 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 ITraceRecordDMContext createNextRecordContext(ITraceRecordDMContext ctx);
|
||||
public ITraceRecordDMContext createPrevRecordContext(ITraceRecordDMContext ctx);
|
||||
|
|
|
@ -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.command.ICommand;
|
||||
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.mi.service.IMIContainerDMContext;
|
||||
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.CLIThread;
|
||||
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.MIAddInferior;
|
||||
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.CLIInfoThreadsInfo;
|
||||
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.MIAddInferiorInfo;
|
||||
import org.eclipse.cdt.dsf.mi.service.command.output.MIBreakInsertInfo;
|
||||
|
@ -267,6 +270,11 @@ public class CommandFactory {
|
|||
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) {
|
||||
return new CLIUnsetEnv(ctx);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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
|
||||
*/
|
Loading…
Add table
Reference in a new issue