1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-24 09:25:31 +02:00

[284286] New Trace Control View to allow to start/stop/status a tracing experiment. Support for Trace State Variables. Support for Saving trace data to a file.

This commit is contained in:
Marc Khouzam 2010-01-27 19:05:47 +00:00
parent 9524c4671f
commit 6764511b39
38 changed files with 3473 additions and 17 deletions

View file

@ -0,0 +1,20 @@
/*******************************************************************************
* Copyright (c) 2010 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
*******************************************************************************/
package org.eclipse.cdt.debug.core.model;
import org.eclipse.debug.core.commands.IDebugCommandHandler;
/**
* Handler interface to save trace data.
* @since 7.0
*/
public interface ISaveTraceDataHandler extends IDebugCommandHandler {
}

View file

@ -0,0 +1,20 @@
/*******************************************************************************
* Copyright (c) 2010 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
*******************************************************************************/
package org.eclipse.cdt.debug.core.model;
import org.eclipse.debug.core.commands.IDebugCommandHandler;
/**
* Handler interface to request the start of tracing.
* @since 7.0
*/
public interface IStartTracingHandler extends IDebugCommandHandler {
}

View file

@ -0,0 +1,20 @@
/*******************************************************************************
* Copyright (c) 2010 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
*******************************************************************************/
package org.eclipse.cdt.debug.core.model;
import org.eclipse.debug.core.commands.IDebugCommandHandler;
/**
* Handler interface to request the stop of tracing.
* @since 7.0
*/
public interface IStopTracingHandler extends IDebugCommandHandler {
}

View file

@ -222,4 +222,12 @@ Uncall.label = Uncall
BreakpointTypes.label=B&reakpoint Types
# Tracepoints
TracepointActionSet.label=Tracepoints
TracepointActionSet.label=C/C++ Tracepoints
TracingCategory.description=Category for Tracing Commands
TracingCategory.name=Tracing Commands
StartTracing.description=Start Tracing Experiment
StartTracing.name=Start Tracing
StopTracing.description=Stop Tracing Experiment
StopTracing.name=Stop Tracing
SaveTraceData.description=Save Trace Data to File
SaveTraceData.name=Save Trace Data

View file

@ -2021,6 +2021,29 @@
id="org.eclipse.cdt.debug.ui.command.uncall"
name="%Uncall.name">
</command>
<category
description="%TracingCategory.description"
id="org.eclipse.cdt.debug.ui.category.tracing"
name="%TracingCategory.name">
</category>
<command
categoryId="org.eclipse.cdt.debug.ui.category.tracing"
description="%StartTracing.description"
id="org.eclipse.cdt.debug.ui.command.startTracing"
name="%StartTracing.name">
</command>
<command
categoryId="org.eclipse.cdt.debug.ui.category.tracing"
description="%StopTracing.description"
id="org.eclipse.cdt.debug.ui.command.stopTracing"
name="%StopTracing.name">
</command>
<command
categoryId="org.eclipse.cdt.debug.ui.category.tracing"
description="%SaveTraceData.description"
id="org.eclipse.cdt.debug.ui.command.saveTraceData"
name="%SaveTraceData.name">
</command>
</extension>
<extension
point="org.eclipse.ui.handlers">
@ -2044,6 +2067,18 @@
class="org.eclipse.cdt.debug.internal.ui.commands.UncallCommandHandler"
commandId="org.eclipse.cdt.debug.ui.command.uncall">
</handler>
<handler
class="org.eclipse.cdt.debug.internal.ui.commands.StartTracingCommandHandler"
commandId="org.eclipse.cdt.debug.ui.command.startTracing">
</handler>
<handler
class="org.eclipse.cdt.debug.internal.ui.commands.StopTracingCommandHandler"
commandId="org.eclipse.cdt.debug.ui.command.stopTracing">
</handler>
<handler
class="org.eclipse.cdt.debug.internal.ui.commands.SaveTraceDataCommandHandler"
commandId="org.eclipse.cdt.debug.ui.command.saveTraceData">
</handler>
</extension>
<extension
point="org.eclipse.core.expressions.definitions">
@ -2344,6 +2379,33 @@
</visibleWhen>
</command>
</menuContribution>
<menuContribution
locationURI="popup:org.eclipse.debug.ui.DebugView?before=renderGroup">
<command
commandId="org.eclipse.cdt.debug.ui.command.startTracing"
icon="icons/obj16/start_tracing_obj.gif"
label="%StartTracing.name"
style="push">
<visibleWhen
checkEnabled="false">
<reference
definitionId="org.eclipse.cdt.debug.ui.testIsTracepointActionSetActive">
</reference>
</visibleWhen>
</command>
<command
commandId="org.eclipse.cdt.debug.ui.command.stopTracing"
icon="icons/obj16/stop_tracing_obj.gif"
label="%StopTracing.name"
style="push">
<visibleWhen
checkEnabled="false">
<reference
definitionId="org.eclipse.cdt.debug.ui.testIsTracepointActionSetActive">
</reference>
</visibleWhen>
</command>
</menuContribution>
</extension>
<extension
point="org.eclipse.ui.popupMenus">

View file

@ -0,0 +1,26 @@
/*******************************************************************************
* Copyright (c) 2010 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
*******************************************************************************/
package org.eclipse.cdt.debug.internal.ui.commands;
import org.eclipse.cdt.debug.core.model.ISaveTraceDataHandler;
import org.eclipse.debug.ui.actions.DebugCommandHandler;
/**
* Command handler to save the trace data to a file
*
* @since 7.0
*/
public class SaveTraceDataCommandHandler extends DebugCommandHandler {
@Override
protected Class<?> getCommandType() {
return ISaveTraceDataHandler.class;
}
}

View file

@ -0,0 +1,26 @@
/*******************************************************************************
* Copyright (c) 2010 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
*******************************************************************************/
package org.eclipse.cdt.debug.internal.ui.commands;
import org.eclipse.cdt.debug.core.model.IStartTracingHandler;
import org.eclipse.debug.ui.actions.DebugCommandHandler;
/**
* Command handler to request the start of tracing
*
* @since 7.0
*/
public class StartTracingCommandHandler extends DebugCommandHandler {
@Override
protected Class<?> getCommandType() {
return IStartTracingHandler.class;
}
}

View file

@ -0,0 +1,26 @@
/*******************************************************************************
* Copyright (c) 2010 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
*******************************************************************************/
package org.eclipse.cdt.debug.internal.ui.commands;
import org.eclipse.cdt.debug.core.model.IStopTracingHandler;
import org.eclipse.debug.ui.actions.DebugCommandHandler;
/**
* Command handler to request the stop of tracing
*
* @since 7.0
*/
public class StopTracingCommandHandler extends DebugCommandHandler {
@Override
protected Class<?> getCommandType() {
return IStopTracingHandler.class;
}
}

View file

@ -29,3 +29,9 @@ editorTextHover.description=Shows formatted value in debugger hover
breakpoints.property.filter=Filter
tracepoints.property.common=Common
tracepoints.property.actions=Actions
# Tracepoints
view.traceControl.name=Trace Control
toolbar.startTracing.name=Start Tracing
toolbar.stopTracing.name=Stop Tracing
toolbar.saveTracing.name=Save Trace Data

View file

@ -355,5 +355,56 @@
debugModelId="org.eclipse.cdt.dsf.gdb">
</modelContextBinding>
</extension>
<extension
point="org.eclipse.ui.views">
<view
category="org.eclipse.debug.ui"
class="org.eclipse.cdt.dsf.gdb.internal.ui.tracepoints.TraceControlView"
icon="icons/full/view16/tracecontrol_view.gif"
id="org.eclipse.cdt.dsf.gdb.ui.tracecontrol.view"
name="%view.traceControl.name">
</view>
</extension>
<extension
point="org.eclipse.ui.perspectiveExtensions">
<perspectiveExtension
targetID="org.eclipse.debug.ui.DebugPerspective">
<view
relative="org.eclipse.ui.views.ContentOutline"
visible="false"
relationship="stack"
id="org.eclipse.cdt.dsf.gdb.ui.tracecontrol.view">
</view>
<viewShortcut
id="org.eclipse.cdt.dsf.gdb.ui.tracecontrol.view">
</viewShortcut>
</perspectiveExtension>
</extension>
<extension
point="org.eclipse.ui.menus">
<menuContribution
locationURI="toolbar:org.eclipse.cdt.dsf.gdb.ui.tracecontrol.view?after=additions">
<command
commandId="org.eclipse.cdt.debug.ui.command.startTracing"
icon="icons/full/obj16/starttracing.gif"
label="%toolbar.startTracing.name"
style="push">
</command>
<command
commandId="org.eclipse.cdt.debug.ui.command.stopTracing"
icon="icons/full/obj16/stoptracing.gif"
label="%toolbar.stopTracing.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>
</plugin>

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2006, 2008 Wind River Systems and others.
* Copyright (c) 2010 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
@ -20,7 +20,10 @@ import org.eclipse.cdt.debug.core.model.IReverseResumeHandler;
import org.eclipse.cdt.debug.core.model.IReverseStepIntoHandler;
import org.eclipse.cdt.debug.core.model.IReverseStepOverHandler;
import org.eclipse.cdt.debug.core.model.IReverseToggleHandler;
import org.eclipse.cdt.debug.core.model.ISaveTraceDataHandler;
import org.eclipse.cdt.debug.core.model.IStartTracingHandler;
import org.eclipse.cdt.debug.core.model.ISteppingModeTarget;
import org.eclipse.cdt.debug.core.model.IStopTracingHandler;
import org.eclipse.cdt.debug.core.model.IUncallHandler;
import org.eclipse.cdt.dsf.concurrent.Immutable;
import org.eclipse.cdt.dsf.concurrent.ThreadSafe;
@ -44,6 +47,9 @@ import org.eclipse.cdt.dsf.gdb.internal.ui.commands.GdbReverseResumeCommand;
import org.eclipse.cdt.dsf.gdb.internal.ui.commands.GdbReverseStepIntoCommand;
import org.eclipse.cdt.dsf.gdb.internal.ui.commands.GdbReverseStepOverCommand;
import org.eclipse.cdt.dsf.gdb.internal.ui.commands.GdbReverseToggleCommand;
import org.eclipse.cdt.dsf.gdb.internal.ui.commands.GdbSaveTraceDataCommand;
import org.eclipse.cdt.dsf.gdb.internal.ui.commands.GdbStartTracingCommand;
import org.eclipse.cdt.dsf.gdb.internal.ui.commands.GdbStopTracingCommand;
import org.eclipse.cdt.dsf.gdb.internal.ui.commands.GdbUncallCommand;
import org.eclipse.cdt.dsf.gdb.internal.ui.viewmodel.GdbViewModelAdapter;
import org.eclipse.cdt.dsf.gdb.launching.GdbLaunch;
@ -104,6 +110,9 @@ public class GdbAdapterFactory
final SteppingController fSteppingController;
final DefaultRefreshAllTarget fRefreshAllTarget;
final GdbReverseToggleCommand fReverseToggleTarget;
final GdbStartTracingCommand fStartTracingTarget;
final GdbStopTracingCommand fStopTracingTarget;
final GdbSaveTraceDataCommand fSaveTraceDataTarget;
SessionAdapterSet(GdbLaunch launch) {
fLaunch = launch;
@ -140,7 +149,10 @@ public class GdbAdapterFactory
fModelSelectionPolicyFactory = new DefaultDsfModelSelectionPolicyFactory();
fRefreshAllTarget = new DefaultRefreshAllTarget();
fReverseToggleTarget = new GdbReverseToggleCommand(session);
fStartTracingTarget = new GdbStartTracingCommand(session);
fStopTracingTarget = new GdbStopTracingCommand(session);
fSaveTraceDataTarget = new GdbSaveTraceDataCommand(session);
session.registerModelAdapter(ISteppingModeTarget.class, fSteppingModeTarget);
session.registerModelAdapter(IStepIntoHandler.class, fStepIntoCommand);
session.registerModelAdapter(IReverseStepIntoHandler.class, fReverseStepIntoCommand);
@ -158,6 +170,9 @@ public class GdbAdapterFactory
session.registerModelAdapter(IModelSelectionPolicyFactory.class, fModelSelectionPolicyFactory);
session.registerModelAdapter(IRefreshAllTarget.class, fRefreshAllTarget);
session.registerModelAdapter(IReverseToggleHandler.class, fReverseToggleTarget);
session.registerModelAdapter(IStartTracingHandler.class, fStartTracingTarget);
session.registerModelAdapter(IStopTracingHandler.class, fStopTracingTarget);
session.registerModelAdapter(ISaveTraceDataHandler.class, fSaveTraceDataTarget);
fDebugModelProvider = new IDebugModelProvider() {
// @see org.eclipse.debug.core.model.IDebugModelProvider#getModelIdentifiers()
@ -203,6 +218,9 @@ public class GdbAdapterFactory
session.unregisterModelAdapter(IModelSelectionPolicyFactory.class);
session.unregisterModelAdapter(IRefreshAllTarget.class);
session.unregisterModelAdapter(IReverseToggleHandler.class);
session.unregisterModelAdapter(IStartTracingHandler.class);
session.unregisterModelAdapter(IStopTracingHandler.class);
session.unregisterModelAdapter(ISaveTraceDataHandler.class);
fSteppingModeTarget.dispose();
fStepIntoCommand.dispose();
@ -220,6 +238,9 @@ public class GdbAdapterFactory
fDisconnectCommand.dispose();
fSuspendTrigger.dispose();
fReverseToggleTarget.dispose();
fStartTracingTarget.dispose();
fStopTracingTarget.dispose();
fSaveTraceDataTarget.dispose();
}
}

View file

@ -0,0 +1,168 @@
/*******************************************************************************
* Copyright (c) 2010 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
*******************************************************************************/
package org.eclipse.cdt.dsf.gdb.internal.ui.commands;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.RejectedExecutionException;
import org.eclipse.cdt.debug.core.model.ISaveTraceDataHandler;
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
import org.eclipse.cdt.dsf.concurrent.DsfExecutor;
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.IGDBTraceControl.ITraceTargetDMContext;
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.IProgressMonitor;
import org.eclipse.debug.core.IRequest;
import org.eclipse.debug.core.commands.AbstractDebugCommand;
import org.eclipse.debug.core.commands.IDebugCommandRequest;
import org.eclipse.debug.core.commands.IEnabledStateRequest;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.PlatformUI;
/**
* Command to save the trace data to file
*
* @since 2.1
*/
public class GdbSaveTraceDataCommand extends AbstractDebugCommand implements ISaveTraceDataHandler {
private final DsfExecutor fExecutor;
private final DsfServicesTracker fTracker;
public GdbSaveTraceDataCommand(DsfSession session) {
fExecutor = session.getExecutor();
fTracker = new DsfServicesTracker(GdbUIPlugin.getBundleContext(), session.getId());
}
public void dispose() {
fTracker.dispose();
}
@Override
protected void doExecute(Object[] targets, IProgressMonitor monitor, IRequest request)
throws CoreException {
if (targets.length != 1) {
return;
}
final ITraceTargetDMContext dmc = DMContexts.getAncestorOfType(((IDMVMContext)targets[0]).getDMContext(), ITraceTargetDMContext.class);
if (dmc == null) {
return;
}
final String[] fileName = new String[1];
PlatformUI.getWorkbench().getDisplay().syncExec(new Runnable() {
public void run() {
fileName[0] = promptForFileName();
};
});
if (fileName[0] != null) {
Query<Object> saveTraceDataQuery = new Query<Object>() {
@Override
public void execute(final DataRequestMonitor<Object> rm) {
IGDBTraceControl traceControl = fTracker.getService(IGDBTraceControl.class);
if (traceControl != null) {
traceControl.saveTraceData(dmc, fileName[0], false, rm);
} else {
rm.done();
}
}
};
try {
fExecutor.execute(saveTraceDataQuery);
saveTraceDataQuery.get();
} catch (InterruptedException e) {
} catch (ExecutionException e) {
} catch (RejectedExecutionException e) {
// Can be thrown if the session is shutdown
}
}
}
@Override
protected boolean isExecutable(Object[] targets, IProgressMonitor monitor, IEnabledStateRequest request)
throws CoreException {
if (targets.length != 1) {
return false;
}
final ITraceTargetDMContext dmc = DMContexts.getAncestorOfType(((IDMVMContext)targets[0]).getDMContext(), ITraceTargetDMContext.class);
if (dmc == null) {
return false;
}
Query<Boolean> canSaveQuery = new Query<Boolean>() {
@Override
public void execute(DataRequestMonitor<Boolean> rm) {
IGDBTraceControl traceControl = fTracker.getService(IGDBTraceControl.class);
if (traceControl != null) {
traceControl.canSaveTraceData(dmc, rm);
} else {
rm.setData(false);
rm.done();
}
}
};
try {
fExecutor.execute(canSaveQuery);
return canSaveQuery.get();
} catch (InterruptedException e) {
} catch (ExecutionException e) {
} catch (RejectedExecutionException e) {
// Can be thrown if the session is shutdown
}
return false;
}
@Override
protected Object getTarget(Object element) {
if (element instanceof IDMVMContext) {
return element;
}
return null;
}
/*
* Keep the command enabled since there is no automatic re-selection of the debug
* context for this command. If not, it will remain disabled until something causes
* the debug context to change.
*
* (non-Javadoc)
* @see org.eclipse.debug.core.commands.AbstractDebugCommand#isRemainEnabled(org.eclipse.debug.core.commands.IDebugCommandRequest)
*/
@Override
protected boolean isRemainEnabled(IDebugCommandRequest request) {
return true;
}
private String promptForFileName() {
Shell shell = Display.getDefault().getActiveShell();
if (shell == null) {
return null;
}
FileDialog fd = new FileDialog(shell, SWT.SAVE);
return fd.open();
}
}

View file

@ -0,0 +1,143 @@
/*******************************************************************************
* Copyright (c) 2010 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
*******************************************************************************/
package org.eclipse.cdt.dsf.gdb.internal.ui.commands;
import java.util.concurrent.ExecutionException;
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.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.IGDBTraceControl.ITraceTargetDMContext;
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.IProgressMonitor;
import org.eclipse.debug.core.IRequest;
import org.eclipse.debug.core.commands.AbstractDebugCommand;
import org.eclipse.debug.core.commands.IDebugCommandRequest;
import org.eclipse.debug.core.commands.IEnabledStateRequest;
/**
* Command to start the tracing experiment
*
* @since 2.1
*/
public class GdbStartTracingCommand extends AbstractDebugCommand implements IStartTracingHandler {
private final DsfExecutor fExecutor;
private final DsfServicesTracker fTracker;
public GdbStartTracingCommand(DsfSession session) {
fExecutor = session.getExecutor();
fTracker = new DsfServicesTracker(GdbUIPlugin.getBundleContext(), session.getId());
}
public void dispose() {
fTracker.dispose();
}
@Override
protected void doExecute(Object[] targets, IProgressMonitor monitor, IRequest request)
throws CoreException {
if (targets.length != 1) {
return;
}
final ITraceTargetDMContext dmc = DMContexts.getAncestorOfType(((IDMVMContext)targets[0]).getDMContext(), ITraceTargetDMContext.class);
if (dmc == null) {
return;
}
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);
} else {
rm.done();
}
}
};
try {
fExecutor.execute(startTracingQuery);
startTracingQuery.get();
} catch (InterruptedException e) {
} catch (ExecutionException e) {
} catch (RejectedExecutionException e) {
// Can be thrown if the session is shutdown
}
}
@Override
protected boolean isExecutable(Object[] targets, IProgressMonitor monitor, IEnabledStateRequest request)
throws CoreException {
if (targets.length != 1) {
return false;
}
final ITraceTargetDMContext dmc = DMContexts.getAncestorOfType(((IDMVMContext)targets[0]).getDMContext(), ITraceTargetDMContext.class);
if (dmc == null) {
return false;
}
Query<Boolean> canStartTracingQuery = new Query<Boolean>() {
@Override
public void execute(DataRequestMonitor<Boolean> rm) {
IGDBTraceControl traceControl = fTracker.getService(IGDBTraceControl.class);
if (traceControl != null) {
traceControl.canStartTracing(dmc, rm);
} else {
rm.setData(false);
rm.done();
}
}
};
try {
fExecutor.execute(canStartTracingQuery);
return canStartTracingQuery.get();
} catch (InterruptedException e) {
} catch (ExecutionException e) {
} catch (RejectedExecutionException e) {
// Can be thrown if the session is shutdown
}
return false;
}
@Override
protected Object getTarget(Object element) {
if (element instanceof IDMVMContext) {
return element;
}
return null;
}
/*
* Re-selection of the debug context will be forced by the Debug Model through a StartTracing event.
* Therefore, the enablement of this command will be refreshed, so we don't need to keep it enabled.
* In fact, it is better to have it disabled right after selection to avoid a double-click
*
* (non-Javadoc)
* @see org.eclipse.debug.core.commands.AbstractDebugCommand#isRemainEnabled(org.eclipse.debug.core.commands.IDebugCommandRequest)
*/
@Override
protected boolean isRemainEnabled(IDebugCommandRequest request) {
return false;
}
}

View file

@ -0,0 +1,142 @@
/*******************************************************************************
* Copyright (c) 2010 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
*******************************************************************************/
package org.eclipse.cdt.dsf.gdb.internal.ui.commands;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.RejectedExecutionException;
import org.eclipse.cdt.debug.core.model.IStopTracingHandler;
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
import org.eclipse.cdt.dsf.concurrent.DsfExecutor;
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.IGDBTraceControl.ITraceTargetDMContext;
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.IProgressMonitor;
import org.eclipse.debug.core.IRequest;
import org.eclipse.debug.core.commands.AbstractDebugCommand;
import org.eclipse.debug.core.commands.IDebugCommandRequest;
import org.eclipse.debug.core.commands.IEnabledStateRequest;
/**
* Command to stop the tracing experiment
*
* @since 2.1
*/
public class GdbStopTracingCommand extends AbstractDebugCommand implements IStopTracingHandler {
private final DsfExecutor fExecutor;
private final DsfServicesTracker fTracker;
public GdbStopTracingCommand(DsfSession session) {
fExecutor = session.getExecutor();
fTracker = new DsfServicesTracker(GdbUIPlugin.getBundleContext(), session.getId());
}
public void dispose() {
fTracker.dispose();
}
@Override
protected void doExecute(Object[] targets, IProgressMonitor monitor, IRequest request)
throws CoreException {
if (targets.length != 1) {
return;
}
final ITraceTargetDMContext dmc = DMContexts.getAncestorOfType(((IDMVMContext)targets[0]).getDMContext(), ITraceTargetDMContext.class);
if (dmc == null) {
return;
}
Query<Object> stopTracingQuery = new Query<Object>() {
@Override
public void execute(final DataRequestMonitor<Object> rm) {
IGDBTraceControl traceControl = fTracker.getService(IGDBTraceControl.class);
if (traceControl != null) {
traceControl.stopTracing(dmc, rm);
} else {
rm.done();
}
}
};
try {
fExecutor.execute(stopTracingQuery);
stopTracingQuery.get();
} catch (InterruptedException e) {
} catch (ExecutionException e) {
} catch (RejectedExecutionException e) {
// Can be thrown if the session is shutdown
}
}
@Override
protected boolean isExecutable(Object[] targets, IProgressMonitor monitor, IEnabledStateRequest request)
throws CoreException {
if (targets.length != 1) {
return false;
}
final ITraceTargetDMContext dmc = DMContexts.getAncestorOfType(((IDMVMContext)targets[0]).getDMContext(), ITraceTargetDMContext.class);
if (dmc == null) {
return false;
}
Query<Boolean> canStopTracingQuery = new Query<Boolean>() {
@Override
public void execute(DataRequestMonitor<Boolean> rm) {
IGDBTraceControl traceControl = fTracker.getService(IGDBTraceControl.class);
if (traceControl != null) {
traceControl.canStopTracing(dmc, rm);
} else {
rm.setData(false);
rm.done();
}
}
};
try {
fExecutor.execute(canStopTracingQuery);
return canStopTracingQuery.get();
} catch (InterruptedException e) {
} catch (ExecutionException e) {
} catch (RejectedExecutionException e) {
// Can be thrown if the session is shutdown
}
return false;
}
@Override
protected Object getTarget(Object element) {
if (element instanceof IDMVMContext) {
return element;
}
return null;
}
/*
* Re-selection of the debug context will be forced by the Debug Model through a StopTracing event.
* Therefore, the enablement of this command will be refreshed, so we don't need to keep it enabled.
* In fact, it is better to have it disabled right after selection to avoid a double-click
* (non-Javadoc)
* @see org.eclipse.debug.core.commands.AbstractDebugCommand#isRemainEnabled(org.eclipse.debug.core.commands.IDebugCommandRequest)
*/
@Override
protected boolean isRemainEnabled(IDebugCommandRequest request) {
return false;
}
}

View file

@ -0,0 +1,145 @@
/*******************************************************************************
* Copyright (c) 2010 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
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Wind River Systems - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.dsf.gdb.internal.ui.tracepoints;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;
import org.eclipse.cdt.dsf.gdb.internal.ui.GdbUIPlugin;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Plugin;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.resource.ImageRegistry;
import org.eclipse.swt.SWTException;
import org.eclipse.swt.graphics.Image;
import org.osgi.framework.Bundle;
/**
* Abstract image registry that allows for defining fallback paths for images.
* This is copy of <code>org.eclipse.cdt.dsf.debug.internal.ui.disassembly.AbstractImageRegistry</code>
*
* @since 2.1
*/
public abstract class AbstractImageRegistry extends ImageRegistry {
private HashMap<String, String> fPlugins = new HashMap<String, String>();
private HashMap<String, String[]> fLocations = new HashMap<String, String[]>();
private URL fBaseUrl;
protected AbstractImageRegistry(Plugin plugin) {
fBaseUrl = plugin.getBundle().getEntry("/"); //$NON-NLS-1$
}
/**
* Defines the key for a local image, that must be found below the icons directory
* in the plugin.
* @param key Key by which the image can be referred by.
* @param dir Directory relative to icons/
* @param name The name of the file defining the icon. The name will be used as
* key.
*/
protected void localImage(String key, String dir, String name) {
if (dir== null || dir.equals(""))//$NON-NLS-1$
fLocations.put(key, new String[] {"icons/" + name}); //$NON-NLS-1$
else
fLocations.put(key, new String[] {"icons/" + dir + "/" + name}); //$NON-NLS-1$ //$NON-NLS-2$
}
/**
* Defines the key for a non-local image, that must be found below the icons directory
* of some plugin.
* @param key Key by which the image can be referred by.
* @param plugin The plugin id, where the icon is searched.
* @param dirs A couple of directories below icons/ in the plugin. If loading fails,
* the next dir will be taken as fallback.
* @param name The name of the file defining the icon. The name will be used as
* key.
*/
protected void externalImage(String key, String plugin, String[] dirs, String name) {
if (plugin != null) {
fPlugins.put(key, plugin);
}
String[] locations = new String[dirs.length];
for (int i = 0; i < dirs.length; i++) {
String dir = dirs[i];
if (dir== null || dir.equals(""))//$NON-NLS-1$
locations[i] = "icons/" + name; //$NON-NLS-1$
else
locations[i] = "icons/" + dir + "/" + name; //$NON-NLS-1$ //$NON-NLS-2$
}
fLocations.put(key, locations);
}
// overrider
@Override
final public Image get(String key) {
Image i = super.get(key);
if (i != null) {
return i;
}
ImageDescriptor d = createFileImageDescriptor(key);
if (d != null) {
put(key, d);
return super.get(key);
}
return null;
}
// overrider
@Override
final public ImageDescriptor getDescriptor(String key) {
ImageDescriptor d = super.getDescriptor(key);
if (d != null) {
return d;
}
d = createFileImageDescriptor(key);
if (d != null) {
put(key, d);
return d;
}
return null;
}
private ImageDescriptor createFileImageDescriptor(String key) {
URL url = fBaseUrl;
String pluginId = fPlugins.get(key);
if (pluginId != null) {
Bundle bundle= Platform.getBundle(pluginId);
if (bundle != null) {
url = bundle.getEntry("/"); //$NON-NLS-1$
}
}
String[] locations= fLocations.get(key);
if (locations != null) {
for (int i = 0; i < locations.length; i++) {
String loc = locations[i];
URL full;
try {
full = new URL(url, loc);
ImageDescriptor candidate = ImageDescriptor.createFromURL(full);
if (candidate != null && candidate.getImageData() != null) {
return candidate;
}
} catch (MalformedURLException e) {
GdbUIPlugin.getDefault().getLog().log(new Status(IStatus.ERROR, GdbUIPlugin.PLUGIN_ID, "Malformed Icon URL", e)); //$NON-NLS-1$
} catch (SWTException e) {
// try the next one.
}
}
}
return null;
}
}

View file

@ -0,0 +1,511 @@
/*******************************************************************************
* Copyright (c) 2010 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
*******************************************************************************/
package org.eclipse.cdt.dsf.gdb.internal.ui.tracepoints;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.RejectedExecutionException;
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.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.service.IGDBTraceControl;
import org.eclipse.cdt.dsf.gdb.service.IGDBTraceControl.ITraceStatusDMData;
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.service.DsfServiceEventHandler;
import org.eclipse.cdt.dsf.service.DsfServicesTracker;
import org.eclipse.cdt.dsf.service.DsfSession;
import org.eclipse.cdt.dsf.service.DsfSession.SessionEndedListener;
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.IDebugUIConstants;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IActionBars;
import org.eclipse.ui.IMemento;
import org.eclipse.ui.ISelectionListener;
import org.eclipse.ui.IViewPart;
import org.eclipse.ui.IViewSite;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.actions.ActionFactory;
import org.eclipse.ui.part.ViewPart;
/**
* TraceControlView Part
*
* This view is used to control Tracing.
*
* @since 2.1
*/
public class TraceControlView extends ViewPart implements IViewPart, SessionEndedListener {
private static final String EMPTY_STRING = ""; //$NON-NLS-1$
public class FailedTraceVariableCreationException extends Exception {
private static final long serialVersionUID = -3042693455630687285L;
FailedTraceVariableCreationException() {}
FailedTraceVariableCreationException(String errorMessage) {
super(errorMessage);
}
}
/**
* Action to refresh the content of the view.
*/
private final class ActionRefreshView extends Action {
public ActionRefreshView() {
setText(TracepointsMessages.TraceControlView_action_Refresh_label);
setImageDescriptor(TracepointImageRegistry.getImageDescriptor(TracepointImageRegistry.ICON_Refresh_enabled));
setDisabledImageDescriptor(TracepointImageRegistry.getImageDescriptor(TracepointImageRegistry.ICON_Refresh_disabled));
}
@Override
public void run() {
updateContent();
}
}
private final class ActionOpenTraceVarDetails extends Action {
public ActionOpenTraceVarDetails() {
setText(TracepointsMessages.TraceControlView_action_trace_variable_details);
setImageDescriptor(TracepointImageRegistry.getImageDescriptor(TracepointImageRegistry.ICON_Trace_Variables));
}
@Override
public void run() {
Shell shell = Display.getDefault().getActiveShell();
TraceVarDetailsDialog dialog = new TraceVarDetailsDialog(shell, TraceControlView.this);
dialog.open();
}
}
private ISelectionListener fDebugViewListener = null;
private String fDebugSessionId = null;
private DsfServicesTracker fServicesTracker = null;
private volatile ITraceTargetDMContext fTargetContext = null;
private StyledText fStatusText = null;
protected Action fActionRefreshView = null;
protected Action fOpenTraceVarDetails = null;
private boolean fTracingSupported = false;
public TraceControlView() {
}
@Override
public void init(IViewSite site) throws PartInitException {
super.init(site);
site.getPage().addSelectionListener(IDebugUIConstants.ID_DEBUG_VIEW,
fDebugViewListener = new ISelectionListener() {
public void selectionChanged(IWorkbenchPart part, ISelection selection) {
updateDebugContext();
}});
}
@Override
public void init(IViewSite site, IMemento memento) throws PartInitException {
init(site);
}
@Override
public void createPartControl(Composite parent) {
Composite composite = new Composite(parent, SWT.NONE);
GridLayout layout = new GridLayout(1, false);
composite.setLayout(layout);
// Let's just create a place to put a text status for now.
// A fancier display would be nicer though
fStatusText = new StyledText(composite, SWT.MULTI);
GridData gd = new GridData(SWT.FILL, SWT.FILL, true, true);
fStatusText.setLayoutData(gd);
fStatusText.setEditable(false);
fStatusText.setCaret(null);
createActions();
if (fDebugSessionId != null) {
debugSessionChanged();
} else {
updateDebugContext();
}
DsfSession.addSessionEndedListener(this);
}
protected void createActions() {
IActionBars bars = getViewSite().getActionBars();
IToolBarManager manager = bars.getToolBarManager();
// Create the action to refresh the view
fActionRefreshView = new ActionRefreshView();
bars.setGlobalActionHandler(ActionFactory.REFRESH.getId(), fActionRefreshView);
manager.add(fActionRefreshView);
// Create the action to open the trace variable details
fOpenTraceVarDetails = new ActionOpenTraceVarDetails();
manager.add(fOpenTraceVarDetails);
bars.updateActionBars();
updateActionEnablement();
}
@Override
public void dispose() {
getSite().getPage().removeSelectionListener(fDebugViewListener);
setDebugContext(null);
super.dispose();
}
protected void updateContent() {
asyncExec(new Runnable() {
public void run() {
String content = ""; //$NON-NLS-1$
String status = retrieveStatus();
if (status != null && status.length() > 0) {
Calendar cal = Calendar.getInstance();
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss"); //$NON-NLS-1$
content = TracepointsMessages.TraceControlView_trace_view_content_updated_label +
sdf.format(cal.getTime()) + "\n" + status; //$NON-NLS-1$
}
fStatusText.setText(content);
updateActionEnablement();
}});
}
protected String retrieveStatus() {
if (fDebugSessionId == null) {
return EMPTY_STRING;
}
final ITraceTargetDMContext ctx = DMContexts.getAncestorOfType(fTargetContext, ITraceTargetDMContext.class);
if (ctx == null) {
return EMPTY_STRING;
}
Query<ITraceStatusDMData> query = new Query<ITraceStatusDMData>() {
@Override
protected void execute(DataRequestMonitor<ITraceStatusDMData> rm) {
final IGDBTraceControl traceControl = getService(IGDBTraceControl.class);
if (traceControl != null) {
traceControl.getTraceStatus(ctx, rm);
} else {
rm.setData(null);
rm.done();
}
}
};
try {
getSession().getExecutor().execute(query);
ITraceStatusDMData data = query.get();
if (data != null) {
fTracingSupported = data.isTracingSupported();
if (fTracingSupported) return data.toString();
} else {
fTracingSupported = false;
}
} catch (InterruptedException exc) {
} catch (ExecutionException exc) {
}
return EMPTY_STRING;
}
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 (fDebugSessionId != null && getSession() != null) {
try {
final DsfSession session = getSession();
session.getExecutor().execute(new DsfRunnable() {
public void run() {
session.removeServiceEventListener(TraceControlView.this);
}
});
} catch (RejectedExecutionException e) {
// Session is shut down.
}
}
fDebugSessionId = sessionId;
if (fServicesTracker != null) {
fServicesTracker.dispose();
}
fServicesTracker = new DsfServicesTracker(GdbUIPlugin.getBundleContext(), sessionId);
debugSessionChanged();
}
} else if (fDebugSessionId != null) {
if (getSession() != null) {
try {
final DsfSession session = getSession();
session.getExecutor().execute(new DsfRunnable() {
public void run() {
session.removeServiceEventListener(TraceControlView.this);
}
});
} catch (RejectedExecutionException e) {
// Session is shut down.
}
}
fDebugSessionId = null;
fTargetContext = null;
if (fServicesTracker != null) {
fServicesTracker.dispose();
fServicesTracker = null;
}
debugSessionChanged();
}
}
private void debugSessionChanged() {
// When dealing with a new debug session, assume tracing is not supported.
// updateContent() will fix it
fTracingSupported = false;
if (fDebugSessionId != null) {
try {
final DsfSession session = getSession();
session.getExecutor().execute(new DsfRunnable() {
public void run() {
session.addServiceEventListener(TraceControlView.this, null);
}
});
} catch (RejectedExecutionException e) {
// Session is shut down.
}
}
updateContent();
}
protected void updateActionEnablement() {
enableActions(fTracingSupported);
}
protected void enableActions(boolean enabled) {
fOpenTraceVarDetails.setEnabled(enabled);
fActionRefreshView.setEnabled(enabled);
}
private void asyncExec(Runnable runnable) {
if (fStatusText != null) {
fStatusText.getDisplay().asyncExec(runnable);
}
}
public void sessionEnded(DsfSession session) {
if (session.getId().equals(fDebugSessionId)) {
asyncExec(new Runnable() {
public void run() {
setDebugContext(null);
}});
}
}
/*
* 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();
}
/*
* 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();
}
@Override
public void setFocus() {
if (fStatusText != null) {
fStatusText.setFocus();
}
}
private DsfSession getSession() {
return DsfSession.getSession(fDebugSessionId);
}
private <V> V getService(Class<V> serviceClass) {
if (fServicesTracker != null) {
return fServicesTracker.getService(serviceClass);
}
return null;
}
/**
* Get the list of trace variables from the backend.
*
* @return null when the list cannot be obtained.
*/
public ITraceVariableDMData[] getTraceVarList() {
if (fDebugSessionId == null) {
return null;
}
final ITraceTargetDMContext ctx = DMContexts.getAncestorOfType(fTargetContext, ITraceTargetDMContext.class);
if (ctx == null) {
return null;
}
Query<ITraceVariableDMData[]> query = new Query<ITraceVariableDMData[]>() {
@Override
protected void execute(final DataRequestMonitor<ITraceVariableDMData[]> rm) {
final IGDBTraceControl traceControl = getService(IGDBTraceControl.class);
if (traceControl != null) {
traceControl.getTraceVariables(ctx,
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();
} catch (InterruptedException exc) {
} catch (ExecutionException exc) {
}
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.
*/
protected void createVariable(final String name, final String value) throws FailedTraceVariableCreationException {
if (fDebugSessionId == null) {
throw new FailedTraceVariableCreationException(TracepointsMessages.TraceControlView_create_variable_error);
}
final ITraceTargetDMContext ctx = DMContexts.getAncestorOfType(fTargetContext, ITraceTargetDMContext.class);
if (ctx == null) {
throw new FailedTraceVariableCreationException(TracepointsMessages.TraceControlView_create_variable_error);
}
Query<String> query = new Query<String>() {
@Override
protected void execute(final DataRequestMonitor<String> rm) {
final IGDBTraceControl traceControl = getService(IGDBTraceControl.class);
if (traceControl != null) {
traceControl.createTraceVariable(ctx, 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));
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));
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);
}
}
}

View file

@ -0,0 +1,311 @@
/*******************************************************************************
* Copyright (c) 2010 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 API and implementation
*******************************************************************************/
package org.eclipse.cdt.dsf.gdb.internal.ui.tracepoints;
import java.text.Collator;
import java.util.Locale;
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.IGDBTraceControl.ITraceVariableDMData;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.FocusListener;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.plugin.AbstractUIPlugin;
public final class TraceVarDetailsDialog extends Dialog {
private Button createButton = null;
private Button refreshButton = null;
private Table table = null;
private TraceControlView fView = null;
private Text nameInput = null;
private Text valueInput = null;
private Image warningImage = null;
private Label warningIconLabel = null;
private Label warningTextLabel = null;
public TraceVarDetailsDialog(Shell shell, TraceControlView view) {
super(shell);
setShellStyle(getShellStyle() | SWT.RESIZE | SWT.MAX);
fView = view;
}
@Override
protected Control createDialogArea(Composite parent) {
getShell().setText(TracepointsMessages.TraceControlView_trace_variable_details_dialog_title);
Composite composite = new Composite(parent, SWT.NONE);
GridLayout gridLayout = new GridLayout(1, false);
composite.setLayout(gridLayout);
composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
// Create the table to show the existing variables and their values
Composite tableComposite = new Composite(composite, SWT.NONE);
gridLayout = new GridLayout(1, false);
tableComposite.setLayout(gridLayout);
tableComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
table = new Table(tableComposite, SWT.BORDER | SWT.HIDE_SELECTION);
final GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, true);
gridData.heightHint = 6 * table.getItemHeight();
table.setLayoutData(gridData);
table.setLinesVisible(true);
table.setHeaderVisible(true);
final TableColumn nameTableColumn = new TableColumn(table, SWT.NONE);
nameTableColumn.setWidth(150);
nameTableColumn.setText(TracepointsMessages.TraceControlView_trace_variable_details_column_name);
nameTableColumn.setAlignment(SWT.LEFT);
final TableColumn initValTableColumn = new TableColumn(table, SWT.NONE);
initValTableColumn.setWidth(120);
initValTableColumn.setText(TracepointsMessages.TraceControlView_trace_variable_details_column_init_value);
initValTableColumn.setAlignment(SWT.RIGHT);
final TableColumn currentValTableColumn = new TableColumn(table, SWT.NONE);
currentValTableColumn.setWidth(120);
currentValTableColumn.setText(TracepointsMessages.TraceControlView_trace_variable_details_column_curr_value);
currentValTableColumn.setAlignment(SWT.RIGHT);
refreshButton = new Button(tableComposite, SWT.NONE);
refreshButton.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, true, false, 2, 1));
refreshButton.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
handleRefresh();
}
});
refreshButton.setText(TracepointsMessages.TraceControlView_trace_variable_details_refresh_button);
refreshButton.setEnabled(true);
Label separator = new Label(composite, SWT.SEPARATOR | SWT.HORIZONTAL);
separator.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
// Create the section to create a new variable
Composite createComposite = new Composite(composite, SWT.NONE);
gridLayout = new GridLayout(1, false);
createComposite.setLayout(gridLayout);
createComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
// Now a composite just for the input
Composite inputComposite = new Composite(createComposite, SWT.NONE);
gridLayout = new GridLayout(2, false);
gridLayout.marginWidth = 0;
gridLayout.marginHeight = 0;
inputComposite.setLayout(gridLayout);
inputComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
Label nameLabel = new Label(inputComposite, SWT.NONE);
nameLabel.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false));
nameLabel.setText(TracepointsMessages.TraceControlView_trace_variable_details_name_label);
nameInput = new Text(inputComposite, SWT.BORDER);
nameInput.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
Label valueLabel = new Label(inputComposite, SWT.NONE);
valueLabel.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false));
valueLabel.setText(TracepointsMessages.TraceControlView_trace_variable_details_value_label);
valueInput = new Text(inputComposite, SWT.BORDER);
valueInput.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
// And a composite for the create button and its warning icon and text
Composite createButtonComposite = new Composite(createComposite, SWT.NONE);
gridLayout = new GridLayout(3, false);
gridLayout.marginWidth = 0;
gridLayout.marginHeight = 0;
createButtonComposite.setLayout(gridLayout);
createButtonComposite.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
createButton = new Button(createButtonComposite, SWT.NONE);
createButton.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false));
createButton.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
handleCreate();
}
});
createButton.setText(TracepointsMessages.TraceControlView_trace_variable_details_create_button);
createButton.setEnabled(true);
warningIconLabel = new Label(createButtonComposite, SWT.NONE);
warningIconLabel.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false));
warningImage = AbstractUIPlugin
.imageDescriptorFromPlugin(
GdbUIPlugin.PLUGIN_ID, "icons/full/obj16/warning.gif").createImage(); //$NON-NLS-1$
warningIconLabel.setImage(warningImage);
warningIconLabel.setVisible(false);
warningTextLabel = new Label(createButtonComposite, SWT.NONE);
warningTextLabel.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
parent.addDisposeListener(new DisposeListener() {
public void widgetDisposed(DisposeEvent e) {
if (warningImage != null)
warningImage.dispose();
}
});
// When the user goes into either input field, then pressing return
// should try to create the command
FocusListener clearWarningFocusListener = new FocusListener() {
public void focusGained(FocusEvent e) {
getShell().setDefaultButton(createButton);
}
public void focusLost(FocusEvent e) {
}
};
nameInput.addFocusListener(clearWarningFocusListener);
valueInput.addFocusListener(clearWarningFocusListener);
// When the user modifies any entry in the input, we should clear any warning
ModifyListener clearWarningListener = new ModifyListener() {
public void modifyText(ModifyEvent e) {
setWarningVisible(false);
}
};
nameInput.addModifyListener(clearWarningListener);
valueInput.addModifyListener(clearWarningListener);
resetInputFields();
handleRefresh();
return composite;
}
/**
* Set the visibility of the warning. Should be set to true when there
* is a problem creating the specific variable; false otherwise
*
* @param visible
* True for visible, false for hidden.
*/
public void setWarningVisible(boolean visible) {
if (warningIconLabel == null)
return;
warningIconLabel.setVisible(visible);
if (visible == false) {
if (warningTextLabel != null) {
warningTextLabel.setText(""); //$NON-NLS-1$
}
}
}
/**
* Set the visibility of the warning icon to true and set its
* text to the parameter message.
*/
public void setWarningVisible(String message) {
if (warningIconLabel == null || warningTextLabel == null)
return;
warningTextLabel.setText(message);
warningIconLabel.setVisible(true);
nameInput.setFocus();
}
@Override
protected void createButtonsForButtonBar(Composite parent) {
// create Close button only
createButton(parent, IDialogConstants.CLOSE_ID, IDialogConstants.CLOSE_LABEL,
true);
}
@Override
protected void buttonPressed(int buttonId) {
if (IDialogConstants.CLOSE_ID == buttonId) {
close();
}
}
protected void handleRefresh() {
ITraceVariableDMData[] vars = fView.getTraceVarList();
table.removeAll();
for (ITraceVariableDMData var : vars) {
String currentVal = var.getValue();
if (currentVal == null) {
currentVal = ""; //$NON-NLS-1$
}
addTableItem(var.getName(), var.getInitialValue(), currentVal);
}
}
private void addTableItem(String name, String initVal, String currentVal) {
// Find where to insert the new element
int index = -1;
TableItem[] items = table.getItems();
Collator collator = Collator.getInstance(Locale.getDefault());
for (int i = 0; i < items.length; i++) {
String rowName = items[i].getText(0);
if (collator.compare(name, rowName) < 0) {
index = i;
break;
}
}
if (index == -1) {
index = items.length;
}
TableItem tableItem = new TableItem(table, SWT.NONE, index);
tableItem.setText(0, name);
tableItem.setText(1, initVal);
tableItem.setText(2, currentVal);
}
protected void resetInputFields() {
nameInput.setText(""); //$NON-NLS-1$
valueInput.setText("0"); //$NON-NLS-1$
}
protected void handleCreate() {
String name = nameInput.getText();
if (name != null && name.length() > 0) {
String value = valueInput.getText();
if (value != null && value.length() == 0) {
value = null; // No value specified
}
try {
fView.createVariable(name, value);
resetInputFields();
nameInput.setFocus();
handleRefresh();
} catch (FailedTraceVariableCreationException e) {
setWarningVisible(e.getMessage());
}
} else {
setWarningVisible(TracepointsMessages.TraceControlView_create_variable_empty_name_error);
}
}
}

View file

@ -0,0 +1,66 @@
/*******************************************************************************
* Copyright (c) 2010 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
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Wind River Systems - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.dsf.gdb.internal.ui.tracepoints;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.eclipse.cdt.dsf.gdb.internal.ui.GdbUIPlugin;
import org.eclipse.core.runtime.Plugin;
import org.eclipse.jface.resource.ImageDescriptor;
/**
* @since 2.1
*/
public class TracepointImageRegistry extends AbstractImageRegistry {
private static List<Object[]> fStore = new ArrayList<Object[]>();
private static String add(String plugin, String[] dirs, String name) {
String key = plugin+'/'+dirs[0]+'/'+name;
fStore.add(new Object[] {key, plugin, dirs, name});
return key;
}
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$
private static TracepointImageRegistry INSTANCE= new TracepointImageRegistry(GdbUIPlugin.getDefault());
TracepointImageRegistry(Plugin plugin) {
super(plugin);
initialize();
}
void initialize() {
for (Iterator<Object[]> iter = fStore.iterator(); iter.hasNext();) {
Object[] element = iter.next();
if (element.length == 2) {
String dir= (String) element[0];
String name= (String) element[1];
localImage(name, dir, name);
} else {
String key = (String) element[0];
String plugin= (String) element[1];
String[] dirs= (String[]) element[2];
String name= (String) element[3];
externalImage(key, plugin, dirs, name);
}
}
}
public static ImageDescriptor getImageDescriptor(String key) {
return INSTANCE.getDescriptor(key);
}
}

View file

@ -0,0 +1,45 @@
/*******************************************************************************
* Copyright (c) 2010 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
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Wind River Systems - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.dsf.gdb.internal.ui.tracepoints;
import org.eclipse.osgi.util.NLS;
/**
* @since 2.1
*/
public final class TracepointsMessages extends NLS {
private static final String BUNDLE_NAME = "org.eclipse.cdt.dsf.gdb.internal.ui.tracepoints.TracepointsMessages";//$NON-NLS-1$
private TracepointsMessages() {
// Do not instantiate
}
public static String TraceControlView_action_Refresh_label;
public static String TraceControlView_trace_view_content_updated_label;
public static String TraceControlView_action_trace_variable_details;
public static String TraceControlView_trace_variable_invalid_value;
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;
public static String TraceControlView_trace_variable_details_column_init_value;
public static String TraceControlView_trace_variable_details_column_curr_value;
public static String TraceControlView_trace_variable_details_refresh_button;
public static String TraceControlView_trace_variable_details_create_button;
public static String TraceControlView_trace_variable_details_name_label;
public static String TraceControlView_trace_variable_details_value_label;
public static String TraceControlView_create_variable_error;
public static String TraceControlView_create_variable_empty_name_error;
static {
NLS.initializeMessages(BUNDLE_NAME, TracepointsMessages.class);
}
}

View file

@ -0,0 +1,26 @@
##########################################################################
# Copyright (c) 2010 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
##########################################################################
TraceControlView_action_Refresh_label=Refresh
TraceControlView_trace_view_content_updated_label=Last updated at:
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
TraceControlView_trace_variable_details_column_init_value=Initial Value
TraceControlView_trace_variable_details_column_curr_value=Current Value
TraceControlView_trace_variable_details_refresh_button=Refresh
TraceControlView_trace_variable_details_create_button=Create
TraceControlView_trace_variable_details_name_label=Name:
TraceControlView_trace_variable_details_value_label=Value:
TraceControlView_create_variable_error=Error creating trace variable
TraceControlView_create_variable_empty_name_error=Cannot create variable with empty name

View file

@ -14,6 +14,7 @@ package org.eclipse.cdt.dsf.gdb.internal.ui.viewmodel.launch;
import java.util.concurrent.RejectedExecutionException;
import org.eclipse.cdt.dsf.concurrent.DsfRunnable;
import org.eclipse.cdt.dsf.concurrent.RequestMonitor;
import org.eclipse.cdt.dsf.concurrent.ThreadSafe;
import org.eclipse.cdt.dsf.debug.service.ICachingService;
import org.eclipse.cdt.dsf.debug.service.IProcesses;
@ -26,6 +27,9 @@ import org.eclipse.cdt.dsf.debug.ui.viewmodel.launch.LaunchRootVMNode;
import org.eclipse.cdt.dsf.debug.ui.viewmodel.launch.StackFramesVMNode;
import org.eclipse.cdt.dsf.debug.ui.viewmodel.launch.StandardProcessVMNode;
import org.eclipse.cdt.dsf.gdb.internal.ui.GdbUIPlugin;
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.service.DsfServicesTracker;
import org.eclipse.cdt.dsf.service.DsfSession;
import org.eclipse.cdt.dsf.ui.viewmodel.AbstractVMAdapter;
@ -70,8 +74,42 @@ public class LaunchVMProvider extends AbstractLaunchVMProvider
{
return false;
}
if (eventToSkip instanceof ITracingStartedDMEvent ||
eventToSkip instanceof ITracingStoppedDMEvent)
{
if (newEvent instanceof ITracingStartedDMEvent ||
newEvent instanceof ITracingStoppedDMEvent)
{
return true;
}
}
if (eventToSkip instanceof ITracingSupportedChangeDMEvent)
{
if (newEvent instanceof ITracingSupportedChangeDMEvent)
{
return true;
}
}
return super.canSkipHandlingEvent(newEvent, eventToSkip);
}
@Override
public void handleEvent(Object event, RequestMonitor rm) {
if (event instanceof ITracingStartedDMEvent ||
event instanceof ITracingStoppedDMEvent ||
event instanceof ITracingSupportedChangeDMEvent)
{
// Refresh the view to trigger a context change, which
// will cause command enablement to be refreshed
refresh();
rm.done();
return;
}
super.handleEvent(event, rm);
}
@Override
public void refresh() {

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2006, 2009 Wind River Systems and others.
* Copyright (c) 2010 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
@ -9,6 +9,7 @@
* Wind River Systems - initial API and implementation
* Nokia - created GDBBackend service. Sep. 2008
* IBM Corporation
* Ericsson - Support for Tracing Control service
*******************************************************************************/
package org.eclipse.cdt.dsf.gdb.launching;
@ -27,6 +28,7 @@ import org.eclipse.cdt.dsf.debug.service.ISourceLookup;
import org.eclipse.cdt.dsf.debug.service.IStack;
import org.eclipse.cdt.dsf.debug.service.ISourceLookup.ISourceLookupDMContext;
import org.eclipse.cdt.dsf.debug.service.command.ICommandControlService;
import org.eclipse.cdt.dsf.gdb.service.IGDBTraceControl;
import org.eclipse.cdt.dsf.mi.service.CSourceLookup;
import org.eclipse.cdt.dsf.mi.service.IMIBackend;
import org.eclipse.cdt.dsf.mi.service.IMIProcesses;
@ -111,6 +113,16 @@ public class ServicesLaunchSequence extends Sequence {
public void execute(RequestMonitor requestMonitor) {
fLaunch.getServiceFactory().createService(IDisassembly.class, fSession).initialize(requestMonitor);
}},
new Step() { @Override
public void execute(RequestMonitor requestMonitor) {
IGDBTraceControl traceService = fLaunch.getServiceFactory().createService(IGDBTraceControl.class, fSession, fLaunch.getLaunchConfiguration());
// Note that for older versions of GDB, we don't support tracing, so there is no trace service.
if (traceService != null) {
traceService.initialize(requestMonitor);
} else {
requestMonitor.done();
}
}},
};
DsfSession fSession;

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2006, 2008 Wind River Systems and others.
* Copyright (c) 2010 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
@ -11,7 +11,6 @@
package org.eclipse.cdt.dsf.gdb.launching;
import org.eclipse.cdt.dsf.concurrent.DsfExecutor;
import org.eclipse.cdt.dsf.concurrent.IDsfStatusConstants;
import org.eclipse.cdt.dsf.concurrent.RequestMonitor;
import org.eclipse.cdt.dsf.concurrent.Sequence;
import org.eclipse.cdt.dsf.debug.service.IBreakpoints;
@ -26,12 +25,11 @@ import org.eclipse.cdt.dsf.debug.service.ISourceLookup;
import org.eclipse.cdt.dsf.debug.service.IStack;
import org.eclipse.cdt.dsf.debug.service.command.ICommandControl;
import org.eclipse.cdt.dsf.gdb.internal.GdbPlugin;
import org.eclipse.cdt.dsf.gdb.service.IGDBTraceControl;
import org.eclipse.cdt.dsf.mi.service.IMIBackend;
import org.eclipse.cdt.dsf.mi.service.MIBreakpointsManager;
import org.eclipse.cdt.dsf.service.DsfServicesTracker;
import org.eclipse.cdt.dsf.service.IDsfService;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
public class ShutdownSequence extends Sequence {
@ -67,6 +65,11 @@ public class ShutdownSequence extends Sequence {
fTracker = null;
requestMonitor.done();
}
}, new Step() {
@Override
public void execute(RequestMonitor requestMonitor) {
shutdownService(IGDBTraceControl.class, requestMonitor);
}
}, new Step() {
@Override
public void execute(RequestMonitor requestMonitor) {
@ -155,8 +158,8 @@ public class ShutdownSequence extends Sequence {
}
});
} else {
requestMonitor.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, IDsfStatusConstants.INTERNAL_ERROR,
"Service '" + clazz.getName() + "' not found.", null)); //$NON-NLS-1$//$NON-NLS-2$
// It is possible that a particular service was not instantiated at all
// depending on our backend
requestMonitor.done();
}
}

View file

@ -0,0 +1,773 @@
/*******************************************************************************
* Copyright (c) 2010 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
*******************************************************************************/
package org.eclipse.cdt.dsf.gdb.service;
import java.util.Hashtable;
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
import org.eclipse.cdt.dsf.concurrent.RequestMonitor;
import org.eclipse.cdt.dsf.datamodel.AbstractDMEvent;
import org.eclipse.cdt.dsf.datamodel.IDMContext;
import org.eclipse.cdt.dsf.debug.service.ICachingService;
import org.eclipse.cdt.dsf.debug.service.command.CommandCache;
import org.eclipse.cdt.dsf.debug.service.command.ICommandControlService;
import org.eclipse.cdt.dsf.gdb.internal.GdbPlugin;
import org.eclipse.cdt.dsf.mi.service.command.commands.MITargetSelectTFile;
import org.eclipse.cdt.dsf.mi.service.command.commands.MITraceDefineVariable;
import org.eclipse.cdt.dsf.mi.service.command.commands.MITraceListVariables;
import org.eclipse.cdt.dsf.mi.service.command.commands.MITraceSave;
import org.eclipse.cdt.dsf.mi.service.command.commands.MITraceStart;
import org.eclipse.cdt.dsf.mi.service.command.commands.MITraceStatus;
import org.eclipse.cdt.dsf.mi.service.command.commands.MITraceStop;
import org.eclipse.cdt.dsf.mi.service.command.output.MIInfo;
import org.eclipse.cdt.dsf.mi.service.command.output.MITraceListVariablesInfo;
import org.eclipse.cdt.dsf.mi.service.command.output.MITraceStatusInfo;
import org.eclipse.cdt.dsf.mi.service.command.output.MITraceStopInfo;
import org.eclipse.cdt.dsf.mi.service.command.output.MITraceListVariablesInfo.MITraceVariableInfo;
import org.eclipse.cdt.dsf.service.AbstractDsfService;
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;
import org.osgi.framework.BundleContext;
/**
* This class implements the ITraceControl interface which gives access
* to the debugger's tracing functionality.
*
* @since 2.1
*/
public class GDBTraceControl_7_1 extends AbstractDsfService implements IGDBTraceControl, ICachingService {
// @Immutable
// private static final class MITraceRecordDMContext extends AbstractDMContext implements ITraceRecordDMContext {
//
// // The trace record reference
// private final int fReference;
//
// /**
// * @param session the DsfSession for this service
// * @param parents the parent contexts
// * @param reference the trace record reference
// */
// public MITraceRecordDMContext(DsfSession session, IDMContext[] parents, int reference) {
// super(session.getId(), parents);
// fReference = reference;
// }
//
// public int getReference() {
// return fReference;
// }
//
// /* (non-Javadoc)
// * @see org.eclipse.cdt.dsf.datamodel.AbstractDMContext#equals(java.lang.Object)
// */
// @Override
// public boolean equals(Object obj) {
// return baseEquals(obj) && (fReference == ((MITraceRecordDMContext) obj).fReference);
// }
//
// /* (non-Javadoc)
// * @see org.eclipse.cdt.dsf.datamodel.AbstractDMContext#hashCode()
// */
// @Override
// public int hashCode() {
// return baseHashCode() + fReference;
// }
//
// /* (non-Javadoc)
// * @see java.lang.Object#toString()
// */
// @Override
// public String toString() {
// return baseToString() + ".reference(" + fReference + ")"; //$NON-NLS-1$//$NON-NLS-2$
// }
// }
//
// /**
// * Trace record context used to indicate that there is no current trace record selected.
// */
// @Immutable
// private static final class InvalidTraceRecordDMContext extends AbstractDMContext implements ITraceRecordDMContext {
//
// /**
// * @param session the DsfSession for this service
// * @param parents the parent contexts
// * @param reference the trace record reference
// */
// public InvalidTraceRecordDMContext(DsfSession session, IDMContext[] parents) {
// super(session.getId(), parents);
// }
//
//
// /* (non-Javadoc)
// * @see org.eclipse.cdt.dsf.datamodel.AbstractDMContext#equals(java.lang.Object)
// */
// @Override
// public boolean equals(Object obj) {
// return baseEquals(obj);
// }
//
// /* (non-Javadoc)
// * @see org.eclipse.cdt.dsf.datamodel.AbstractDMContext#hashCode()
// */
// @Override
// public int hashCode() {
// return baseHashCode();
// }
//
// /* (non-Javadoc)
// * @see java.lang.Object#toString()
// */
// @Override
// public String toString() {
// return baseToString() + ".noTraceRecord"; //$NON-NLS-1$
// }
// }
//
// @Immutable
// private static class MITraceRecordDMData implements ITraceRecordDMData {
// private final String fData;
//
// public MITraceRecordDMData(String data) {
// fData = data;
// }
//
// public String getData() { return fData; }
// }
private class TraceVariableDMData implements ITraceVariableDMData {
private String fName;
private String fValue;
private String fInitialValue;
public TraceVariableDMData(String name, String value) {
this(name, value, null);
}
public TraceVariableDMData(String name, String initial, String value) {
fName = name;
fInitialValue = initial;
fValue = value;
}
public String getName() {
return fName;
}
public String getValue() {
return fValue;
}
public String getInitialValue() {
return fInitialValue;
}
}
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);
}
/**
* Create a status when tracing is not supported
*/
public TraceStatusDMData() {
this(false, 0, 0, 0);
fTracingSupported = false;
}
public int getFreeBufferSize() {
return fFreeBufferSize;
}
public int getNumberOfCollectedFrame() {
return fNumberOfCollectedFrames;
}
public int getTotalBufferSize() {
return fTotalBufferSize;
}
public boolean isTracingActive() {
return fTracingActive;
}
public boolean isTracingSupported() {
return fTracingSupported;
}
public STOP_REASON_ENUM getStopReason() {
return fStopReason;
}
public Integer getStoppingTracepoint() {
if (fStopReason == null) {
return null;
}
return fStoppingTracepoint;
}
@SuppressWarnings("nls")
@Override
public String toString() {
String str = "\n";
if (!fTracingSupported) {
return "\nTracing is not supported\n";
}
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";
}
}
return str;
}
}
private static class TracingSupportedChangeEvent extends AbstractDMEvent<ITraceTargetDMContext>
implements ITracingSupportedChangeDMEvent {
private final boolean fTracingSupported;
public TracingSupportedChangeEvent(ITraceTargetDMContext context, boolean supported) {
super(context);
fTracingSupported = supported;
}
public boolean isTracingSupported() {
return fTracingSupported;
}
}
private static class TracingStartedEvent extends AbstractDMEvent<ITraceTargetDMContext>
implements ITracingStartedDMEvent {
public TracingStartedEvent(ITraceTargetDMContext context) {
super(context);
}
}
private static class TracingStoppedEvent extends AbstractDMEvent<ITraceTargetDMContext>
implements ITracingStoppedDMEvent {
public TracingStoppedEvent(ITraceTargetDMContext context) {
super(context);
}
}
// private static class TraceRecordSelectedChangedEvent extends AbstractDMEvent<ITraceRecordDMContext>
// implements ITraceRecordSelectedChangedDMEvent {
// public TraceRecordSelectedChangedEvent(ITraceRecordDMContext context) {
// super(context);
// }
// }
private CommandCache fTraceCache;
private ICommandControlService fConnection;
// private ITraceRecordDMContext fCurrentRecordDmc = null;
private boolean fIsTracingActive = false;
private boolean fIsTracingSupported = false;
private int fTraceRecordsStored = 0;
public GDBTraceControl_7_1(DsfSession session, ILaunchConfiguration config) {
super(session);
}
/**
* This method initializes this service.
*
* @param requestMonitor
* The request monitor indicating the operation is finished
*/
@Override
public void initialize(final RequestMonitor requestMonitor) {
super.initialize(new RequestMonitor(getExecutor(), requestMonitor) {
@Override
protected void handleSuccess() {
doInitialize(requestMonitor);
}
});
}
/**
* This method initializes this service after our superclass's initialize()
* method succeeds.
*
* @param requestMonitor
* The call-back object to notify when this service's
* initialization is done.
*/
private void doInitialize(RequestMonitor requestMonitor) {
// Register to receive service events for this session.
// getSession().addServiceEventListener(this, null);
// Register this service.
register(new String[] {IGDBTraceControl.class.getName()},
new Hashtable<String, String>());
fConnection = getServicesTracker().getService(ICommandControlService.class);
fTraceCache = new CommandCache(getSession(), fConnection);
fTraceCache.setContextAvailable(fConnection.getContext(), true);
requestMonitor.done();
}
/**
* This method shuts down this service. It unregisters the service, stops
* receiving service events, and calls the superclass shutdown() method to
* finish the shutdown process.
*
* @return void
*/
@Override
public void shutdown(RequestMonitor requestMonitor) {
unregister();
// getSession().removeServiceEventListener(this);
super.shutdown(requestMonitor);
}
/**
* @return The bundle context of the plug-in to which this service belongs.
*/
@Override
protected BundleContext getBundleContext() {
return GdbPlugin.getBundleContext();
}
public void canStartTracing(ITraceTargetDMContext context, final DataRequestMonitor<Boolean> rm) {
if (context == null) {
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INVALID_STATE, "Invalid context", null)); //$NON-NLS-1$
rm.done();
return;
}
rm.setData(fIsTracingSupported);
rm.done();
}
public void startTracing(final ITraceTargetDMContext context, final RequestMonitor rm) {
if (context == null) {
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INVALID_STATE, "Invalid context", null)); //$NON-NLS-1$
rm.done();
return;
}
canStartTracing(context, new DataRequestMonitor<Boolean>(getExecutor(), rm) {
@Override
protected void handleSuccess() {
if (!getData()) {
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INVALID_STATE, "Cannot start tracing", null)); //$NON-NLS-1$
rm.done();
return;
}
fConnection.queueCommand(
new MITraceStart(context),
new DataRequestMonitor<MIInfo>(getExecutor(), rm) {
@Override
protected void handleSuccess() {
fIsTracingActive = true;
getSession().dispatchEvent(new TracingStartedEvent(context), getProperties());
rm.done();
}
});
}
});
}
public void canStopTracing(ITraceTargetDMContext context, DataRequestMonitor<Boolean> rm) {
if (context == null) {
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INVALID_STATE, "Invalid context", null)); //$NON-NLS-1$
rm.done();
return;
}
isTracing(context, rm);
}
public void stopTracing(final ITraceTargetDMContext context, final RequestMonitor rm) {
if (context == null) {
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INVALID_STATE, "Invalid context", null)); //$NON-NLS-1$
rm.done();
return;
}
canStopTracing(context, new DataRequestMonitor<Boolean>(getExecutor(), rm) {
@Override
protected void handleSuccess() {
if (!getData()) {
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INVALID_STATE, "Cannot stop tracing", null)); //$NON-NLS-1$
rm.done();
return;
}
fConnection.queueCommand(
new MITraceStop(context),
new DataRequestMonitor<MITraceStopInfo>(getExecutor(), rm) {
@Override
protected void handleSuccess() {
MITraceStopInfo info = getData();
// Update the tracing state in case it was stopped by the backend
if (fIsTracingActive != info.isTracingActive()) {
fIsTracingActive = info.isTracingActive();
if (!fIsTracingActive) {
getSession().dispatchEvent(new TracingStoppedEvent(context), getProperties());
}
}
fTraceRecordsStored = info.getNumberOfCollectedFrame();
rm.done();
}
});
}
});
}
public void isTracing(ITraceTargetDMContext context, final DataRequestMonitor<Boolean> rm) {
if (context == null) {
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INVALID_STATE, "Invalid context", null)); //$NON-NLS-1$
rm.done();
return;
}
// Although tracing can be automatically stopped on the target, we
// don't go to the backend for this call, or we would make too many calls
// Instead, we can use our buffered state; we simply won't know about an
// automatic stop until a forced refresh. (Note that the MI notification
// about automatic stops, is not available until GDB 7.1 is released)
rm.setData(fIsTracingActive);
rm.done();
}
public void canSaveTraceData(ITraceTargetDMContext context, DataRequestMonitor<Boolean> rm) {
if (context == null) {
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INVALID_STATE, "Invalid context", null)); //$NON-NLS-1$
rm.done();
return;
}
rm.setData(fTraceRecordsStored > 0);
rm.done();
}
public void saveTraceData(ITraceTargetDMContext context, String file, boolean remoteSave, RequestMonitor rm) {
if (context == null) {
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INVALID_STATE, "Invalid context", null)); //$NON-NLS-1$
rm.done();
return;
}
fConnection.queueCommand(
new MITraceSave(context, file, remoteSave),
new DataRequestMonitor<MIInfo>(getExecutor(), rm));
}
public void canLoadTraceData(ITraceTargetDMContext context, DataRequestMonitor<Boolean> rm) {
if (context == null) {
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INVALID_STATE, "Invalid context", null)); //$NON-NLS-1$
rm.done();
return;
}
rm.setData(true);
rm.done();
}
public void loadTraceData(ITraceTargetDMContext context, String file, RequestMonitor rm) {
if (context == null) {
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INVALID_STATE, "Invalid context", null)); //$NON-NLS-1$
rm.done();
return;
}
fConnection.queueCommand(
new MITargetSelectTFile(context, file),
new DataRequestMonitor<MIInfo>(getExecutor(), rm));
}
public void getTraceStatus(final ITraceTargetDMContext context, final DataRequestMonitor<ITraceStatusDMData> rm) {
if (context == null) {
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INVALID_STATE, "Invalid context", null)); //$NON-NLS-1$
rm.done();
return;
}
fConnection.queueCommand(
new MITraceStatus(context),
new DataRequestMonitor<MITraceStatusInfo>(getExecutor(), rm) {
@Override
protected void handleSuccess() {
MITraceStatusInfo info = getData();
if (fIsTracingSupported != info.isTracingSupported()) {
fIsTracingSupported = info.isTracingSupported();
getSession().dispatchEvent(new TracingSupportedChangeEvent(context, fIsTracingSupported), getProperties());
}
if (fIsTracingSupported) {
// Update the tracing state in case it was stopped by the backend
if (fIsTracingActive != info.isTracingActive()) {
fIsTracingActive = info.isTracingActive();
if (fIsTracingActive) {
getSession().dispatchEvent(new TracingStartedEvent(context), getProperties());
} else {
getSession().dispatchEvent(new TracingStoppedEvent(context), getProperties());
}
}
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()));
}
} else {
fTraceRecordsStored = 0;
fIsTracingActive = false;
rm.setData(new TraceStatusDMData());
}
rm.done();
}
});
}
public void createTraceVariable(ITraceTargetDMContext context,
String varName,
String varValue,
RequestMonitor rm) {
if (context == null) {
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INVALID_STATE, "Invalid context", null)); //$NON-NLS-1$
rm.done();
return;
}
if (varValue == null) {
fConnection.queueCommand(
new MITraceDefineVariable(context, varName),
new DataRequestMonitor<MIInfo>(getExecutor(), rm));
} else {
fConnection.queueCommand(
new MITraceDefineVariable(context, varName, varValue),
new DataRequestMonitor<MIInfo>(getExecutor(), rm));
}
}
public void getTraceVariables(ITraceTargetDMContext context, final DataRequestMonitor<ITraceVariableDMData[]> rm) {
if (context == null) {
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INVALID_STATE, "Invalid context", null)); //$NON-NLS-1$
rm.done();
return;
}
// It may be possible to cache this call, if we can figure out that all the cases
// where to data can change, to clear the cache in those cases
fConnection.queueCommand(
new MITraceListVariables(context),
new DataRequestMonitor<MITraceListVariablesInfo>(getExecutor(), rm) {
@Override
protected void handleSuccess() {
MITraceVariableInfo[] vars = getData().getTraceVariables();
TraceVariableDMData[] varDataArray = new TraceVariableDMData[vars.length];
for (int i = 0; i < vars.length; i++) {
varDataArray[i] = new TraceVariableDMData(vars[i].getName(),
vars[i].getInitialValue(),
vars[i].getCurrentValue());
}
rm.setData(varDataArray);
rm.done();
}
});
}
//
// /**
// * Create a trace record context
// */
// public ITraceRecordDMContext createTraceRecordContext(IDMContext ctx, int index) {
// return new MITraceRecordDMContext(getSession(), new IDMContext[] { ctx }, index);
// }
//
// public ITraceRecordDMContext createNextRecordContext(ITraceRecordDMContext ctx) {
// if (ctx instanceof InvalidTraceRecordDMContext) {
// // No specified context, so we return the first record context
// return new MITraceRecordDMContext(getSession(), new IDMContext[] { ctx }, 0);
// }
// if (ctx instanceof MITraceRecordDMContext) {
// return new MITraceRecordDMContext(getSession(),
// ctx.getParents(),
// ((MITraceRecordDMContext)ctx).getReference() + 1);
// }
// return null;
// }
//
// public ITraceRecordDMContext createPrevRecordContext(ITraceRecordDMContext ctx) {
// if (ctx instanceof MITraceRecordDMContext) {
// return new MITraceRecordDMContext(getSession(),
// ctx.getParents(),
// ((MITraceRecordDMContext)ctx).getReference() - 1);
// }
// return null;
// }
//
//
// public void getCurrentTraceRecordContext(ITraceTargetDMContext context, DataRequestMonitor<ITraceRecordDMContext> drm) {
// if (fCurrentRecordDmc == null) {
// drm.setData(new InvalidTraceRecordDMContext(getSession(), new IDMContext[] { context }));
// } else {
// drm.setData(fCurrentRecordDmc);
// }
// drm.done();
// }
//
// public void selectTraceRecord(final ITraceRecordDMContext context, final RequestMonitor rm) {
// if (context instanceof MITraceRecordDMContext) {
// ITraceTargetDMContext targetDmc = DMContexts.getAncestorOfType(context, ITraceTargetDMContext.class);
// fConnection.queueCommand(
// new MITraceFind(targetDmc, ((MITraceRecordDMContext)context).getReference()),
// new DataRequestMonitor<MITraceFindInfo>(getExecutor(), rm) {
// @Override
// protected void handleSuccess() {
// if (getData().isFound() == false) {
// rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INTERNAL_ERROR, "Could not find trace record", null)); //$NON-NLS-1$
// } else {
// fCurrentRecordDmc = context;
// getSession().dispatchEvent(new TraceRecordSelectedChangedEvent(context), getProperties());
// }
// rm.done();
// }
// });
// } else {
// rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INTERNAL_ERROR, "Invalid trace record context.", null)); //$NON-NLS-1$
// rm.done();
// }
// }
//
// public void setDefaultCollect(ITraceTargetDMContext context, String[] expressions, RequestMonitor rm) {
// fConnection.queueCommand(
// new MIGDBSetDefaultCollect(context, expressions),
// new DataRequestMonitor<MIInfo>(getExecutor(), rm));
// }
//
// public void getDefaultCollect(ITraceTargetDMContext context, final DataRequestMonitor<String> rm) {
// // should use a cache and have it reset in setDefaultCommands
// fConnection.queueCommand(
// new MIGDBShowDefaultCollect(context),
// new DataRequestMonitor<MIGDBShowInfo>(getExecutor(), rm) {
// @Override
// protected void handleSuccess() {
// rm.setData(getData().getValue());
// rm.done();
// }
// });
// }
//
//
// public void getTraceRecordData(ITraceRecordDMContext context,
// DataRequestMonitor<ITraceRecordDMData> rm) {
// assert false;
// }
//
// public void saveTracepoints(ITraceTargetDMContext context,
// String file,
// RequestMonitor rm) {
// assert false;
// }
//
// public void loadTracepoints(ITraceTargetDMContext context,
// String file,
// RequestMonitor rm) {
// assert false;
// }
//
// public void saveTraceData(ITraceTargetDMContext context,
// String file,
// RequestMonitor rm) {
// assert false;
// }
//
// public void loadTraceData(ITraceTargetDMContext context,
// String file,
// RequestMonitor rm) {
// assert false;
// }
//
// public void createTraceVariable(IExecutionDMContext context,
// RequestMonitor rm) {
// assert false;
// }
public void flushCache(IDMContext context) {
fTraceCache.reset(context);
}
}

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2008 Ericsson and others.
* Copyright (c) 2010 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
@ -27,11 +27,11 @@ import org.eclipse.cdt.dsf.debug.service.command.ICommandControl;
import org.eclipse.cdt.dsf.gdb.service.command.GDBControl;
import org.eclipse.cdt.dsf.gdb.service.command.GDBControl_7_0;
import org.eclipse.cdt.dsf.mi.service.CSourceLookup;
import org.eclipse.cdt.dsf.mi.service.MIExpressions;
import org.eclipse.cdt.dsf.mi.service.IMIBackend;
import org.eclipse.cdt.dsf.mi.service.MIBreakpoints;
import org.eclipse.cdt.dsf.mi.service.MIBreakpointsManager;
import org.eclipse.cdt.dsf.mi.service.MIDisassembly;
import org.eclipse.cdt.dsf.mi.service.MIExpressions;
import org.eclipse.cdt.dsf.mi.service.MIMemory;
import org.eclipse.cdt.dsf.mi.service.MIModules;
import org.eclipse.cdt.dsf.mi.service.MIRegisters;
@ -71,9 +71,14 @@ public class GdbDebugServicesFactory extends AbstractDsfDebugServicesFactory {
return (V)createBackendGDBService(session, (ILaunchConfiguration)arg);
}
}
} else if (IGDBTraceControl.class.isAssignableFrom(clazz)) {
for (Object arg : optionalArguments) {
if (arg instanceof ILaunchConfiguration) {
return (V)createTraceControlService(session, (ILaunchConfiguration)arg);
}
}
}
return super.createService(clazz, session);
}
@ -154,4 +159,15 @@ public class GdbDebugServicesFactory extends AbstractDsfDebugServicesFactory {
protected IStack createStackService(DsfSession session) {
return new MIStack(session);
}
/** @since 2.1 */
protected IGDBTraceControl createTraceControlService(DsfSession session, ILaunchConfiguration config) {
// This service is available for GDB 7.1. But until that GDB is itself available
// there is a pre-release that has a version of 6.8.50.20090414
if ("6.8.50.20090414".compareTo(fVersion) <= 0) {
return new GDBTraceControl_7_1(session, config);
}
// There is no implementation of the TraceControl service before GDB 7.1
return null;
}
}

View file

@ -0,0 +1,190 @@
/*******************************************************************************
* Copyright (c) 2010 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
*******************************************************************************/
package org.eclipse.cdt.dsf.gdb.service;
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
import org.eclipse.cdt.dsf.concurrent.Immutable;
import org.eclipse.cdt.dsf.concurrent.RequestMonitor;
import org.eclipse.cdt.dsf.datamodel.IDMContext;
import org.eclipse.cdt.dsf.datamodel.IDMData;
import org.eclipse.cdt.dsf.datamodel.IDMEvent;
import org.eclipse.cdt.dsf.service.IDsfService;
/**
* The TraceControl service provides access to the debugger Tracing functionality.
* It is used to do such things as start and stop tracing.
*
* @since 2.1
*/
public interface IGDBTraceControl extends IDsfService {
/**
* Marker interface for a context on which trace operations can be performed
*/
public interface ITraceTargetDMContext extends IDMContext {}
/**
* Specific Trace Record context. It describes tracing data.
*/
@Immutable
public interface ITraceRecordDMContext extends IDMContext {}
/**
* 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 {
}
/**
* Trace events
*/
public interface ITracingSupportedChangeDMEvent extends IDMEvent<ITraceTargetDMContext> {
boolean isTracingSupported();
}
public interface ITracingStartedDMEvent extends IDMEvent<ITraceTargetDMContext> {}
public interface ITracingStoppedDMEvent extends IDMEvent<ITraceTargetDMContext> {}
public interface ITraceRecordSelectedChangedDMEvent extends IDMEvent<ITraceRecordDMContext> {}
/**
* Returns whether tracing can be started on the specified trace target
*/
public void canStartTracing(ITraceTargetDMContext context, DataRequestMonitor<Boolean> rm);
/**
* Start tracing on the specified trace target
*/
public void startTracing(ITraceTargetDMContext context, RequestMonitor rm);
/**
* Returns whether tracing can be stopped on the specified trace target
*/
public void canStopTracing(ITraceTargetDMContext context, DataRequestMonitor<Boolean> rm);
/**
* Stop tracing on the specified trace target
*/
public void stopTracing(ITraceTargetDMContext context, RequestMonitor rm);
/**
* Returns true if tracing is ongoing.
*/
public void isTracing(ITraceTargetDMContext context, DataRequestMonitor<Boolean> rm);
/**
* Returns true if trace data can be saved to file
*/
public void canSaveTraceData(ITraceTargetDMContext context, DataRequestMonitor<Boolean> rm);
/**
* Save trace data (all trace records) to the specified file in a format suitable for {@link loadTraceData}
* If 'remoteSave' is true, the storage will be done on the target.
*/
public void saveTraceData(ITraceTargetDMContext context,
String file, boolean remoteSave,
RequestMonitor rm);
/**
* Returns true if trace data can be loaded from a file
*/
public void canLoadTraceData(ITraceTargetDMContext context, DataRequestMonitor<Boolean> rm);
/**
* Load trace data (all trace records) from the specified file. A file created from a call to
* {@link saveTraceData} should have the correct format to be loaded by this call.
*/
public void loadTraceData(ITraceTargetDMContext context,
String file,
RequestMonitor rm);
// /**
// * Request that the backend use the specified trace record.
// */
// public void selectTraceRecord(ITraceRecordDMContext context, RequestMonitor rm);
// /**
// * Returns the trace record data of the specified trace record.
// */
// public void getTraceRecordData(ITraceRecordDMContext context,
// DataRequestMonitor<ITraceRecordDMData> rm);
//
// /**
// * Save all tracepoint definitions to the specified file in a
// * format suitable for {@link loadTracepoints}.
// */
// // This should probably be part of the GDB Breakpoints service
// public void saveTracepoints(ITraceTargetDMContext context,
// String file,
// RequestMonitor rm);
//
// /**
// * Load all tracepoint definitions from the specified file.
// * A file created from a call to {@link saveTracepoints} should have
// * the correct format to be loaded by this call.
// */
// // This should probably be part of the GDB Breakpoints service
// public void loadTracepoints(ITraceTargetDMContext context,
// String file,
// RequestMonitor rm);
//
/////////////////////////////////////////////////
// GDB specific part
/////////////////////////////////////////////////
public static enum STOP_REASON_ENUM { REQUEST, PASSCOUNT, OVERFLOW, DISCONNECTION, ERROR, UNKNOWN };
public interface ITraceStatusDMData extends IDMData {
boolean isTracingSupported();
boolean isTracingActive();
int getNumberOfCollectedFrame();
int getTotalBufferSize();
int getFreeBufferSize();
STOP_REASON_ENUM getStopReason();
/**
* Returns the id of the tracepoint that caused the stop.
* Should be null if getStopReason is null
*/
Integer getStoppingTracepoint();
}
public interface ITraceVariableDMData extends IDMData {
String getName();
String getValue();
String getInitialValue();
}
/**
* Request the tracing status of the specified trace target
*/
public void getTraceStatus(ITraceTargetDMContext context, DataRequestMonitor<ITraceStatusDMData> rm);
/**
* Create a new trace state variable with an optional value
*/
public void createTraceVariable(ITraceTargetDMContext context,
String varName,
String varValue,
RequestMonitor rm);
/**
* Get a list of all trace state variables and their values
*/
public void getTraceVariables(ITraceTargetDMContext context, DataRequestMonitor<ITraceVariableDMData[]> rm);
// public ITraceRecordDMContext createTraceRecordContext(IDMContext ctx, int index);
// public void getCurrentTraceRecordContext(ITraceTargetDMContext context, DataRequestMonitor<ITraceRecordDMContext> drm);
// public ITraceRecordDMContext createNextRecordContext(ITraceRecordDMContext ctx);
// public ITraceRecordDMContext createPrevRecordContext(ITraceRecordDMContext ctx);
//
// public void setDefaultCollect(ITraceTargetDMContext context, String[] expressions, RequestMonitor rm);
// public void getDefaultCollect(ITraceTargetDMContext context, DataRequestMonitor<String> rm);
}

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2007, 2008 Wind River Systems and others.
* Copyright (c) 2010 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
@ -15,6 +15,7 @@ import org.eclipse.cdt.dsf.debug.service.IDisassembly.IDisassemblyDMContext;
import org.eclipse.cdt.dsf.debug.service.IModules.ISymbolDMContext;
import org.eclipse.cdt.dsf.debug.service.ISignals.ISignalsDMContext;
import org.eclipse.cdt.dsf.debug.service.ISourceLookup.ISourceLookupDMContext;
import org.eclipse.cdt.dsf.gdb.service.IGDBTraceControl.ITraceTargetDMContext;
import org.eclipse.cdt.dsf.mi.service.command.MIControlDMContext;
/**
@ -22,7 +23,7 @@ import org.eclipse.cdt.dsf.mi.service.command.MIControlDMContext;
*/
public class GDBControlDMContext extends MIControlDMContext
implements ISymbolDMContext, IBreakpointsTargetDMContext, ISourceLookupDMContext,
ISignalsDMContext, IDisassemblyDMContext
ISignalsDMContext, IDisassemblyDMContext, ITraceTargetDMContext
{
public GDBControlDMContext(String sessionId, String commandControlId) {

View file

@ -704,6 +704,57 @@ public abstract class AbstractMIControl extends AbstractDsfService
return clientMsg.toString();
}
private String getBackendMessage(MIOutput response) {
// Attempt to extract a message from the result record:
String message = null;
String[] parameters = null;
if (response != null && response.getMIResultRecord() != null) {
MIResult[] results = response.getMIResultRecord().getMIResults();
// Extract the parameters
MIResult paramsRes = findResultRecord(results, "parameters"); //$NON-NLS-1$
if (paramsRes != null && paramsRes.getMIValue() instanceof MIList) {
MIValue[] paramValues = ((MIList)paramsRes.getMIValue()).getMIValues();
parameters = new String[paramValues.length];
for (int i = 0; i < paramValues.length; i++) {
if (paramValues[i] instanceof MIConst) {
parameters[i] = ((MIConst)paramValues[i]).getString();
} else {
parameters[i] = ""; //$NON-NLS-1$
}
}
}
MIResult messageRes = findResultRecord(results, "message"); //$NON-NLS-1$
if (messageRes != null && messageRes.getMIValue() instanceof MIConst) {
message = ((MIConst)messageRes.getMIValue()).getString();
}
// FRCH: I believe that the actual string is "msg" ...
// FRCH: (at least for the version of gdb I'm using)
else {
messageRes = findResultRecord(results, "msg"); //$NON-NLS-1$
if (messageRes != null && messageRes.getMIValue() instanceof MIConst) {
message = ((MIConst)messageRes.getMIValue()).getString();
}
}
}
StringBuilder clientMsg = new StringBuilder();
if (message != null) {
if (parameters != null) {
try {
clientMsg.append(MessageFormat.format(message, parameters));
} catch(IllegalArgumentException e2) {
// Message format string invalid. Fallback to just appending the strings.
clientMsg.append(message);
clientMsg.append(parameters);
}
} else {
clientMsg.append(message);
}
}
return clientMsg.toString();
}
void processMIOutput(String line) {
MIParser.RecordType recordType = fMiParser.getRecordType(line);
@ -740,7 +791,9 @@ public abstract class AbstractMIControl extends AbstractDsfService
if ( errorResult.equals(MIResultRecord.ERROR) ) {
String status = getStatusString(commandHandle.getCommand(),response);
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, REQUEST_FAILED, status, null));
String message = getBackendMessage(response);
Exception exception = new Exception(message);
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, REQUEST_FAILED, status, exception));
}
/*

View file

@ -0,0 +1,27 @@
/*******************************************************************************
* Copyright (c) 2010 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
*******************************************************************************/
package org.eclipse.cdt.dsf.mi.service.command.commands;
import org.eclipse.cdt.dsf.datamodel.IDMContext;
/**
* This command sets up a connection with a trace data file.
*
* Available with GDB 7.1
*
* @since 2.1
*/
public class MITargetSelectTFile extends MITargetSelect {
public MITargetSelectTFile(IDMContext ctx, String traceFilePath) {
super(ctx, new String[] { "tfile", traceFilePath}); //$NON-NLS-1$
}
}

View file

@ -0,0 +1,36 @@
/*******************************************************************************
* Copyright (c) 2010 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
*******************************************************************************/
package org.eclipse.cdt.dsf.mi.service.command.commands;
import org.eclipse.cdt.dsf.gdb.service.IGDBTraceControl.ITraceTargetDMContext;
import org.eclipse.cdt.dsf.mi.service.command.output.MIInfo;
/**
* -trace-define-variable
*
* Creates trace variable name if it does not exist. If value is specified,
* sets the initial value of the specified trace variable to that value.
* Note that the name should start with the `$' character.
*
* Available with GDB 7.1
*
* @since 2.1
*/
public class MITraceDefineVariable extends MICommand<MIInfo> {
public MITraceDefineVariable(ITraceTargetDMContext ctx, String varName) {
this(ctx, varName, ""); //$NON-NLS-1$
}
public MITraceDefineVariable(ITraceTargetDMContext ctx, String varName, String varValue) {
super(ctx, "-trace-define-variable", new String[] { varName, varValue }); //$NON-NLS-1$
}
}

View file

@ -0,0 +1,42 @@
/*******************************************************************************
* Copyright (c) 2010 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
*******************************************************************************/
package org.eclipse.cdt.dsf.mi.service.command.commands;
import org.eclipse.cdt.dsf.gdb.service.IGDBTraceControl.ITraceTargetDMContext;
import org.eclipse.cdt.dsf.mi.service.command.output.MIOutput;
import org.eclipse.cdt.dsf.mi.service.command.output.MITraceListVariablesInfo;
/**
* -trace-list-variables
*
* Return a table of all defined trace variables. Each element of the table has the
* following fields:
* 'name' The name of the trace variable. This field is always present.
* 'initial' The initial value. This is a 64-bit signed integer. This field is always present.
* 'current' The value the trace variable has at the moment. This is a 64-bit signed integer.
* This field may is absent if the current value is not defined, for example if
* the trace was never run, or is presently running.
*
* Available with GDB 7.1
*
* @since 2.1
*/
public class MITraceListVariables extends MICommand<MITraceListVariablesInfo> {
public MITraceListVariables(ITraceTargetDMContext ctx) {
super(ctx, "-trace-list-variables"); //$NON-NLS-1$
}
@Override
public MITraceListVariablesInfo getResult(MIOutput out) {
return new MITraceListVariablesInfo(out);
}
}

View file

@ -0,0 +1,36 @@
/*******************************************************************************
* Copyright (c) 2010 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
*******************************************************************************/
package org.eclipse.cdt.dsf.mi.service.command.commands;
import org.eclipse.cdt.dsf.gdb.service.IGDBTraceControl.ITraceTargetDMContext;
import org.eclipse.cdt.dsf.mi.service.command.output.MIInfo;
/**
* -trace-save [-r] FILENAME
*
* Saves the collected trace data to FILENAME. Without the '-r' option, the data is downloaded
* from the target and saved in a local file. With the '-r' option the target is asked to perform
* the save.
*
* Available with GDB 7.1
*
* @since 2.1
*/
public class MITraceSave extends MICommand<MIInfo> {
public MITraceSave(ITraceTargetDMContext ctx, String file, boolean remoteSave) {
super(ctx, "-trace-save", null, new String[] { file }); //$NON-NLS-1$
if (remoteSave) {
setOptions(new String[] { "-r" }); //$NON-NLS-1$
}
}
}

View file

@ -0,0 +1,29 @@
/*******************************************************************************
* Copyright (c) 2010 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
*******************************************************************************/
package org.eclipse.cdt.dsf.mi.service.command.commands;
import org.eclipse.cdt.dsf.gdb.service.IGDBTraceControl.ITraceTargetDMContext;
import org.eclipse.cdt.dsf.mi.service.command.output.MIInfo;
/**
* -trace-start
*
* Starts a tracing experiment. The result of this command does not have any fields.
*
* Available with GDB 7.1
*
* @since 2.1
*/
public class MITraceStart extends MICommand<MIInfo> {
public MITraceStart(ITraceTargetDMContext ctx) {
super(ctx, "-trace-start"); //$NON-NLS-1$
}
}

View file

@ -0,0 +1,34 @@
/*******************************************************************************
* Copyright (c) 2010 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
*******************************************************************************/
package org.eclipse.cdt.dsf.mi.service.command.commands;
import org.eclipse.cdt.dsf.gdb.service.IGDBTraceControl.ITraceTargetDMContext;
import org.eclipse.cdt.dsf.mi.service.command.output.MIOutput;
import org.eclipse.cdt.dsf.mi.service.command.output.MITraceStatusInfo;
/**
* -trace-status
*
* Gets the status of tracing.
*
* Available with GDB 7.1
*
* @since 2.1
*/
public class MITraceStatus extends MICommand<MITraceStatusInfo> {
public MITraceStatus(ITraceTargetDMContext ctx) {
super(ctx, "-trace-status"); //$NON-NLS-1$
}
@Override
public MITraceStatusInfo getResult(MIOutput out) {
return new MITraceStatusInfo(out);
}
}

View file

@ -0,0 +1,35 @@
/*******************************************************************************
* Copyright (c) 2010 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
*******************************************************************************/
package org.eclipse.cdt.dsf.mi.service.command.commands;
import org.eclipse.cdt.dsf.gdb.service.IGDBTraceControl.ITraceTargetDMContext;
import org.eclipse.cdt.dsf.mi.service.command.output.MIOutput;
import org.eclipse.cdt.dsf.mi.service.command.output.MITraceStopInfo;
/**
* -trace-stop
*
* Stops a tracing experiment. The result of this command has the same fields
* as -trace-status, except that the 'supported' and 'running' fields are not output.
*
* Available with GDB 7.1
*
* @since 2.1
*/
public class MITraceStop extends MICommand<MITraceStopInfo> {
public MITraceStop(ITraceTargetDMContext ctx) {
super(ctx, "-trace-stop"); //$NON-NLS-1$
}
@Override
public MITraceStopInfo getResult(MIOutput out) {
return new MITraceStopInfo(out);
}
}

View file

@ -0,0 +1,124 @@
/*******************************************************************************
* Copyright (c) 2010 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
*******************************************************************************/
package org.eclipse.cdt.dsf.mi.service.command.output;
import java.util.ArrayList;
import java.util.List;
/**
* -trace-list-variables
*
* ^done,trace-variables={nr_rows="1",nr_cols="3",
* hdr=[{width="15",alignment="-1",col_name="name",colhdr="Name"},
* {width="11",alignment="-1",col_name="initial",colhdr="Initial"},
* {width="11",alignment="-1",col_name="current",colhdr="Current"}],
* body=[variable={name="$trace_timestamp",initial="0"}
* variable={name="$foo",initial="10",current="15"}]}
*
* @since 2.1
*/
public class MITraceListVariablesInfo extends MIInfo {
public class MITraceVariableInfo {
private String fName;
private String fInitialValue;
private String fCurrentValue;
public String getName() {
return fName;
}
public String getCurrentValue() {
return fCurrentValue;
}
public String getInitialValue() {
return fInitialValue;
}
}
private MITraceVariableInfo[] fVariables;
public MITraceListVariablesInfo(MIOutput out) {
super(out);
parse();
}
public MITraceVariableInfo[] getTraceVariables() {
return fVariables;
}
private void parse() {
List<MITraceVariableInfo> aList = new ArrayList<MITraceVariableInfo>(1);
if (isDone()) {
MIOutput out = getMIOutput();
MIResultRecord rr = out.getMIResultRecord();
if (rr != null) {
MIResult[] results = rr.getMIResults();
for (int i = 0; i < results.length; i++) {
String var = results[i].getVariable();
if (var.equals("trace-variables")) { //$NON-NLS-1$
parseTable(results[i].getMIValue(), aList);
}
}
}
}
fVariables = aList.toArray(new MITraceVariableInfo[aList.size()]);
}
private void parseTable(MIValue val, List<MITraceVariableInfo> aList) {
if (val instanceof MITuple) {
MIResult[] table = ((MITuple)val).getMIResults();
for (int i = 0; i < table.length; i++) {
String variable = table[i].getVariable();
if (variable.equals("body")) { //$NON-NLS-1$
parseBody(table[i].getMIValue(), aList);
}
}
}
}
private void parseBody(MIValue body, List<MITraceVariableInfo> aList) {
if (body instanceof MIList) {
MIResult[] vars = ((MIList)body).getMIResults();
for (int i = 0; i < vars.length; i++) {
String variable = vars[i].getVariable();
if (variable.equals("variable")) { //$NON-NLS-1$
parseVariable(vars[i].getMIValue(), aList);
}
}
}
}
private void parseVariable(MIValue variable, List<MITraceVariableInfo> aList) {
if (variable instanceof MITuple) {
MIResult[] results = ((MITuple)variable).getMIResults();
MITraceVariableInfo info = new MITraceVariableInfo();
for (int i = 0; i < results.length; i++) {
String var = results[i].getVariable();
MIValue value = results[i].getMIValue();
String str = ""; //$NON-NLS-1$
if (value != null && value instanceof MIConst) {
str = ((MIConst)value).getCString();
}
if (var.equals("name")) { //$NON-NLS-1$
info.fName = str;
} else if (var.equals("initial")) { //$NON-NLS-1$
info.fInitialValue = str;
} else if (var.equals("current")) { //$NON-NLS-1$
info.fCurrentValue = str;
}
}
aList.add(info);
}
}
}

View file

@ -0,0 +1,136 @@
/*******************************************************************************
* Copyright (c) 2010 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
*******************************************************************************/
package org.eclipse.cdt.dsf.mi.service.command.output;
import org.eclipse.cdt.dsf.gdb.service.IGDBTraceControl.STOP_REASON_ENUM;
/**
* -trace-status result.
*
* ^done,supported="1",running="1",frames="0",buffer-size="5242880",buffer-free="5242880"
* ^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"
*
* @since 2.1
*/
public class MITraceStatusInfo extends MIInfo {
private int fFreeBufferSize = 0;
private int fTotalBufferSize = 0;
private int fNumberOfCollectedFrames = 0;
private boolean fIsTracingActive = false;
private boolean fIsTracingSupported = false;
private STOP_REASON_ENUM fStopReason = null;
private Integer fStoppingTracepoint = null;
public MITraceStatusInfo(MIOutput out) {
super(out);
parse();
}
public int getFreeBufferSize() {
return fFreeBufferSize;
}
public int getNumberOfCollectedFrame() {
return fNumberOfCollectedFrames;
}
public int getTotalBufferSize() {
return fTotalBufferSize;
}
public boolean isTracingActive() {
return fIsTracingActive;
}
public boolean isTracingSupported() {
return fIsTracingSupported;
}
public STOP_REASON_ENUM getStopReason() {
return fStopReason;
}
public Integer getStopTracepoint() {
return fStoppingTracepoint;
}
private void parse() {
if (isDone()) {
MIOutput out = getMIOutput();
MIResultRecord rr = out.getMIResultRecord();
if (rr != null) {
MIResult[] results = rr.getMIResults();
for (int i = 0; i < results.length; i++) {
String var = results[i].getVariable();
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$
}
} 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) {}
}
} else if (var.equals("stop-reason")) { //$NON-NLS-1$
MIValue val = results[i].getMIValue();
if (val instanceof MIConst) {
String reason = ((MIConst)val).getString().trim();
if (reason.equalsIgnoreCase("request")) { //$NON-NLS-1$
fStopReason = STOP_REASON_ENUM.REQUEST;
} else if (reason.equalsIgnoreCase("overflow")) { //$NON-NLS-1$
fStopReason = STOP_REASON_ENUM.OVERFLOW;
} else if (reason.equalsIgnoreCase("disconnection")) { //$NON-NLS-1$
fStopReason = STOP_REASON_ENUM.DISCONNECTION;
} else if (reason.equalsIgnoreCase("passcount")) { //$NON-NLS-1$
fStopReason = STOP_REASON_ENUM.PASSCOUNT;
} else if (reason.equalsIgnoreCase("error")) { //$NON-NLS-1$
fStopReason = STOP_REASON_ENUM.ERROR;
} else {
fStopReason = STOP_REASON_ENUM.UNKNOWN;
}
}
} else if (var.equals("stopping-tracepoint")) { //$NON-NLS-1$
MIValue val = results[i].getMIValue();
if (val instanceof MIConst) {
try {
fStoppingTracepoint = Integer.parseInt(((MIConst)val).getString());
} catch (NumberFormatException e) {}
}
}
}
}
}
}
}

View file

@ -0,0 +1,28 @@
/*******************************************************************************
* Copyright (c) 2010 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
*******************************************************************************/
package org.eclipse.cdt.dsf.mi.service.command.output;
/**
* -trace-stop result.
*
* The result of this command has the same fields as -trace-status, except that the
* 'supported' and 'running' fields are not output.
* The output is therefore a subset of the output of the -trace-status command.
* The way MI fields are optional allows us to simply re-use the MITraceStatusInfo class
*
* @since 2.1
*/
public class MITraceStopInfo extends MITraceStatusInfo {
public MITraceStopInfo(MIOutput out) {
super(out);
}
}