1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-08-10 09:45:39 +02:00

Bug 390827 - Trace View enhancement

Enhance Trace Control View UI.

Change-Id: I3ae49dece2056c8e8fd9eb21118926b039a5cdf0
Signed-off-by: Dmitry Kozlov <ddk@codesourcery.com>
Reviewed-on: https://git.eclipse.org/r/7997
Reviewed-by: Marc Khouzam <marc.khouzam@ericsson.com>
IP-Clean: Marc Khouzam <marc.khouzam@ericsson.com>
Tested-by: Marc Khouzam <marc.khouzam@ericsson.com>
Reviewed-by: Mikhail Khodjaiants <mikhailkhod@googlemail.com>
IP-Clean: Mikhail Khodjaiants <mikhailkhod@googlemail.com>
Tested-by: Mikhail Khodjaiants <mikhailkhod@googlemail.com>
This commit is contained in:
Dmitry Kozlov 2013-07-11 21:00:34 +04:00 committed by Mikhail Khodjaiants
parent 412727c5cb
commit 9ddde64119
33 changed files with 2505 additions and 656 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 411 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 913 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 375 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 964 B

After

Width:  |  Height:  |  Size: 961 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 881 B

After

Width:  |  Height:  |  Size: 115 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 210 B

View file

@ -282,9 +282,9 @@
<perspectiveExtension
targetID="org.eclipse.debug.ui.DebugPerspective">
<view
relative="org.eclipse.ui.views.ContentOutline"
relative="org.eclipse.debug.ui.DebugView"
visible="false"
relationship="stack"
relationship="right"
id="org.eclipse.cdt.dsf.gdb.ui.tracecontrol.view">
</view>
<viewShortcut
@ -344,16 +344,13 @@
label="%toolbar.prevTraceRecord.label"
style="push">
</command>
<command
commandId="org.eclipse.cdt.debug.ui.command.saveTraceData"
icon="icons/full/obj16/savetrace.gif"
label="%toolbar.saveTracing.name"
style="push">
</command>
</menuContribution>
<menuContribution
locationURI="menu:org.eclipse.cdt.dsf.gdb.ui.tracecontrol.view?after=additions">
<command
commandId="org.eclipse.cdt.debug.ui.command.saveTraceData"
icon="icons/full/obj16/savetrace.gif"
label="%toolbar.saveTracing.name"
style="push">
</command>
</menuContribution>
</extension>
<extension
point="org.eclipse.cdt.debug.ui.BreakpointActionPage">

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2010, 2011 Ericsson and others.
* Copyright (c) 2010, 2013 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
@ -7,6 +7,7 @@
*
* Contributors:
* Ericsson - initial API and implementation
* Marc Khouzam (Ericsson) - Disable button when no trace record is selected
*******************************************************************************/
package org.eclipse.cdt.dsf.gdb.internal.ui.commands;
@ -25,6 +26,7 @@ import org.eclipse.cdt.dsf.gdb.service.GDBTraceControl_7_2.TraceRecordSelectedCh
import org.eclipse.cdt.dsf.gdb.service.IGDBTraceControl;
import org.eclipse.cdt.dsf.gdb.service.IGDBTraceControl.ITraceRecordDMContext;
import org.eclipse.cdt.dsf.gdb.service.IGDBTraceControl.ITraceStatusDMData;
import org.eclipse.cdt.dsf.gdb.service.IGDBTraceControl.ITraceStatusDMData2;
import org.eclipse.cdt.dsf.gdb.service.IGDBTraceControl.ITraceTargetDMContext;
import org.eclipse.cdt.dsf.service.DsfServicesTracker;
import org.eclipse.cdt.dsf.service.DsfSession;
@ -119,35 +121,37 @@ public class GdbSelectPrevTraceRecordCommand extends AbstractDebugCommand implem
Query<Boolean> canSelectRecordQuery = new Query<Boolean>() {
@Override
public void execute(final DataRequestMonitor<Boolean> rm) {
IGDBTraceControl traceControl = fTracker.getService(IGDBTraceControl.class);
final IGDBTraceControl traceControl = fTracker.getService(IGDBTraceControl.class);
if (traceControl != null) {
traceControl.getTraceStatus(dmc, new DataRequestMonitor<ITraceStatusDMData>(fExecutor, rm) {
@Override
protected void handleSuccess() {
if (getData().getNumberOfCollectedFrame() > 0) {
IGDBTraceControl traceControl = fTracker.getService(IGDBTraceControl.class);
if (traceControl != null) {
traceControl.isTracing(dmc, new DataRequestMonitor<Boolean>(fExecutor, rm) {
@Override
protected void handleSuccess() {
rm.setData(!getData());
rm.done();
};
});
} else {
rm.setData(false);
rm.done();
}
} else {
rm.setData(false);
rm.done();
if (getData().getNumberOfCollectedFrame() <= 0) {
// No frames to look at.
rm.done(false);
return;
}
if (getData() instanceof ITraceStatusDMData2) {
if (((ITraceStatusDMData2)getData()).getCurrentTraceFrameId() == null) {
// Haven't started looking at frames, so don't enable the "Previous" button
rm.done(false);
return;
}
}
traceControl.isTracing(dmc, new DataRequestMonitor<Boolean>(fExecutor, rm) {
@Override
protected void handleSuccess() {
// Can do visualization if we are tracing.
rm.done(!getData());
};
});
};
});
} else {
rm.setData(false);
rm.done();
rm.done(false);
}
}
};

View file

@ -16,10 +16,12 @@ import java.util.concurrent.RejectedExecutionException;
import org.eclipse.cdt.debug.core.model.IStartTracingHandler;
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
import org.eclipse.cdt.dsf.concurrent.DsfExecutor;
import org.eclipse.cdt.dsf.concurrent.ImmediateRequestMonitor;
import org.eclipse.cdt.dsf.concurrent.Query;
import org.eclipse.cdt.dsf.datamodel.DMContexts;
import org.eclipse.cdt.dsf.gdb.internal.ui.GdbUIPlugin;
import org.eclipse.cdt.dsf.gdb.service.IGDBTraceControl;
import org.eclipse.cdt.dsf.gdb.service.IGDBTraceControl2;
import org.eclipse.cdt.dsf.gdb.service.IGDBTraceControl.ITraceTargetDMContext;
import org.eclipse.cdt.dsf.service.DsfServicesTracker;
import org.eclipse.cdt.dsf.service.DsfSession;
@ -63,11 +65,20 @@ public class GdbStartTracingCommand extends AbstractDebugCommand implements ISta
Query<Object> startTracingQuery = new Query<Object>() {
@Override
public void execute(DataRequestMonitor<Object> rm) {
IGDBTraceControl traceControl = fTracker.getService(IGDBTraceControl.class);
if (traceControl != null) {
traceControl.startTracing(dmc, rm);
public void execute(final DataRequestMonitor<Object> rm) {
final IGDBTraceControl traceControl = fTracker.getService(IGDBTraceControl.class);
if (traceControl != null) {
String user = System.getProperty("user.name"); //$NON-NLS-1$
if (user != null && user.length() > 0 && traceControl instanceof IGDBTraceControl2) {
((IGDBTraceControl2)traceControl).setTraceUser(dmc, user, new ImmediateRequestMonitor() {
@Override
protected void handleCompleted() {
traceControl.startTracing(dmc, rm);
};
});
} else {
traceControl.startTracing(dmc, rm);
}
} else {
rm.done();
}

View file

@ -0,0 +1,103 @@
/*******************************************************************************
* Copyright (c) 2013 Mentor Graphics 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:
* Dmitry Kozlov (Mentor Graphics) - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.dsf.gdb.internal.ui.tracepoints;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Canvas;
import org.eclipse.swt.widgets.Composite;
public class CircularProgress extends Canvas {
private static final String PERCENT_SIGN = "%"; //$NON-NLS-1$
private static final String PERCENT_TEXT = "100%"; //$NON-NLS-1$
private static final int PROGRESS_WIDTH = 8;
private static final int PROGRESS_MARGIN = 2;
private static final int PROGRESS_ARC = 15;
final protected int[] fBufferProgressMeasure = {0};
public CircularProgress(Composite parent, int flags)
{
super(parent, flags);
addPaintListener(new PaintListener() {
@Override
public void paintControl(PaintEvent e) {
onPaint(e);
}
});
GC gc = new GC(this);
Point e = gc.textExtent(PERCENT_TEXT);
int size = e.x + 8 * PROGRESS_MARGIN + 2 * PROGRESS_WIDTH;
setBounds(0, 0, size, size);
}
/**
* Set progress as number of percent (0-100)
*/
public void setProgress(int progress) {
fBufferProgressMeasure[0] = progress;
}
@Override
public Point computeSize(int wHint, int hHint, boolean changed) {
return computeSize(wHint, hHint);
}
@Override
public Point computeSize(int wHint, int hHint) {
return new Point(getBounds().width, getBounds().height);
}
private void onPaint(PaintEvent e) {
Rectangle clientArea = getClientArea();
int margin = PROGRESS_MARGIN;
int width = PROGRESS_WIDTH;
e.gc.setBackground(getParent().getBackground());
e.gc.fillRectangle(0, 0, clientArea.width, clientArea.height);
e.gc.setBackground(getParent().getDisplay().getSystemColor(SWT.COLOR_GRAY));
e.gc.fillOval(margin, margin, clientArea.width-2*margin, clientArea.height-2*margin);
e.gc.setBackground(getParent().getBackground());
e.gc.fillOval(margin+width, margin+width, clientArea.width-2*(margin+width), clientArea.height-2*(margin+width));
String progress;
e.gc.setBackground(getParent().getDisplay().getSystemColor(SWT.COLOR_LIST_SELECTION));
if (0 <= fBufferProgressMeasure[0] && fBufferProgressMeasure[0] <= 100) {
// Draw usual progress bar and text value in %
progress = fBufferProgressMeasure[0] + PERCENT_SIGN;
int n = (int) (fBufferProgressMeasure[0] * 3.6);
e.gc.fillArc(margin, margin, clientArea.width-2*margin, clientArea.height-2*margin, 90 , -n );
} else {
// Draw constantly moving progress without exact value and text value 100%
progress = PERCENT_TEXT;
int n = (int) ((fBufferProgressMeasure[0] % 100) * 3.6);
// Fill in the full buffer first
e.gc.fillOval(margin, margin, clientArea.width-2*margin, clientArea.height-2*margin);
// Move progress bar within the buffer
e.gc.setBackground(getParent().getDisplay().getSystemColor(SWT.COLOR_DARK_GRAY));
e.gc.fillArc(margin, margin, clientArea.width-2*margin, clientArea.height-2*margin, 90 - n - PROGRESS_ARC, - PROGRESS_ARC );
}
e.gc.setBackground(getParent().getBackground());
e.gc.fillOval(margin+width, margin+width, clientArea.width-2*(margin+width), clientArea.width-2*(margin+width));
// Progress % in the text form
e.gc.setForeground(getParent().getDisplay().getSystemColor(SWT.COLOR_LIST_FOREGROUND));
e.gc.setFont(getParent().getDisplay().getSystemFont());
Point p = e.gc.textExtent(progress);
e.gc.drawText(progress,(clientArea.width - p.x)/2 + 1,(clientArea.height-p.y)/2);
}
}

View file

@ -7,6 +7,7 @@
*
* Contributors:
* Vladimir Prus (Mentor Graphics) - initial API and implementation
* Dmitry Kozlov (Mentor Graphics) - extend to be inheritance-friendly
*******************************************************************************/
package org.eclipse.cdt.dsf.gdb.internal.ui.tracepoints;
@ -28,9 +29,9 @@ import org.eclipse.swt.widgets.TypedListener;
public class FlatButton extends Canvas {
private String fText;
private int fMargin = 4;
private Cursor fHandCursor;
protected String fText;
protected int fMargin = 4;
protected Cursor fHandCursor;
public FlatButton(Composite parent, int flags) {
super(parent, flags);
@ -48,9 +49,7 @@ public class FlatButton extends Canvas {
addMouseListener(new MouseAdapter() {
@Override
public void mouseDown(MouseEvent e) {
if (isEnabled()) {
notifyListeners(SWT.Selection, null);
}
onSelection(e);
}
});
}
@ -94,7 +93,7 @@ public class FlatButton extends Canvas {
return new Point(e.x + fMargin*2, e.y + fMargin*2);
}
private void onPaint(PaintEvent event) {
protected void onPaint(PaintEvent event) {
GC gc = event.gc;
Rectangle ca = getClientArea();
@ -123,4 +122,10 @@ public class FlatButton extends Canvas {
borderColor.dispose();
shadowColor.dispose();
}
protected void onSelection(MouseEvent e) {
if (isEnabled()) {
notifyListeners(SWT.Selection, null);
}
}
}

View file

@ -0,0 +1,109 @@
/*******************************************************************************
* Copyright (c) 2014 Mentor Graphics 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:
* Dmitry Kozlov (Mentor Graphics) - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.dsf.gdb.internal.ui.tracepoints;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Composite;
public class FlatRadioButton extends FlatButton {
protected static final String STATE_OFF_LABEL = "OFF"; //$NON-NLS-1$
protected static final String STATE_ON_LABEL = "ON"; //$NON-NLS-1$
protected boolean selection = false;
public FlatRadioButton(Composite parent, int flags) {
super(parent, flags);
}
@Override
public Point computeSize(int wHint, int hHint) {
GC gc = new GC(this);
if (fText == null || fText.isEmpty()) {
Point e = gc.textExtent("A"); //$NON-NLS-1$
return new Point(0, e.y + fMargin*2);
}
Point e = gc.textExtent(fText);
Point pOn = gc.textExtent(STATE_ON_LABEL);
Point pOff = gc.textExtent(STATE_OFF_LABEL);
int h = Math.max(pOn.y, pOff.y);
return new Point(e.x + fMargin*4 + Math.max(pOn.x, pOff.x), Math.max(e.y, h) + fMargin*2 );
}
@Override
protected void onPaint(PaintEvent event) {
GC gc = event.gc;
Rectangle ca = getClientArea();
Color mainColor = gc.getDevice().getSystemColor(SWT.COLOR_LIST_SELECTION);
gc.setBackground(mainColor);
float[] mainHSB = mainColor.getRGB().getHSB();
float h = mainHSB[0];
float s = mainHSB[1];
float b = mainHSB[2];
Point e = gc.textExtent(fText);
Color borderColor = new Color(gc.getDevice(), new RGB(h, s, (float)(b*0.7)));
Color shadowColor = new Color(gc.getDevice(), new RGB(h, s, (float)(b*0.5)));
gc.setForeground(borderColor);
gc.drawRectangle(0, 0, ca.width-1, ca.height-1);
gc.setForeground(shadowColor);
gc.drawLine(0, ca.height-1, ca.width-1, ca.height-1);
gc.fillRectangle(e.x + fMargin*2 , 1, ca.width - 1 - e.x - fMargin*2 , ca.height-2);
gc.setForeground(gc.getDevice().getSystemColor(SWT.COLOR_LIST_FOREGROUND));
gc.drawText(fText, fMargin, fMargin, true);
gc.setForeground(gc.getDevice().getSystemColor(SWT.COLOR_LIST_SELECTION_TEXT));
Point pOn = gc.textExtent(STATE_ON_LABEL);
Point pOff = gc.textExtent(STATE_OFF_LABEL);
if (selection) {
int offset = pOn.x < pOff.x ? (pOff.x - pOn.x)/2 : 0;
gc.drawText(STATE_ON_LABEL , e.x + fMargin*3 + offset, fMargin);
} else {
int offset = pOn.x < pOff.x ? 0 : (pOn.x - pOff.x)/2 ;
gc.drawText(STATE_OFF_LABEL , e.x + fMargin*3 + offset, fMargin);
}
borderColor.dispose();
shadowColor.dispose();
}
@Override
protected void onSelection(MouseEvent e) {
if (isEnabled()) {
selection = ! selection;
notifyListeners(SWT.Selection, null);
redraw();
}
}
public void setSelection(boolean selection) {
this.selection = selection;
}
public boolean getSelection() {
return selection;
}
}

View file

@ -0,0 +1,518 @@
/*******************************************************************************
* Copyright (c) 2013 Mentor Graphics 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:
* Dmitry Kozlov (Mentor Graphics) - Trace control view enhancements (Bug 390827)
*******************************************************************************/
package org.eclipse.cdt.dsf.gdb.internal.ui.tracepoints;
import java.util.Hashtable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.RejectedExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
import org.eclipse.cdt.dsf.concurrent.DsfRunnable;
import org.eclipse.cdt.dsf.concurrent.IDsfStatusConstants;
import org.eclipse.cdt.dsf.concurrent.ImmediateDataRequestMonitor;
import org.eclipse.cdt.dsf.concurrent.ImmediateRequestMonitor;
import org.eclipse.cdt.dsf.concurrent.Query;
import org.eclipse.cdt.dsf.concurrent.RequestMonitor;
import org.eclipse.cdt.dsf.datamodel.DMContexts;
import org.eclipse.cdt.dsf.datamodel.IDMContext;
import org.eclipse.cdt.dsf.debug.service.IRunControl.ISuspendedDMEvent;
import org.eclipse.cdt.dsf.gdb.internal.ui.GdbUIPlugin;
import org.eclipse.cdt.dsf.gdb.internal.ui.tracepoints.TraceControlView.FailedTraceVariableCreationException;
import org.eclipse.cdt.dsf.gdb.service.GDBTraceControl_7_2.TraceRecordSelectedChangedEvent;
import org.eclipse.cdt.dsf.gdb.service.IGDBTraceControl;
import org.eclipse.cdt.dsf.gdb.service.IGDBTraceControl.ITraceRecordDMContext;
import org.eclipse.cdt.dsf.gdb.service.IGDBTraceControl.ITraceRecordSelectedChangedDMEvent;
import org.eclipse.cdt.dsf.gdb.service.IGDBTraceControl.ITraceStatusDMData;
import org.eclipse.cdt.dsf.gdb.service.IGDBTraceControl.ITraceStatusDMData2;
import org.eclipse.cdt.dsf.gdb.service.IGDBTraceControl.ITraceTargetDMContext;
import org.eclipse.cdt.dsf.gdb.service.IGDBTraceControl.ITraceVariableDMData;
import org.eclipse.cdt.dsf.gdb.service.IGDBTraceControl.ITracingStartedDMEvent;
import org.eclipse.cdt.dsf.gdb.service.IGDBTraceControl.ITracingStoppedDMEvent;
import org.eclipse.cdt.dsf.gdb.service.IGDBTraceControl.ITracingSupportedChangeDMEvent;
import org.eclipse.cdt.dsf.gdb.service.IGDBTraceControl2;
import org.eclipse.cdt.dsf.service.DsfServiceEventHandler;
import org.eclipse.cdt.dsf.service.DsfServicesTracker;
import org.eclipse.cdt.dsf.service.DsfSession;
import org.eclipse.cdt.dsf.ui.viewmodel.datamodel.IDMVMContext;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.debug.ui.DebugUITools;
import org.eclipse.debug.ui.contexts.DebugContextEvent;
import org.eclipse.debug.ui.contexts.IDebugContextListener;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.IWorkbenchWindow;
/**
* This class is a bridge between the TraceControl view and the TraceControl service.
* It performs the necessary requests to the service on behalf of the view.
* Those request must be done on the DSF Executor thread.
* Note that this class will have a single instance which will deal with
* all DSF debug sessions at the same time.
*/
public class TraceControlModel {
private String fDebugSessionId;
private DsfServicesTracker fServicesTracker;
private volatile IGDBTraceControl fGDBTraceControl;
private volatile ITraceTargetDMContext fTargetContext;
private TraceControlView fTraceControlView;
private IDebugContextListener fDebugContextListener = new IDebugContextListener() {
@Override
public void debugContextChanged(DebugContextEvent event) {
if ((event.getFlags() & DebugContextEvent.ACTIVATED) != 0) {
updateDebugContext();
}
}
};
TraceControlModel(TraceControlView view) {
fTraceControlView = view;
IWorkbenchWindow window = fTraceControlView.getSite().getWorkbenchWindow();
DebugUITools.getDebugContextManager().getContextService(window).addDebugContextListener(fDebugContextListener);
updateDebugContext();
}
protected void updateContent() {
if (getSession() == null) {
notifyUI(TracepointsMessages.TraceControlView_trace_status_no_debug_session);
return;
}
if (fTargetContext == null || fGDBTraceControl == null) {
notifyUI(TracepointsMessages.TraceControlView_trace_status_not_supported);
return;
}
getSession().getExecutor().execute(
new DsfRunnable() {
@Override
public void run() {
if (fTargetContext != null && fGDBTraceControl != null) {
fGDBTraceControl.getTraceStatus(
fTargetContext, new DataRequestMonitor<ITraceStatusDMData>(getSession().getExecutor(), null) {
@Override
protected void handleCompleted() {
if (isSuccess() && getData() != null) {
notifyUI((ITraceStatusDMData2)getData());
} else {
notifyUI((ITraceStatusDMData2)null);
}
}
});
} else {
notifyUI((ITraceStatusDMData2)null);
}
}
});
}
public void init() {
if (fDebugSessionId != null) {
debugSessionChanged();
} else {
updateDebugContext();
}
}
public void dispose() {
IWorkbenchWindow window = fTraceControlView.getSite().getWorkbenchWindow();
DebugUITools.getDebugContextManager().getContextService(window).removeDebugContextListener(fDebugContextListener);
setDebugContext(null);
}
protected void updateDebugContext() {
IAdaptable debugContext = DebugUITools.getDebugContext();
if (debugContext instanceof IDMVMContext) {
setDebugContext((IDMVMContext)debugContext);
} else {
setDebugContext(null);
}
}
protected void setDebugContext(IDMVMContext vmContext) {
if (vmContext != null) {
IDMContext dmContext = vmContext.getDMContext();
String sessionId = dmContext.getSessionId();
fTargetContext = DMContexts.getAncestorOfType(dmContext, ITraceTargetDMContext.class);
if (!sessionId.equals(fDebugSessionId)) {
if (getSession() != null) {
try {
final DsfSession session = getSession();
session.getExecutor().execute(new DsfRunnable() {
@Override
public void run() {
session.removeServiceEventListener(TraceControlModel.this);
}
});
} catch (RejectedExecutionException e) {
// Session is shut down.
}
}
fDebugSessionId = sessionId;
if (fServicesTracker != null) {
fServicesTracker.dispose();
}
fServicesTracker = new DsfServicesTracker(GdbUIPlugin.getBundleContext(), sessionId);
getGDBTraceControl();
debugSessionChanged();
}
} else if (fDebugSessionId != null) {
if (getSession() != null) {
try {
final DsfSession session = getSession();
session.getExecutor().execute(new DsfRunnable() {
@Override
public void run() {
session.removeServiceEventListener(TraceControlModel.this);
}
});
} catch (RejectedExecutionException e) {
// Session is shut down.
}
}
fDebugSessionId = null;
fTargetContext = null;
if (fServicesTracker != null) {
fServicesTracker.dispose();
fServicesTracker = null;
}
debugSessionChanged();
}
}
private void debugSessionChanged() {
if (getSession() != null) {
try {
final DsfSession session = getSession();
session.getExecutor().execute(new DsfRunnable() {
@Override
public void run() {
session.addServiceEventListener(TraceControlModel.this, null);
}
});
} catch (RejectedExecutionException e) {
// Session is shut down.
}
}
updateContent();
}
public void exitVisualizationMode() {
if (getSession() == null) {
return;
}
getSession().getExecutor().execute(
new DsfRunnable() {
@Override
public void run() {
if (fTargetContext != null && fGDBTraceControl != null) {
if (fGDBTraceControl instanceof IGDBTraceControl2) {
((IGDBTraceControl2)fGDBTraceControl).stopTraceVisualization(fTargetContext, new ImmediateRequestMonitor());
} else {
// Legacy way of stopping visualization of trace data
ITraceRecordDMContext emptyDmc = fGDBTraceControl.createTraceRecordContext(fTargetContext, "-1"); //$NON-NLS-1$
fGDBTraceControl.selectTraceRecord(emptyDmc, new ImmediateRequestMonitor());
}
}
}
});
}
/**
* Get the list of trace variables from the backend.
*
* @return null when the list cannot be obtained.
*/
public ITraceVariableDMData[] getTraceVarList() {
if (getSession() == null) {
return null;
}
Query<ITraceVariableDMData[]> query = new Query<ITraceVariableDMData[]>() {
@Override
protected void execute(final DataRequestMonitor<ITraceVariableDMData[]> rm) {
if (fTargetContext != null && fGDBTraceControl != null) {
fGDBTraceControl.getTraceVariables(fTargetContext,
new DataRequestMonitor<ITraceVariableDMData[]>(getSession().getExecutor(), rm) {
@Override
protected void handleCompleted() {
if (isSuccess()) {
rm.setData(getData());
} else {
rm.setData(null);
}
rm.done();
};
});
} else {
rm.setData(null);
rm.done();
}
}
};
try {
getSession().getExecutor().execute(query);
return query.get(1, TimeUnit.SECONDS);
} catch (InterruptedException exc) {
} catch (ExecutionException exc) {
} catch (TimeoutException e) {
}
return null;
}
/**
* Create a new trace variable in the backend.
*
* @throws FailedTraceVariableCreationException when the creation fails. The exception
* will contain the error message to display to the user.
*/
public void createVariable(final String name, final String value) throws FailedTraceVariableCreationException {
if (getSession() == null) {
throw new TraceControlView.FailedTraceVariableCreationException(TracepointsMessages.TraceControlView_create_variable_error);
}
Query<String> query = new Query<String>() {
@Override
protected void execute(final DataRequestMonitor<String> rm) {
if (fTargetContext != null && fGDBTraceControl != null) {
fGDBTraceControl.createTraceVariable(fTargetContext, name, value,
new RequestMonitor(getSession().getExecutor(), rm) {
@Override
protected void handleFailure() {
String message = TracepointsMessages.TraceControlView_create_variable_error;
Throwable t = getStatus().getException();
if (t != null) {
message = t.getMessage();
}
FailedTraceVariableCreationException e =
new FailedTraceVariableCreationException(message);
rm.setStatus(new Status(IStatus.ERROR, GdbUIPlugin.PLUGIN_ID, IDsfStatusConstants.INVALID_STATE, "Backend error", e)); //$NON-NLS-1$
rm.done();
};
});
} else {
FailedTraceVariableCreationException e =
new FailedTraceVariableCreationException(TracepointsMessages.TraceControlView_trace_variable_tracing_unavailable);
rm.setStatus(new Status(IStatus.ERROR, GdbUIPlugin.PLUGIN_ID, IDsfStatusConstants.INVALID_STATE, "Tracing unavailable", e)); //$NON-NLS-1$
rm.done();
}
}
};
try {
getSession().getExecutor().execute(query);
query.get();
} catch (InterruptedException e) {
// Session terminated
} catch (ExecutionException e) {
Throwable t = e.getCause();
if (t instanceof CoreException) {
t = ((CoreException)t).getStatus().getException();
if (t instanceof FailedTraceVariableCreationException) {
throw (FailedTraceVariableCreationException)t;
}
}
throw new FailedTraceVariableCreationException(TracepointsMessages.TraceControlView_create_variable_error);
}
}
public void setCurrentTraceRecord(final String traceRecordId) {
if (getSession() == null) {
return;
}
getSession().getExecutor().execute(
new DsfRunnable() {
@Override
public void run() {
if (fTargetContext != null && fGDBTraceControl != null) {
fGDBTraceControl.getCurrentTraceRecordContext(
fTargetContext,
new ImmediateDataRequestMonitor<ITraceRecordDMContext>() {
@Override
protected void handleSuccess() {
final ITraceRecordDMContext previousDmc = getData();
ITraceRecordDMContext nextRecord = fGDBTraceControl.createTraceRecordContext(fTargetContext, traceRecordId);
// Must send the event right away to tell the services we are starting visualization
// If we don't, the services won't behave accordingly soon enough
// Bug 347514
getSession().dispatchEvent(new TraceRecordSelectedChangedEvent(nextRecord), new Hashtable<String, String>());
fGDBTraceControl.selectTraceRecord(nextRecord, new ImmediateRequestMonitor() {
@Override
protected void handleError() {
// If we weren't able to select the next record, we must notify that we are still on the previous one
// since we have already sent a TraceRecordSelectedChangedEvent early, but it didn't happen.
getSession().dispatchEvent(new TraceRecordSelectedChangedEvent(previousDmc), new Hashtable<String, String>());
}
});
};
});
}
}
});
}
public void setCircularBuffer(final boolean useCircularBuffer) {
if (getSession() == null) {
return;
}
getSession().getExecutor().execute(
new DsfRunnable() {
@Override
public void run() {
if (fTargetContext != null && fGDBTraceControl != null && fGDBTraceControl instanceof IGDBTraceControl2) {
((IGDBTraceControl2)fGDBTraceControl).setCircularTraceBuffer(fTargetContext, useCircularBuffer, new ImmediateRequestMonitor());
}
}
});
}
public void setDisconnectedTracing(final boolean disconnected) {
if (getSession() == null) {
return;
}
getSession().getExecutor().execute(
new DsfRunnable() {
@Override
public void run() {
if (fTargetContext != null && fGDBTraceControl != null && fGDBTraceControl instanceof IGDBTraceControl2) {
((IGDBTraceControl2)fGDBTraceControl).setDisconnectedTracing(fTargetContext, disconnected, new ImmediateRequestMonitor());
}
}
});
}
public void setTraceNotes(final String notes) {
if (getSession() == null) {
return;
}
getSession().getExecutor().execute(
new DsfRunnable() {
@Override
public void run() {
if (fTargetContext != null && fGDBTraceControl != null && fGDBTraceControl instanceof IGDBTraceControl2) {
((IGDBTraceControl2)fGDBTraceControl).setTraceNotes(fTargetContext, notes, new ImmediateRequestMonitor());
}
}
});
}
private void getGDBTraceControl() {
if (getSession() == null) {
fGDBTraceControl = null;
return;
}
getSession().getExecutor().execute(
new DsfRunnable() {
@Override
public void run() {
fGDBTraceControl = getService(IGDBTraceControl.class);
}
});
}
private DsfSession getSession() {
return DsfSession.getSession(fDebugSessionId);
}
private <V> V getService(Class<V> serviceClass) {
if (fServicesTracker != null) {
return fServicesTracker.getService(serviceClass);
}
return null;
}
private void notifyUI(final ITraceStatusDMData2 data) {
final TraceControlView v = fTraceControlView;
if (v != null) {
Display.getDefault().asyncExec(new Runnable() {
@Override
public void run() {
if (v != null) {
v.fLastRefreshTime = System.currentTimeMillis();
v.updateUI(data);
}
}
});
}
}
private void notifyUI(final String message) {
final TraceControlView v = fTraceControlView;
if (v != null) {
Display.getDefault().asyncExec(new Runnable() {
@Override
public void run() {
if (v != null) {
v.updateUI(message);
}
}
});
}
}
/*
* When tracing starts, we know the status has changed
*/
@DsfServiceEventHandler
public void handleEvent(ITracingStartedDMEvent event) {
updateContent();
}
/*
* When tracing stops, we know the status has changed
*/
@DsfServiceEventHandler
public void handleEvent(ITracingStoppedDMEvent event) {
updateContent();
}
@DsfServiceEventHandler
public void handleEvent(ITraceRecordSelectedChangedDMEvent event) {
updateContent();
}
/*
* Since something suspended, might as well refresh our status
* to show the latest.
*/
@DsfServiceEventHandler
public void handleEvent(ISuspendedDMEvent event) {
updateContent();
}
/*
* Tracing support has changed, update view
*/
@DsfServiceEventHandler
public void handleEvent(ITracingSupportedChangeDMEvent event) {
updateContent();
}
}

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2010 Ericsson.
* Copyright (c) 2010, 2013 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
@ -7,6 +7,7 @@
*
* Contributors:
* Ericsson - Initial API and implementation
* Dmitry Kozlov (Mentor Graphics) - Trace control view enhancements (Bug 390827)
*******************************************************************************/
package org.eclipse.cdt.dsf.gdb.internal.ui.tracepoints;
@ -253,7 +254,7 @@ public final class TraceVarDetailsDialog extends Dialog {
}
protected void handleRefresh() {
ITraceVariableDMData[] vars = fView.getTraceVarList();
ITraceVariableDMData[] vars = fView.fTraceControlModel.getTraceVarList();
if (vars == null) {
setWarningVisible(TracepointsMessages.TraceControlView_refresh_variable_error);
createButton.setEnabled(false);
@ -312,7 +313,7 @@ public final class TraceVarDetailsDialog extends Dialog {
}
try {
fView.createVariable(name, value);
fView.fTraceControlModel.createVariable(name, value);
resetInputFields();
nameInput.setFocus();
handleRefresh();

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2010 Wind River Systems and others.
* Copyright (c) 2010, 2013 Wind River Systems 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
@ -7,6 +7,7 @@
*
* Contributors:
* Wind River Systems - initial API and implementation
* Dmitry Kozlov (Mentor Graphics) - Trace control view enhancements (Bug 390827)
*******************************************************************************/
package org.eclipse.cdt.dsf.gdb.internal.ui.tracepoints;
@ -33,12 +34,16 @@ public class TracepointImageRegistry extends AbstractImageRegistry {
private static final String ORG_ECLIPSE_UI_PLUGIN_ID = "org.eclipse.ui"; //$NON-NLS-1$
private static final String ORG_ECLIPSE_CDT_DSF_GDB_UI_PLUGIN_ID = "org.eclipse.cdt.dsf.gdb.ui"; //$NON-NLS-1$
public static final String ICON_Refresh_enabled = add(ORG_ECLIPSE_UI_PLUGIN_ID, new String[] {"full/elcl16"}, "refresh_nav.gif"); //$NON-NLS-1$ //$NON-NLS-2$
public static final String ICON_Refresh_disabled = add(ORG_ECLIPSE_UI_PLUGIN_ID, new String[] {"full/dlcl16"}, "refresh_nav.gif"); //$NON-NLS-1$ //$NON-NLS-2$
public static final String ICON_Trace_Variables = add(ORG_ECLIPSE_CDT_DSF_GDB_UI_PLUGIN_ID, new String[] {"full/obj16"}, "tracevariables.gif"); //$NON-NLS-1$ //$NON-NLS-2$
public static final String ICON_Exit_Visualization = add(ORG_ECLIPSE_CDT_DSF_GDB_UI_PLUGIN_ID, new String[] {"full/obj16"}, "stop_visual_trace.gif"); //$NON-NLS-1$ //$NON-NLS-2$
public static final String ICON_Refresh_enabled = add(ORG_ECLIPSE_UI_PLUGIN_ID, new String[] {"full/elcl16"}, "refresh_nav.gif"); //$NON-NLS-1$ //$NON-NLS-2$
public static final String ICON_Refresh_disabled = add(ORG_ECLIPSE_UI_PLUGIN_ID, new String[] {"full/dlcl16"}, "refresh_nav.gif"); //$NON-NLS-1$ //$NON-NLS-2$
public static final String ICON_Refresh_Auto = add(ORG_ECLIPSE_CDT_DSF_GDB_UI_PLUGIN_ID, new String[] {"full/obj16"}, "refresh_auto.gif"); //$NON-NLS-1$ //$NON-NLS-2$
public static final String ICON_Disconnected_Tracing = add(ORG_ECLIPSE_CDT_DSF_GDB_UI_PLUGIN_ID, new String[] {"full/obj16"}, "disconnected_tracing.png"); //$NON-NLS-1$ //$NON-NLS-2$
public static final String ICON_Circular_Buffer = add(ORG_ECLIPSE_CDT_DSF_GDB_UI_PLUGIN_ID, new String[] {"full/obj16"}, "circular_buffer.png"); //$NON-NLS-1$ //$NON-NLS-2$
public static final String ICON_Trace_Variables = add(ORG_ECLIPSE_CDT_DSF_GDB_UI_PLUGIN_ID, new String[] {"full/obj16"}, "tracevariables.gif"); //$NON-NLS-1$ //$NON-NLS-2$
public static final String ICON_Exit_Visualization = add(ORG_ECLIPSE_CDT_DSF_GDB_UI_PLUGIN_ID, new String[] {"full/obj16"}, "stop_visual_trace.gif"); //$NON-NLS-1$ //$NON-NLS-2$
public static final String ICON_Edit_enabled = add(ORG_ECLIPSE_CDT_DSF_GDB_UI_PLUGIN_ID, new String[] {"full/obj16"}, "write_obj.gif"); //$NON-NLS-1$ //$NON-NLS-2$
private static TracepointImageRegistry INSTANCE= new TracepointImageRegistry(GdbUIPlugin.getDefault());
private static TracepointImageRegistry INSTANCE = new TracepointImageRegistry(GdbUIPlugin.getDefault());
TracepointImageRegistry(Plugin plugin) {
super(plugin);

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2010 Wind River Systems and others.
* Copyright (c) 2010, 2013 Wind River Systems 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
@ -7,6 +7,7 @@
*
* Contributors:
* Wind River Systems - initial API and implementation
* Dmitry Kozlov (Mentor Graphics) - trace control view enhancements (Bug 390827)
*******************************************************************************/
package org.eclipse.cdt.dsf.gdb.internal.ui.tracepoints;
@ -20,11 +21,23 @@ public final class TracepointsMessages extends NLS {
private TracepointsMessages() {
// Do not instantiate
}
public static String TraceControlView_buffer_label;
public static String TraceControlView_buffer_circular_button_label;
public static String TraceControlView_buffer_circular_on_tooltip;
public static String TraceControlView_buffer_circular_off_tooltip;
public static String TraceControlView_buffer_frames_collected;
public static String TraceControlView_trace_status_offline;
public static String TraceControlView_tracing_stopped_user_request;
public static String TraceControlView_tracing_stopped_passcount;
public static String TraceControlView_tracing_stopped_tracepoint_number;
public static String TraceControlView_tracing_stopped_buffer_full;
public static String TraceControlView_tracing_stopped_disconnection;
public static String TraceControlView_tracing_stopped_error;
public static String TraceControlView_tracing_stopped_unknown;
public static String TraceControlView_action_Refresh_label;
public static String TraceControlView_trace_view_content_updated_label;
public static String TraceControlView_auto_refresh_action_label;
public static String TraceControlView_action_trace_variable_details;
public static String TraceControlView_trace_variable_invalid_value;
public static String TraceControlView_action_Disconnected_tracing_label;
public static String TraceControlView_trace_variable_tracing_unavailable;
public static String TraceControlView_trace_variable_details_dialog_title;
public static String TraceControlView_trace_variable_details_column_name;
@ -38,6 +51,44 @@ public final class TracepointsMessages extends NLS {
public static String TraceControlView_create_variable_empty_name_error;
public static String TraceControlView_action_exit_visualization_mode;
public static String TraceControlView_refresh_variable_error;
public static String TraceControlView_trace_status_not_supported;
public static String TraceControlView_trace_status_inactive;
public static String TraceControlView_trace_status_no_debug_session;
public static String TraceControlView_trace_status_not_started;
public static String TraceControlView_trace_status_in_progress;
public static String TraceControlView_trace_status_visualization;
public static String TraceControlView_trace_status_stopped;
public static String TraceControlView_frame_label;
public static String TraceControlView_frame_looking;
public static String TraceControlView_frame_dragging;
public static String TraceControlView_frame_not_looking;
public static String TraceControlView_trace_notes_edit_tooltip;
public static String TraceControlView_trace_notes_save_tooltip;
public static String TraceControlView_trace_notes_not_set;
public static String TraceControlView_trace_notes_label;
public static String TraceControlView_trace_status_secondary_stopped;
public static String TraceControlView_trace_status_secondary_running;
public static String TraceControlView_trace_status_secondary_user;
public static String TraceControlView_trace_status_secondary_refresh_time;
public static String TraceControlView_trace_status_secondary_offline;
public static String TraceControlView_action_start;
public static String TraceControlView_action_stop;
public static String TraceControlView_action_restart;
public static String TraceControlView_action_finish_visualization;
public static String TraceControlView_today;
public static String TraceControlView_yesterday;
public static String TraceControlView_date_days;
public static String TraceControlView_date_hours;
public static String TraceControlView_date_minutes;
public static String TraceControlView_date_seconds;
public static String TraceControlView_date_zero;
public static String TraceControlView_date_short_days;
public static String TraceControlView_date_short_hours;
public static String TraceControlView_date_short_minutes;
public static String TraceControlView_date_short_seconds;
public static String TraceControlView_date_short_zero;
// Not used
public static String TraceControlView_tracing_stopped_at;
static {
NLS.initializeMessages(TracepointsMessages.class.getName(), TracepointsMessages.class);

View file

@ -1,5 +1,5 @@
##########################################################################
# Copyright (c) 2010 Ericsson and others.
# Copyright (c) 2010, 2013 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
@ -7,12 +7,13 @@
#
# Contributors:
# Ericsson - initial API and implementation
# Dmitry Kozlov (Mentor Graphics) - trace control view enhancements (Bug 390827)
##########################################################################
TraceControlView_action_Refresh_label=Refresh
TraceControlView_trace_view_content_updated_label=Last updated at:
TraceControlView_auto_refresh_action_label=Refresh view automatically
TraceControlView_action_Disconnected_tracing_label=Continue tracing after GDB has disconnected
TraceControlView_action_trace_variable_details=Manage Trace Variables
TraceControlView_trace_variable_invalid_value=Initial value must be an integer
TraceControlView_trace_variable_tracing_unavailable=Tracing unavailable
TraceControlView_trace_variable_details_dialog_title=Trace Variable Details
TraceControlView_trace_variable_details_column_name=Name
@ -26,3 +27,68 @@ TraceControlView_create_variable_error=Error creating trace variable
TraceControlView_create_variable_empty_name_error=Cannot create variable with empty name
TraceControlView_action_exit_visualization_mode=Exit Visualization Mode
TraceControlView_refresh_variable_error=Unable to retrieve trace variables
TraceControlView_trace_status_not_supported=Tracing is not supported
TraceControlView_trace_status_inactive=Tracing is not active
TraceControlView_trace_status_offline=Examining trace data from a file
TraceControlView_trace_status_not_started=Tracing not started
TraceControlView_trace_status_in_progress=Tracing is running
TraceControlView_trace_status_visualization=Examining trace
TraceControlView_trace_status_stopped=Trace data available
TraceControlView_trace_status_no_debug_session=Debug session is not selected or started
TraceControlView_trace_status_secondary_stopped={0}trace{1}, stopped {2} on {3}
# {1} is the user name if set provided by binding TraceControlView_trace_status_secondary_user
# {2} is the last refresh time if auto-refresh is not enabled, provided by binding TraceControlView_trace_status_secondary_refresh_time
TraceControlView_trace_status_secondary_running=started {0}{1}{2}
# {1} is the user name if set provided by binding TraceControlView_trace_status_secondary_user
TraceControlView_trace_status_secondary_offline=Tracing was started {0}{1}, stopped {2} on {3}
TraceControlView_trace_status_secondary_user=\ by {0}
# Note: TraceControlView.updateUIRefreshStatusOnly relies on the exact content of this field,
# mind when change it
TraceControlView_trace_status_secondary_refresh_time=, last refreshed {0}ago
TraceControlView_action_start=Start
TraceControlView_action_stop=Stop
TraceControlView_action_finish_visualization=End
TraceControlView_action_restart=Restart
TraceControlView_date_days=\ days\
TraceControlView_date_hours=\ hours\
TraceControlView_date_minutes=\ minutes\
TraceControlView_date_seconds=\ seconds\
TraceControlView_date_zero=0 seconds\
TraceControlView_date_short_days=d\
TraceControlView_date_short_hours=h\
TraceControlView_date_short_minutes=m\
TraceControlView_date_short_seconds=s\
TraceControlView_date_short_zero=0s\
TraceControlView_tracing_stopped_at={0},
TraceControlView_tracing_stopped_user_request=user request
TraceControlView_tracing_stopped_passcount=passcount
TraceControlView_tracing_stopped_tracepoint_number=passcount of tracepoint {0}
TraceControlView_tracing_stopped_buffer_full=buffer full
TraceControlView_tracing_stopped_disconnection=disconnection
TraceControlView_tracing_stopped_error=error
TraceControlView_tracing_stopped_unknown=unknown reason
TraceControlView_buffer_label=Buffer
TraceControlView_buffer_circular_button_label=Circular
TraceControlView_buffer_circular_on_tooltip= Circular buffer is on
TraceControlView_buffer_circular_off_tooltip= Circular buffer is off
TraceControlView_buffer_frames_collected={0} frames, {1}Kb
TraceControlView_trace_notes_label=Notes
TraceControlView_trace_notes_not_set=No trace notes set
TraceControlView_trace_notes_edit_tooltip=Edit notes
TraceControlView_trace_notes_save_tooltip=Save notes
TraceControlView_frame_label=Current selected trace frame:
TraceControlView_frame_not_looking =n/a
TraceControlView_frame_looking={0}, tracepoint {1}
TraceControlView_frame_dragging={0}
TraceControlView_today={0} today
TraceControlView_yesterday={0} yesterday

View file

@ -3,7 +3,7 @@ Bundle-ManifestVersion: 2
Bundle-Name: %pluginName
Bundle-Vendor: %providerName
Bundle-SymbolicName: org.eclipse.cdt.dsf.gdb;singleton:=true
Bundle-Version: 4.3.0.qualifier
Bundle-Version: 4.4.0.qualifier
Bundle-Activator: org.eclipse.cdt.dsf.gdb.internal.GdbPlugin
Bundle-Localization: plugin
Require-Bundle: org.eclipse.core.runtime,

View file

@ -11,7 +11,7 @@
<relativePath>../../pom.xml</relativePath>
</parent>
<version>4.3.0-SNAPSHOT</version>
<version>4.4.0-SNAPSHOT</version>
<artifactId>org.eclipse.cdt.dsf.gdb</artifactId>
<packaging>eclipse-plugin</packaging>
</project>

View file

@ -1,12 +1,13 @@
/*******************************************************************************
* Copyright (c) 2010, 2011 Ericsson and others.
* Copyright (c) 2010, 2013 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 API and implementation
* Ericsson - Initial API and implementation
* Dmitry Kozlov (Mentor Graphics) - Add support for IGDBTraceControl2 (Bug 390827)
*******************************************************************************/
package org.eclipse.cdt.dsf.gdb.service;
@ -14,6 +15,7 @@ import java.util.Hashtable;
import java.util.concurrent.TimeUnit;
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
import org.eclipse.cdt.dsf.concurrent.ImmediateDataRequestMonitor;
import org.eclipse.cdt.dsf.concurrent.ImmediateRequestMonitor;
import org.eclipse.cdt.dsf.concurrent.Immutable;
import org.eclipse.cdt.dsf.concurrent.RequestMonitor;
@ -55,7 +57,7 @@ import org.osgi.framework.BundleContext;
*
* @since 3.0
*/
public class GDBTraceControl_7_2 extends AbstractDsfService implements IGDBTraceControl, ICachingService {
public class GDBTraceControl_7_2 extends AbstractDsfService implements IGDBTraceControl2, ICachingService {
@Immutable
protected static final class MITraceRecordDMContext extends AbstractDMContext implements ITraceRecordDMContext {
@ -213,136 +215,143 @@ public class GDBTraceControl_7_2 extends AbstractDsfService implements IGDBTrace
}
}
private class TraceStatusDMData implements ITraceStatusDMData {
private int fFreeBufferSize;
private int fTotalBufferSize;
private int fNumberOfCollectedFrames;
private boolean fTracingActive;
private boolean fTracingSupported;
private STOP_REASON_ENUM fStopReason;
private Integer fStoppingTracepoint;
/**
* Create a status when tracing is supported
*/
public TraceStatusDMData(boolean active, int free, int total, int frames,
STOP_REASON_ENUM reason, Integer tracepoint) {
fFreeBufferSize = free;
fTotalBufferSize = total;
fNumberOfCollectedFrames = frames;
fTracingActive = active;
fTracingSupported = true;
fStopReason = reason;
fStoppingTracepoint = tracepoint;
}
/**
* Status without a Stop reason
*/
public TraceStatusDMData(boolean active, int free, int total, int frames) {
this(active, free, total, frames, null, null);
private class TraceStatusDMData implements ITraceStatusDMData2 {
private MITraceStatusInfo fInfo;
public TraceStatusDMData(MITraceStatusInfo info) {
fInfo = info;
}
/**
* Create a status when tracing is not supported
*/
public TraceStatusDMData() {
this(false, 0, 0, 0);
fTracingSupported = false;
this(null);
}
@Override
public int getFreeBufferSize() {
return fFreeBufferSize;
if (fInfo == null) return 0;
return fInfo.getFreeBufferSize();
}
@Override
public int getNumberOfCreatedFrames() {
if (fInfo == null) return 0;
return fInfo.getNumberOfCreatedFrames();
}
@Override
public int getNumberOfCollectedFrame() {
return fNumberOfCollectedFrames;
if (fInfo == null) return 0;
return fInfo.getNumberOfCollectedFrame();
}
@Override
public int getTotalBufferSize() {
return fTotalBufferSize;
if (fInfo == null) return 0;
return fInfo.getTotalBufferSize();
}
@Override
public boolean isTracingActive() {
return fTracingActive;
if (fInfo == null) return false;
return fInfo.isTracingActive();
}
@Override
public boolean isTracingSupported() {
return fTracingSupported;
return fInfo != null;
}
@Override
public boolean isCircularBuffer() {
if (fInfo == null) return false;
return fInfo.isCircularBuffer();
}
@Override
public boolean isTracingFromFile() {
if (fInfo == null) return false;
return fInfo.isTracingFromFile();
}
@Override
public boolean isDisconnectedTracingEnabled() {
if (fInfo == null) return false;
return fInfo.isDisconnectedTracingEnabled();
}
@Override
public STOP_REASON_ENUM getStopReason() {
return fStopReason;
if (fInfo == null) return null;
return fInfo.getStopReason();
}
@Override
public Integer getStoppingTracepoint() {
if (fStopReason == null) {
if (fInfo.getStopReason() == null) {
return null;
}
return fStoppingTracepoint;
return fInfo.getStopTracepoint();
}
@SuppressWarnings("nls")
@Override
public String toString() {
String str = "\n";
if (!fTracingSupported) {
return "\nTracing is not supported\n";
public String getUserName() {
if (fInfo == null) return ""; //$NON-NLS-1$
return fInfo.getUserName() == null ? "" : fInfo.getUserName(); //$NON-NLS-1$
}
@Override
public String getNotes() {
if (fInfo == null) return ""; //$NON-NLS-1$
return fInfo.getNotes() == null ? "" : fInfo.getNotes(); //$NON-NLS-1$
}
@Override
public String getStartTime() {
if (fInfo == null) return ""; //$NON-NLS-1$
return fInfo.getStartTime() == null ? "" : fInfo.getStartTime(); //$NON-NLS-1$
}
@Override
public String getStopTime() {
if (fInfo == null) return ""; //$NON-NLS-1$
return fInfo.getStopTime() == null ? "" : fInfo.getStopTime(); //$NON-NLS-1$
}
@Override
public String getStopErrorDescription() {
if (getStopReason() != STOP_REASON_ENUM.ERROR) {
return null;
}
if (fBackend.getSessionType() == SessionType.CORE) {
str += "Off-line trace visualization\n";
} else {
str += "Tracing with live execution\n";
}
return fInfo.getStopErrorDescription();
}
@Override
public String getTraceFile() {
if (!isTracingFromFile()) {
return null;
}
return fInfo.getTraceFile();
}
@Override
public String getCurrentTraceFrameId() {
// Not currently provided by -trace-status
if (fCurrentRecordDmc instanceof MITraceRecordDMContext) {
str += "Looking at trace frame " +
((MITraceRecordDMContext)fCurrentRecordDmc).getRecordId() +
", tracepoint " + fTracepointIndexForTraceRecord + "\n\n";
} else {
str += "Not currently looking at any trace frame\n\n";
return ((MITraceRecordDMContext)fCurrentRecordDmc).getRecordId();
}
str += "Tracing is currently" + (!fTracingActive ? " not":"") + " active\n";
str += "Buffer contains " + fNumberOfCollectedFrames + " trace frame" +
(fNumberOfCollectedFrames>1?"s":"") + "\n";//" (out of ? created in total)\n";
str += "Currently using " + (fTotalBufferSize - fFreeBufferSize) +
" bytes out of " + fTotalBufferSize + "\n";
if (fStopReason != null) {
assert !fTracingActive;
str += "Tracing stopped because of";
if (fStopReason == STOP_REASON_ENUM.REQUEST) {
str += " user request";
} else if (fStopReason == STOP_REASON_ENUM.PASSCOUNT) {
str += " passcount";
if (fStoppingTracepoint != null) {
str += " of tracepoint number " + fStoppingTracepoint;
}
} else if (fStopReason == STOP_REASON_ENUM.OVERFLOW) {
str += " buffer full";
} else if (fStopReason == STOP_REASON_ENUM.DISCONNECTION) {
str += " disconnection";
} else if (fStopReason == STOP_REASON_ENUM.ERROR) {
str += " error";
} else {
str += " unknow reason";
}
str += "\n";
return null;
}
@Override
public Integer getTracepointNumberForCurrentTraceFrame() {
// Not currently provided by -trace-status
if (getCurrentTraceFrameId() != null) {
return fTracepointIndexForTraceRecord;
}
return str;
return null;
}
}
@ -433,7 +442,8 @@ public class GDBTraceControl_7_2 extends AbstractDsfService implements IGDBTrace
*/
private void doInitialize(RequestMonitor requestMonitor) {
// Register this service.
register(new String[] {IGDBTraceControl.class.getName()},
register(new String[] {IGDBTraceControl.class.getName(),
IGDBTraceControl2.class.getName()},
new Hashtable<String, String>());
@ -468,6 +478,16 @@ public class GDBTraceControl_7_2 extends AbstractDsfService implements IGDBTrace
return GdbPlugin.getBundleContext();
}
/** @since 4.4 */
protected boolean isTracingCurrentlySupported() {
return fIsTracingCurrentlySupported;
}
/** @since 4.4 */
protected CommandCache getTraceStatusCache() {
return fTraceStatusCache;
}
@Override
public void canStartTracing(ITraceTargetDMContext context, final DataRequestMonitor<Boolean> rm) {
if (context == null) {
@ -521,6 +541,8 @@ public class GDBTraceControl_7_2 extends AbstractDsfService implements IGDBTrace
new DataRequestMonitor<MIInfo>(getExecutor(), rm) {
@Override
protected void handleSuccess() {
fTraceStatusCache.reset(context);
fIsTracingActive = true;
getSession().dispatchEvent(new TracingStartedEvent(context), getProperties());
rm.done();
@ -594,7 +616,9 @@ public class GDBTraceControl_7_2 extends AbstractDsfService implements IGDBTrace
new DataRequestMonitor<MITraceStopInfo>(getExecutor(), rm) {
@Override
protected void handleSuccess() {
MITraceStopInfo info = getData();
fTraceStatusCache.reset(context);
MITraceStopInfo info = getData();
// Update the tracing state in case it was stopped by the backend
if (fIsTracingActive != info.isTracingActive()) {
@ -721,6 +745,8 @@ public class GDBTraceControl_7_2 extends AbstractDsfService implements IGDBTrace
new DataRequestMonitor<MIInfo>(getExecutor(), rm) {
@Override
protected void handleSuccess() {
fTraceStatusCache.reset(context);
fIsTracingCurrentlySupported = true;
// Workaround for GDB pre-release where we don't get the details
// of the frame when we load a trace file.
@ -760,10 +786,6 @@ public class GDBTraceControl_7_2 extends AbstractDsfService implements IGDBTrace
// because -trace-status can change very fast as it reports
// the number of frames collected. Having a small interval of
// stale data is currently not a big deal, and not user-visible.
// We just have to be careful in the future that command enablement
// should not be affected by this cache. For example, if a command
// checks if it should be enabled by using this call, and misses
// the latest state due to the cache.
// Bug 353034
getExecutor().schedule(new Runnable() {
@Override public void run() { fTraceStatusCache.reset(context); }
@ -800,20 +822,7 @@ public class GDBTraceControl_7_2 extends AbstractDsfService implements IGDBTrace
fTraceRecordsStored = info.getNumberOfCollectedFrame();
STOP_REASON_ENUM stopReason = info.getStopReason();
if (stopReason == null) {
rm.setData(new TraceStatusDMData(info.isTracingActive(),
info.getFreeBufferSize(),
info.getTotalBufferSize(),
info.getNumberOfCollectedFrame()));
} else {
rm.setData(new TraceStatusDMData(info.isTracingActive(),
info.getFreeBufferSize(),
info.getTotalBufferSize(),
info.getNumberOfCollectedFrame(),
stopReason,
info.getStopTracepoint()));
}
rm.setData(new TraceStatusDMData(info));
} else {
fTraceRecordsStored = 0;
fIsTracingActive = false;
@ -962,9 +971,9 @@ public class GDBTraceControl_7_2 extends AbstractDsfService implements IGDBTrace
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.
stopVisualizingTraceData(targetDmc, rm);
// This was the old way to indicate that we want to exit visualization mode.
// We continue supporting it for backward compatibility
stopTraceVisualization(targetDmc, rm);
return;
}
@ -1062,7 +1071,9 @@ public class GDBTraceControl_7_2 extends AbstractDsfService implements IGDBTrace
}
}
private void stopVisualizingTraceData(final ITraceTargetDMContext context, final RequestMonitor rm) {
/** @since 4.4 */
@Override
public void stopTraceVisualization(final ITraceTargetDMContext context, final RequestMonitor rm) {
if (fIsTracingCurrentlySupported == false) {
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, NOT_SUPPORTED, "Tracing not supported", null)); //$NON-NLS-1$
rm.done();
@ -1086,7 +1097,6 @@ public class GDBTraceControl_7_2 extends AbstractDsfService implements IGDBTrace
ITraceRecordDMContext invalidDmc = new InvalidTraceRecordDMContext(getSession(), context);
getSession().dispatchEvent(new TraceRecordSelectedChangedEvent(invalidDmc), getProperties());
rm.done();
return;
}
@ -1134,6 +1144,68 @@ public class GDBTraceControl_7_2 extends AbstractDsfService implements IGDBTrace
}
}
/** @since 4.4 */
@Override
public void setCircularTraceBuffer(final ITraceTargetDMContext context, boolean useCircularBuffer, final RequestMonitor rm) {
if (context == null) {
rm.done(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INVALID_STATE, "Invalid context", null)); //$NON-NLS-1$
return;
}
if (fIsTracingCurrentlySupported == false) {
rm.done(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, NOT_SUPPORTED, "Tracing not supported", null)); //$NON-NLS-1$
return;
}
fConnection.queueCommand(
fCommandFactory.createMIGDBSetCircularTraceBuffer(context, useCircularBuffer),
new ImmediateDataRequestMonitor<MIInfo>(rm) {
@Override
protected void handleSuccess() {
fTraceStatusCache.reset(context);
rm.done();
}
});
}
/** @since 4.4 */
@Override
public void setDisconnectedTracing(final ITraceTargetDMContext context, boolean disconnectedTracing,final RequestMonitor rm) {
if (context == null) {
rm.done(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INVALID_STATE, "Invalid context", null)); //$NON-NLS-1$
return;
}
if (fIsTracingCurrentlySupported == false) {
rm.done(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, NOT_SUPPORTED, "Tracing not supported", null)); //$NON-NLS-1$
return;
}
fConnection.queueCommand(
fCommandFactory.createMIGDBSetDisconnectedTracing(context, disconnectedTracing),
new ImmediateDataRequestMonitor<MIInfo>(rm) {
@Override
protected void handleSuccess() {
fTraceStatusCache.reset(context);
rm.done();
}
});
}
/** @since 4.4 */
@Override
public void setTraceUser(ITraceTargetDMContext context, String userName, RequestMonitor rm) {
// Only supported started with GDB 7.4
rm.done(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INVALID_STATE, Messages.ErrorNotSupported, null));
}
/** @since 4.4 */
@Override
public void setTraceNotes(ITraceTargetDMContext context, String note, RequestMonitor rm) {
// Only supported started with GDB 7.4
rm.done(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INVALID_STATE, Messages.ErrorNotSupported, null));
}
@Override
public void flushCache(IDMContext context) {
fTraceStatusCache.reset(context);

View file

@ -0,0 +1,120 @@
/*******************************************************************************
* Copyright (c) 2013 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:
* Marc Khouzam (Ericsson) - Initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.dsf.gdb.service;
import java.util.Hashtable;
import org.eclipse.cdt.dsf.concurrent.ImmediateDataRequestMonitor;
import org.eclipse.cdt.dsf.concurrent.ImmediateRequestMonitor;
import org.eclipse.cdt.dsf.concurrent.RequestMonitor;
import org.eclipse.cdt.dsf.debug.service.command.ICommandControlService;
import org.eclipse.cdt.dsf.gdb.internal.GdbPlugin;
import org.eclipse.cdt.dsf.mi.service.IMICommandControl;
import org.eclipse.cdt.dsf.mi.service.command.CommandFactory;
import org.eclipse.cdt.dsf.mi.service.command.output.MIInfo;
import org.eclipse.cdt.dsf.service.DsfSession;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.debug.core.ILaunchConfiguration;
/**
* This class adds extra support for Trace Control for GDB 7.4
*
* @since 4.4
*/
public class GDBTraceControl_7_4 extends GDBTraceControl_7_2 {
private ICommandControlService fConnection;
private CommandFactory fCommandFactory;
public GDBTraceControl_7_4(DsfSession session, ILaunchConfiguration config) {
super(session, config);
}
@Override
public void initialize(final RequestMonitor requestMonitor) {
super.initialize(new ImmediateRequestMonitor(requestMonitor) {
@Override
protected void handleSuccess() {
doInitialize(requestMonitor);
}
});
}
private void doInitialize(RequestMonitor requestMonitor) {
// Register this service.
register(new String[] {IGDBTraceControl.class.getName(),
IGDBTraceControl2.class.getName(),
GDBTraceControl_7_2.class.getName(),
GDBTraceControl_7_4.class.getName()},
new Hashtable<String, String>());
fConnection = getServicesTracker().getService(ICommandControlService.class);
fCommandFactory = getServicesTracker().getService(IMICommandControl.class).getCommandFactory();
requestMonitor.done();
}
@Override
public void shutdown(RequestMonitor requestMonitor) {
unregister();
super.shutdown(requestMonitor);
}
@Override
public void setTraceUser(final ITraceTargetDMContext context, String userName, final RequestMonitor rm) {
if (context == null) {
rm.done(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INVALID_STATE, "Invalid context", null)); //$NON-NLS-1$
return;
}
if (isTracingCurrentlySupported() == false) {
rm.done(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, NOT_SUPPORTED, "Tracing not supported", null)); //$NON-NLS-1$
return;
}
fConnection.queueCommand(
fCommandFactory.createMIGDBSetTraceUser(context, userName),
new ImmediateDataRequestMonitor<MIInfo>(rm) {
@Override
protected void handleSuccess() {
getTraceStatusCache().reset(context);
rm.done();
}
});
}
@Override
public void setTraceNotes(final ITraceTargetDMContext context, String note, final RequestMonitor rm) {
if (context == null) {
rm.done(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INVALID_STATE, "Invalid context", null)); //$NON-NLS-1$
return;
}
if (isTracingCurrentlySupported() == false) {
rm.done(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, NOT_SUPPORTED, "Tracing not supported", null)); //$NON-NLS-1$
return;
}
getTraceStatusCache().reset(context);
fConnection.queueCommand(
fCommandFactory.createMIGDBSetTraceNotes(context, note),
new ImmediateDataRequestMonitor<MIInfo>(rm) {
@Override
protected void handleSuccess() {
getTraceStatusCache().reset(context);
rm.done();
}
});
}
}

View file

@ -13,6 +13,7 @@
* Marc Khouzam (Ericsson) - Include IGDBHardware service for the multicore visualizer (Bug 335027)
* Vladimir Prus (Mentor Graphics) - Support for OS resources.
* Marc Khouzam (Ericsson) - Support for GDB 7.6 memory service
* Marc Khouzam (Ericsson) - Support for GDB 7.4 trace control service
*******************************************************************************/
package org.eclipse.cdt.dsf.gdb.service;
@ -238,6 +239,9 @@ public class GdbDebugServicesFactory extends AbstractDsfDebugServicesFactory {
/** @since 3.0 */
protected IGDBTraceControl createTraceControlService(DsfSession session, ILaunchConfiguration config) {
if (GDB_7_4_VERSION.compareTo(fVersion) <= 0) {
return new GDBTraceControl_7_4(session, config);
}
// This service is available for GDB 7.2 but there is a pre-release of GDB that
// supports the same features and has version of 6.8.50.20090414
if (GDB_7_2_VERSION.compareTo(fVersion) <= 0 || "6.8.50.20090414".equals(fVersion)) { //$NON-NLS-1$

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2010, 2011 Ericsson and others.
* Copyright (c) 2010, 2013 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
@ -7,6 +7,7 @@
*
* Contributors:
* Ericsson - Initial API and implementation
* Dmitry Kozlov (Mentor Graphics) - Enhance trace status (Bug 390827)
*******************************************************************************/
package org.eclipse.cdt.dsf.gdb.service;
@ -19,10 +20,6 @@ import org.eclipse.cdt.dsf.datamodel.IDMEvent;
import org.eclipse.cdt.dsf.service.IDsfService;
/**
* <strong>EXPERIMENTAL</strong>. This class or interface has been added as part
* of a work in progress. There is no guarantee that this API will work or that
* it will remain the same.
*
* The TraceControl service provides access to the debugger Tracing functionality.
* It is used to do such things as start and stop tracing.
*
@ -133,7 +130,6 @@ public interface IGDBTraceControl extends IDsfService {
String file,
RequestMonitor rm);
/**
* Request that the backend use the specified trace record.
*/
@ -161,11 +157,80 @@ public interface IGDBTraceControl extends IDsfService {
/**
* Returns the id of the tracepoint that caused the stop.
* Should be null if getStopReason is null
* Should be null if getStopReason() is null
*/
Integer getStoppingTracepoint();
}
}
/** @since 4.4 */
public interface ITraceStatusDMData2 extends ITraceStatusDMData {
/**
* Returns the user-name of the user that started or stopped a trace. Returns an
* empty string if no user-name is available.
*/
String getUserName();
/**
* Returns the traces notes related to a started or stopped trace. Returns an
* empty string if no notes are defined.
*/
String getNotes();
/**
* Returns the start-time of an on-going trace.
* Returns an empty string if no start-time is available or if no trace was started.
*/
String getStartTime();
/**
* Returns the stop-time of the last trace experiment.
* Returns an empty string if no stop-time is available, if a trace is currently
* running or if no trace was ever started.
*/
String getStopTime();
/**
* Returns true if trace visualization is done from a trace file
* as compared to one from an ongoing execution.
*/
boolean isTracingFromFile();
/**
* Returns true if an ongoing tracing experiment will continue after
* GDB disconnects from the target.
*/
boolean isDisconnectedTracingEnabled();
/**
* Returns true if the buffer being used or to be used to record
* the trace data is a circular buffer (overwriting/flight-recorder), or not.
*/
boolean isCircularBuffer();
/**
* Returns the number of created frames of the current trace experiment.
*/
int getNumberOfCreatedFrames();
/**
* Returns the error description if the trace was stopped due to an error (getStopReason() returns ERROR).
* Returns null if the trace is not stopped, or if it is not stopped by an ERROR.
* Can return an empty string in other cases if no description is available.
*/
String getStopErrorDescription();
/**
* Returns the trace file path when isTracingFromFile() is true. Can return
* an empty string if the file path is not available.
* Should return null if isTracingFromFile() is false;
*/
String getTraceFile();
/**
* If a trace frame is currently being examined, this method will return
* its id. Returns null if no trace frame is in focus.
*/
String getCurrentTraceFrameId();
/**
* If a trace frame is currently being examined, this method will return
* the GDB tracepoint number that triggered the trace record in focus.
* Returns null if no trace frame is in focus (if getCurrentTraceFrameId() == null).
*/
Integer getTracepointNumberForCurrentTraceFrame();
}
public interface ITraceVariableDMData extends IDMData {
String getName();
String getValue();

View file

@ -0,0 +1,49 @@
/*******************************************************************************
* Copyright (c) 2013 Mentor Graphics 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:
* Dmitry Kozlov (Mentor Graphics) - initial API and implementation (Bug 390827)
*******************************************************************************/
package org.eclipse.cdt.dsf.gdb.service;
import org.eclipse.cdt.dsf.concurrent.RequestMonitor;
/**
* Enhancements to the trace control functionality, which allow to enable new settings.
* @since 4.4
*/
public interface IGDBTraceControl2 extends IGDBTraceControl {
/**
* Stops the visualization of trace data.
*/
public void stopTraceVisualization(ITraceTargetDMContext context, RequestMonitor rm);
/**
* Enables/disables the user of a circular trace buffer to collect trace data.
*/
public void setCircularTraceBuffer(ITraceTargetDMContext context, boolean useCircularBuffer, RequestMonitor rm);
/**
* Enables/disables disconnected tracing. When this flag is enabled, an ongoing tracing experiment will
* continue even if GDB disconnects from the target.
*/
public void setDisconnectedTracing(ITraceTargetDMContext context, boolean disconnectedTracing, RequestMonitor rm);
/**
* Sets the name of the user that is performing tracing operations.
* This name will be persisted during a disconnected tracing experiment.
*/
public void setTraceUser(ITraceTargetDMContext context, String userName, RequestMonitor rm);
/**
* Sets some information about the tracing experiment.
* This information will be persisted during a disconnected tracing experiment.
*/
public void setTraceNotes(ITraceTargetDMContext context, String notes, RequestMonitor rm);
}

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2012 Ericsson and others.
* Copyright (c) 2012, 2013 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
@ -24,6 +24,7 @@ class Messages extends NLS {
public static String NoMatches;
public static String UniqueMatch;
public static String UniqueMatches;
public static String ErrorNotSupported;
static {
// initialize resource bundle

View file

@ -16,3 +16,4 @@ GroupPattern=Group-pattern
NoMatches=No matches
UniqueMatch={0} unique match
UniqueMatches={0} unique matches
ErrorNotSupported=Operation not supported with this GDB version

View file

@ -22,6 +22,7 @@
* John Dallaway - Support for -data-write-memory-bytes (Bug 387793)
* Alvaro Sanchez-Leon (Ericsson) - Make Registers View specific to a frame (Bug (323552)
* Philippe Gil (AdaCore) - Add show/set language CLI commands (Bug 421541)
* Dmitry Kozlov (Mentor Graphics) - New trace-related methods (Bug 390827)
*******************************************************************************/
package org.eclipse.cdt.dsf.mi.service.command;
@ -110,7 +111,9 @@ import org.eclipse.cdt.dsf.mi.service.command.commands.MIGDBSetArgs;
import org.eclipse.cdt.dsf.mi.service.command.commands.MIGDBSetAutoSolib;
import org.eclipse.cdt.dsf.mi.service.command.commands.MIGDBSetBreakpointPending;
import org.eclipse.cdt.dsf.mi.service.command.commands.MIGDBSetCharset;
import org.eclipse.cdt.dsf.mi.service.command.commands.MIGDBSetCircularTraceBuffer;
import org.eclipse.cdt.dsf.mi.service.command.commands.MIGDBSetDetachOnFork;
import org.eclipse.cdt.dsf.mi.service.command.commands.MIGDBSetDisconnectedTracing;
import org.eclipse.cdt.dsf.mi.service.command.commands.MIGDBSetEnv;
import org.eclipse.cdt.dsf.mi.service.command.commands.MIGDBSetHostCharset;
import org.eclipse.cdt.dsf.mi.service.command.commands.MIGDBSetLanguage;
@ -125,6 +128,8 @@ import org.eclipse.cdt.dsf.mi.service.command.commands.MIGDBSetSolibSearchPath;
import org.eclipse.cdt.dsf.mi.service.command.commands.MIGDBSetTargetAsync;
import org.eclipse.cdt.dsf.mi.service.command.commands.MIGDBSetTargetCharset;
import org.eclipse.cdt.dsf.mi.service.command.commands.MIGDBSetTargetWideCharset;
import org.eclipse.cdt.dsf.mi.service.command.commands.MIGDBSetTraceNotes;
import org.eclipse.cdt.dsf.mi.service.command.commands.MIGDBSetTraceUser;
import org.eclipse.cdt.dsf.mi.service.command.commands.MIGDBShowExitCode;
import org.eclipse.cdt.dsf.mi.service.command.commands.MIGDBShowLanguage;
import org.eclipse.cdt.dsf.mi.service.command.commands.MIInferiorTTYSet;
@ -684,10 +689,20 @@ public class CommandFactory {
return new MIGDBSetCharset(ctx, charset);
}
/** @since 4.4 */
public ICommand<MIInfo> createMIGDBSetCircularTraceBuffer(ITraceTargetDMContext ctx, boolean useCircularBuffer) {
return new MIGDBSetCircularTraceBuffer(ctx, useCircularBuffer);
}
/** @since 4.0 */
public ICommand<MIInfo> createMIGDBSetDetachOnFork(ICommandControlDMContext ctx, boolean detach) {
return new MIGDBSetDetachOnFork(ctx, detach);
}
}
/** @since 4.4 */
public ICommand<MIInfo> createMIGDBSetDisconnectedTracing(ITraceTargetDMContext ctx, boolean disconnectedTracing) {
return new MIGDBSetDisconnectedTracing(ctx, disconnectedTracing);
}
public ICommand<MIInfo> createMIGDBSetEnv(ICommandControlDMContext dmc, String name) {
return new MIGDBSetEnv(dmc, name);
@ -757,6 +772,16 @@ public class CommandFactory {
return new MIGDBSetTargetAsync(ctx, isSet);
}
/** @since 4.4 */
public ICommand<MIInfo> createMIGDBSetTraceNotes(ITraceTargetDMContext ctx, String notes) {
return new MIGDBSetTraceNotes(ctx, notes);
}
/** @since 4.4*/
public ICommand<MIInfo> createMIGDBSetTraceUser(ITraceTargetDMContext ctx, String userName) {
return new MIGDBSetTraceUser(ctx, userName);
}
public ICommand<MIGDBShowExitCodeInfo> createMIGDBShowExitCode(ICommandControlDMContext ctx) {
return new MIGDBShowExitCode(ctx);
}
@ -1045,4 +1070,4 @@ public class CommandFactory {
public ICommand<MIVarUpdateInfo> createMIVarUpdate(ICommandControlDMContext dmc, String name) {
return new MIVarUpdate(dmc, name);
}
}
}

View file

@ -0,0 +1,26 @@
/*******************************************************************************
* Copyright (c) 2013 Mentor Graphics 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:
* Dmitry Kozlov (Mentor Graphics) - Initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.dsf.mi.service.command.commands;
import org.eclipse.cdt.dsf.gdb.service.IGDBTraceControl.ITraceTargetDMContext;
/**
* -gdb-set circular-trace-buffer on | off
*
* Sets circular trace buffer on or off.
* @since 4.4
*/
public class MIGDBSetCircularTraceBuffer extends MIGDBSet {
public MIGDBSetCircularTraceBuffer(ITraceTargetDMContext ctx, boolean useCircularTraceBuffer) {
super(ctx, new String[] {"circular-trace-buffer", useCircularTraceBuffer ? "on": "off"}); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
}
}

View file

@ -0,0 +1,26 @@
/*******************************************************************************
* Copyright (c) 2013 Mentor Graphics 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:
* Dmitry Kozlov (Mentor Graphics) - Initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.dsf.mi.service.command.commands;
import org.eclipse.cdt.dsf.gdb.service.IGDBTraceControl.ITraceTargetDMContext;
/**
* -gdb-set disconnected-tracing on | off
*
* Sets disconnected-tracing on or off.
* @since 4.4
*/
public class MIGDBSetDisconnectedTracing extends MIGDBSet {
public MIGDBSetDisconnectedTracing(ITraceTargetDMContext ctx, boolean disconnectedTracing) {
super(ctx, new String[] {"disconnected-tracing", disconnectedTracing ? "on": "off"}); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
}
}

View file

@ -0,0 +1,26 @@
/*******************************************************************************
* Copyright (c) 2013 Mentor Graphics 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:
* Dmitry Kozlov (Mentor Graphics) - Initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.dsf.mi.service.command.commands;
import org.eclipse.cdt.dsf.gdb.service.IGDBTraceControl.ITraceTargetDMContext;
/**
* -gdb-set trace-notes "note"
*
* Sets trace notes
* @since 4.4
*/
public class MIGDBSetTraceNotes extends MIGDBSet {
public MIGDBSetTraceNotes(ITraceTargetDMContext ctx, String notes) {
super(ctx, new String[] {"trace-notes", notes}); //$NON-NLS-1$
}
}

View file

@ -0,0 +1,26 @@
/*******************************************************************************
* Copyright (c) 2013 Mentor Graphics 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:
* Dmitry Kozlov (Mentor Graphics) - Initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.dsf.mi.service.command.commands;
import org.eclipse.cdt.dsf.gdb.service.IGDBTraceControl.ITraceTargetDMContext;
/**
* -gdb-set trace-user "user"
*
* Sets trace user
* @since 4.4
*/
public class MIGDBSetTraceUser extends MIGDBSet {
public MIGDBSetTraceUser(ITraceTargetDMContext ctx, String userName) {
super(ctx, new String[] {"trace-user", userName}); //$NON-NLS-1$
}
}

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2010 Ericsson and others.
* Copyright (c) 2010, 2013 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
@ -7,6 +7,7 @@
*
* Contributors:
* Ericsson - Initial API and implementation
* Dmitry Kozlov (Mentor Graphics) - Enhance trace status (Bug 390827)
*******************************************************************************/
package org.eclipse.cdt.dsf.mi.service.command.output;
@ -19,6 +20,27 @@ import org.eclipse.cdt.dsf.gdb.service.IGDBTraceControl.STOP_REASON_ENUM;
* ^done,supported="1",running="0",stop-reason="request",frames="0",buffer-size="5242880",buffer-free="5242880"
* ^done,supported="1",running="0",stop-reason="passcount",stopping-tracepoint="7",frames="3",buffer-size="5242880",buffer-free="5242862"
*
* Field presence:
* With GDB 7.2:
* "supported"
* "running"
* "stop-reason"
* "stopping-tracepoint"
* "error-description"
* "frames"
* "frames-created"
* "buffer-size"
* "buffer-free"
* "disconnected"
* "circular"
* Added in GDB 7.4:
* "user-name"
* "notes"
* "start-time"
* "stop-time"
* Added in GDB 7.6:
* "trace-file"
*
* @since 3.0
*/
public class MITraceStatusInfo extends MIInfo {
@ -26,10 +48,20 @@ public class MITraceStatusInfo extends MIInfo {
private int fFreeBufferSize = 0;
private int fTotalBufferSize = 0;
private int fNumberOfCollectedFrames = 0;
private int fNumberOfCreatedFrames = 0;
private boolean fIsTracingActive = false;
private boolean fIsTracingSupported = false;
private STOP_REASON_ENUM fStopReason = null;
private String fStopErrorDesc = ""; //$NON-NLS-1$
private Integer fStoppingTracepoint = null;
private boolean fIsTracingFromFile = false;
private String fTraceFile = ""; //$NON-NLS-1$
private boolean fIsDisconnectedTracingEnabled = false;
private String fUserName = ""; //$NON-NLS-1$
private String fNotes = ""; //$NON-NLS-1$
private String fStartTime = ""; //$NON-NLS-1$
private String fStopTime = ""; //$NON-NLS-1$
private boolean fIsCircularBuffer = false;
public MITraceStatusInfo(MIOutput out) {
super(out);
@ -44,6 +76,11 @@ public class MITraceStatusInfo extends MIInfo {
return fNumberOfCollectedFrames;
}
/** @since 4.4 */
public int getNumberOfCreatedFrames() {
return fNumberOfCreatedFrames;
}
public int getTotalBufferSize() {
return fTotalBufferSize;
}
@ -55,15 +92,60 @@ public class MITraceStatusInfo extends MIInfo {
public boolean isTracingSupported() {
return fIsTracingSupported;
}
/** @since 4.4 */
public boolean isTracingFromFile() {
return fIsTracingFromFile;
}
/** @since 4.4 */
public boolean isDisconnectedTracingEnabled() {
return fIsDisconnectedTracingEnabled;
}
public STOP_REASON_ENUM getStopReason() {
return fStopReason;
}
/** @since 4.4 */
public String getStopErrorDescription() {
return fStopErrorDesc;
}
public Integer getStopTracepoint() {
return fStoppingTracepoint;
}
/** @since 4.4 */
public String getUserName() {
return fUserName;
}
/** @since 4.4 */
public String getNotes() {
return fNotes;
}
/** @since 4.4 */
public String getStartTime() {
return fStartTime;
}
/** @since 4.4 */
public String getStopTime() {
return fStopTime;
}
/** @since 4.4 */
public String getTraceFile() {
return isTracingFromFile() ? fTraceFile : null;
}
/** @since 4.4 */
public boolean isCircularBuffer() {
return fIsCircularBuffer;
}
private void parse() {
if (isDone()) {
MIOutput out = getMIOutput();
@ -75,33 +157,18 @@ public class MITraceStatusInfo extends MIInfo {
if (var.equals("supported")) { //$NON-NLS-1$
MIValue val = results[i].getMIValue();
if (val instanceof MIConst) {
fIsTracingSupported = ((MIConst)val).getString().equals("0") ? false : true;; //$NON-NLS-1$
fIsTracingSupported = ((MIConst)val).getString().equals("0") ? false : true; //$NON-NLS-1$
fIsTracingFromFile = ((MIConst)val).getString().equals("file"); //$NON-NLS-1$
}
} else if (var.equals("trace-file")) { //$NON-NLS-1$
MIValue val = results[i].getMIValue();
if (val instanceof MIConst) {
fTraceFile = ((MIConst)val).getString().trim();
}
} else if (var.equals("running")) { //$NON-NLS-1$
MIValue val = results[i].getMIValue();
if (val instanceof MIConst) {
fIsTracingActive = ((MIConst)val).getString().equals("0") ? false : true;; //$NON-NLS-1$
}
} else if (var.equals("frames")) { //$NON-NLS-1$
MIValue val = results[i].getMIValue();
if (val instanceof MIConst) {
try {
fNumberOfCollectedFrames = Integer.parseInt(((MIConst)val).getString());
} catch (NumberFormatException e) {}
}
} else if (var.equals("buffer-size")) { //$NON-NLS-1$
MIValue val = results[i].getMIValue();
if (val instanceof MIConst) {
try {
fTotalBufferSize = Integer.parseInt(((MIConst)val).getString());
} catch (NumberFormatException e) {}
}
} else if (var.equals("buffer-free")) { //$NON-NLS-1$
MIValue val = results[i].getMIValue();
if (val instanceof MIConst) {
try {
fFreeBufferSize = Integer.parseInt(((MIConst)val).getString());
} catch (NumberFormatException e) {}
fIsTracingActive = ((MIConst)val).getString().equals("0") ? false : true; //$NON-NLS-1$
}
} else if (var.equals("stop-reason")) { //$NON-NLS-1$
MIValue val = results[i].getMIValue();
@ -125,10 +192,73 @@ public class MITraceStatusInfo extends MIInfo {
MIValue val = results[i].getMIValue();
if (val instanceof MIConst) {
try {
fStoppingTracepoint = Integer.parseInt(((MIConst)val).getString());
fStoppingTracepoint = Integer.parseInt(((MIConst)val).getString().trim());
} catch (NumberFormatException e) {}
}
}
} else if (var.equals("error-description")) { //$NON-NLS-1$
MIValue val = results[i].getMIValue();
if (val instanceof MIConst) {
fStopErrorDesc = ((MIConst)val).getString().trim();
}
} else if (var.equals("frames")) { //$NON-NLS-1$
MIValue val = results[i].getMIValue();
if (val instanceof MIConst) {
try {
fNumberOfCollectedFrames = Integer.parseInt(((MIConst)val).getString().trim());
} catch (NumberFormatException e) {}
}
} else if (var.equals("frames-created")) { //$NON-NLS-1$
MIValue val = results[i].getMIValue();
if (val instanceof MIConst) {
try {
fNumberOfCreatedFrames = Integer.parseInt(((MIConst)val).getString().trim());
} catch (NumberFormatException e) {}
}
} else if (var.equals("buffer-size")) { //$NON-NLS-1$
MIValue val = results[i].getMIValue();
if (val instanceof MIConst) {
try {
fTotalBufferSize = Integer.parseInt(((MIConst)val).getString().trim());
} catch (NumberFormatException e) {}
}
} else if (var.equals("buffer-free")) { //$NON-NLS-1$
MIValue val = results[i].getMIValue();
if (val instanceof MIConst) {
try {
fFreeBufferSize = Integer.parseInt(((MIConst)val).getString().trim());
} catch (NumberFormatException e) {}
}
} else if (var.equals("disconnected")) { //$NON-NLS-1$
MIValue val = results[i].getMIValue();
if (val instanceof MIConst) {
fIsDisconnectedTracingEnabled = ((MIConst)val).getString().equals("0") ? false : true; //$NON-NLS-1$
}
} else if (var.equals("circular")) { //$NON-NLS-1$
MIValue val = results[i].getMIValue();
if (val instanceof MIConst) {
fIsCircularBuffer = ((MIConst)val).getString().trim().equals("0") ? false : true; //$NON-NLS-1$
}
} else if (var.equals("user-name")) { //$NON-NLS-1$
MIValue val = results[i].getMIValue();
if (val instanceof MIConst) {
fUserName = ((MIConst)val).getString().trim();
}
} else if (var.equals("notes")) { //$NON-NLS-1$
MIValue val = results[i].getMIValue();
if (val instanceof MIConst) {
fNotes = ((MIConst)val).getString();
}
} else if (var.equals("start-time")) { //$NON-NLS-1$
MIValue val = results[i].getMIValue();
if (val instanceof MIConst) {
fStartTime = ((MIConst)val).getString().trim();
}
} else if (var.equals("stop-time")) { //$NON-NLS-1$
MIValue val = results[i].getMIValue();
if (val instanceof MIConst) {
fStopTime = ((MIConst)val).getString().trim();
}
}
}
}
}