1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-23 14:42:11 +02:00

Bug 341731 - Show values returned from function calls when doing a

step-return operation

Change-Id: I4ac5c64a940ffcbe75b21618a74f2c4eba93d27e
Signed-off-by: Marc Khouzam <marc.khouzam@ericsson.com>
Reviewed-on: https://git.eclipse.org/r/15377
Reviewed-by: Marc-Andre Laperle <marc-andre.laperle@ericsson.com>
IP-Clean: Marc-Andre Laperle <marc-andre.laperle@ericsson.com>
Tested-by: Marc-Andre Laperle <marc-andre.laperle@ericsson.com>
Reviewed-by: Mikhail Khodjaiants <mikhailkhod@googlemail.com>
IP-Clean: Mikhail Khodjaiants <mikhailkhod@googlemail.com>
Tested-by: Mikhail Khodjaiants <mikhailkhod@googlemail.com>
This commit is contained in:
Marc Khouzam 2013-08-12 08:21:06 -04:00
parent 2186138b87
commit 2a935a9926
15 changed files with 875 additions and 174 deletions

View file

@ -9,6 +9,7 @@
* Freescale Semiconductor - initial API and implementation
* Jens Elmenthaler (Verigy) - Added Full GDB pretty-printing support (bug 302121)
* Marc Khouzam (Ericsson) - Add support disable "View Memory" action (bug 418710)
* Marc Khouzam (Ericsson) - Turn off "watch" action for return values of methods (bug 341731)
*******************************************************************************/
package org.eclipse.cdt.dsf.gdb.internal.ui.viewmodel;
@ -48,6 +49,7 @@ import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenCountUpd
import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IHasChildrenUpdate;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta;
import org.eclipse.debug.ui.actions.IWatchExpressionFactoryAdapter2;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.jface.viewers.TreePath;
@ -194,6 +196,15 @@ public class GdbVariableVMNode extends VariableVMNode {
}
return super.canViewInMemory();
}
@SuppressWarnings({ "unchecked", "rawtypes" })
@Override
public Object getAdapter(Class adapter) {
if (adapter.isAssignableFrom(IWatchExpressionFactoryAdapter2.class)) {
return fGdbVariableExpressionFactory;
}
return super.getAdapter(adapter);
}
};
private static boolean isConvenienceVariable(String expr) {
@ -229,6 +240,25 @@ public class GdbVariableVMNode extends VariableVMNode {
return false;
}
/**
* A factory to control the "Watch" action for GDB variables.
*/
protected class GdbVariableExpressionFactory extends VariableExpressionFactory {
@Override
public boolean canCreateWatchExpression(Object element) {
if (element instanceof VariableExpressionVMC) {
String expression = ((VariableExpressionVMC)element).getExpression();
if (isConvenienceVariable(expression)) {
return false;
}
}
return super.canCreateWatchExpression(element);
}
}
final protected VariableExpressionFactory fGdbVariableExpressionFactory = new GdbVariableExpressionFactory();
/**
* The special context representing more children to be available.
*

View file

@ -10,13 +10,17 @@
* Ericsson - Modified for handling of multiple execution contexts
* Axel Mueller - Bug 306555 - Add support for cast to type / view as array (IExpressions2)
* Jens Elmenthaler (Verigy) - Added Full GDB pretty-printing support (bug 302121)
* Marc Khouzam (Ericsson) - Added support for expression aliases for return values of functions (bug 341731)
*******************************************************************************/
package org.eclipse.cdt.dsf.mi.service;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import org.eclipse.cdt.core.IAddress;
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
@ -35,7 +39,11 @@ import org.eclipse.cdt.dsf.debug.service.IFormattedValues;
import org.eclipse.cdt.dsf.debug.service.IMemory.IMemoryChangedEvent;
import org.eclipse.cdt.dsf.debug.service.IMemory.IMemoryDMContext;
import org.eclipse.cdt.dsf.debug.service.IRegisters.IRegisterDMContext;
import org.eclipse.cdt.dsf.debug.service.IRunControl;
import org.eclipse.cdt.dsf.debug.service.IRunControl.IContainerSuspendedDMEvent;
import org.eclipse.cdt.dsf.debug.service.IRunControl.IExecutionDMContext;
import org.eclipse.cdt.dsf.debug.service.IRunControl.IExitedDMEvent;
import org.eclipse.cdt.dsf.debug.service.IRunControl.IResumedDMEvent;
import org.eclipse.cdt.dsf.debug.service.IRunControl.ISuspendedDMEvent;
import org.eclipse.cdt.dsf.debug.service.IRunControl.StateChangeReason;
import org.eclipse.cdt.dsf.debug.service.IStack.IFrameDMContext;
import org.eclipse.cdt.dsf.debug.service.command.CommandCache;
@ -49,12 +57,16 @@ import org.eclipse.cdt.dsf.mi.service.command.commands.ExprMetaGetChildCount;
import org.eclipse.cdt.dsf.mi.service.command.commands.ExprMetaGetChildren;
import org.eclipse.cdt.dsf.mi.service.command.commands.ExprMetaGetValue;
import org.eclipse.cdt.dsf.mi.service.command.commands.ExprMetaGetVar;
import org.eclipse.cdt.dsf.mi.service.command.events.IMIDMEvent;
import org.eclipse.cdt.dsf.mi.service.command.events.MIFunctionFinishedEvent;
import org.eclipse.cdt.dsf.mi.service.command.events.MIStoppedEvent;
import org.eclipse.cdt.dsf.mi.service.command.output.ExprMetaGetAttributesInfo;
import org.eclipse.cdt.dsf.mi.service.command.output.ExprMetaGetChildCountInfo;
import org.eclipse.cdt.dsf.mi.service.command.output.ExprMetaGetChildrenInfo;
import org.eclipse.cdt.dsf.mi.service.command.output.ExprMetaGetValueInfo;
import org.eclipse.cdt.dsf.mi.service.command.output.ExprMetaGetVarInfo;
import org.eclipse.cdt.dsf.mi.service.command.output.MIDataEvaluateExpressionInfo;
import org.eclipse.cdt.dsf.mi.service.command.output.MIFrame;
import org.eclipse.cdt.dsf.service.AbstractDsfService;
import org.eclipse.cdt.dsf.service.DsfServiceEventHandler;
import org.eclipse.cdt.dsf.service.DsfServicesTracker;
@ -65,6 +77,8 @@ import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.osgi.framework.BundleContext;
import com.ibm.icu.text.MessageFormat;
/**
* This class implements a debugger expression evaluator as a DSF service. The
* primary interface that clients of this class should use is IExpressions.
@ -815,6 +829,116 @@ public class MIExpressions extends AbstractDsfService implements IMIExpressions,
}
}
/**
* Keeps track of aliases for return values of methods.
*/
private class ReturnValueAliasing {
/**
* Map of expression to alias. The expression is the name of the convenience variable
* storing the return value, e.g., $1 -> "foo() returned"
* This map allows to quickly find the alias to be used for return value variables.
*/
private Map<String, String> fExpressionAliasesMap = new HashMap<String, String>();
/**
* Map of thread to aliases expression list. This map allows to know which aliases are related
* to a thread of execution. This is important to allow us to delete aliases when a
* thread exits. Note that we need a list because we keep all previous aliases until
* the thread exits.
*/
private Map<IMIExecutionDMContext, List<String>> fThreadToAliasedExpressionsMap = new HashMap<IMIExecutionDMContext, List<String>>();
/**
* Map of thread to the name of the method the thread last stopped in.
* This allows us to create the alias based on the method the thread was in
* before it returned out of the method.
*/
private Map<IMIExecutionDMContext, String> fThreadToTopMethodName = new HashMap<IMIExecutionDMContext, String>();
/**
* Create an alias for expr with respect to threadDmc.
* The alias is created based on where threadDmc was previously stopped.
*/
public void createAlias(IMIExecutionDMContext threadDmc, String expr) {
String alias = expr;
String methodName = fThreadToTopMethodName.get(threadDmc);
if (methodName != null) {
alias = MessageFormat.format(Messages.MIExpressions_ReturnValueAlias,
methodName + "()"); //$NON-NLS-1$
}
fExpressionAliasesMap.put(expr, alias);
List<String> aliasedExprList = fThreadToAliasedExpressionsMap.get(threadDmc);
if (aliasedExprList == null) {
aliasedExprList = new ArrayList<String>();
fThreadToAliasedExpressionsMap.put(threadDmc, aliasedExprList);
}
aliasedExprList.add(expr);
}
/**
* Clear all information related to a particular thread of execution.
*/
public void clearThread(IMIExecutionDMContext threadDmc) {
fThreadToTopMethodName.remove(threadDmc);
clearAliases(threadDmc);
}
/**
* Clear all aliased expressions related to a particular thread of execution.
* It is good to keep the aliases around as long as the thread is alive;
* even if we won't show the return value automatically, the user
* could add the expression in the expression view, and the alias
* would then be used.
*/
public void clearAliases(IMIExecutionDMContext threadDmc) {
List<String> aliasedExprList = fThreadToAliasedExpressionsMap.remove(threadDmc);
if (aliasedExprList != null) {
for (String expr : aliasedExprList) {
fExpressionAliasesMap.remove(expr);
}
}
}
/**
* Update the method name of the last location where threadDmc was stopped.
*/
public void updateStoppedLocation(IMIExecutionDMContext threadDmc, String methodName) {
fThreadToTopMethodName.put(threadDmc, methodName);
}
/**
* @return The alias for 'expr' if there is one. null if there
* is no alias for that expression.
*/
public String getAlias(String expr) {
String alias = fExpressionAliasesMap.get(expr);
if (alias == null) {
// Check if the expression contains the string that must be aliased.
// E.g., $1[0], *$2
// If it does, just replace that string within the expression to
// create the full alias
for (Entry<String, String> entry : fExpressionAliasesMap.entrySet()) {
int index = expr.indexOf(entry.getKey());
if (index != -1) {
// Found the string! Now replace it with our alias.
// We put it between () to make things clearer to the user.
// Note that there can only be one string contained
// in the expression, so once we found it, we are done.
alias = expr.substring(0, index) +
"(" + entry.getValue() + ")" + //$NON-NLS-1$ //$NON-NLS-2$
expr.substring(index + entry.getKey().length());
break;
}
}
}
return alias;
}
}
/** Structure to keep track of aliases for method return values. */
private ReturnValueAliasing fReturnValueAliases = new ReturnValueAliasing();
/**
* @since 4.3
*/
@ -1061,8 +1185,13 @@ public class MIExpressions extends AbstractDsfService implements IMIExpressions,
}
}
String relativeExpr = getData().getExpr();
String alias = fReturnValueAliases.getAlias(relativeExpr);
if (alias != null) {
relativeExpr = alias;
}
rm.setData(new ExpressionDMData(
getData().getExpr(),getData().getType(), getData().getNumChildren(),
relativeExpr, getData().getType(), getData().getNumChildren(),
getData().getEditable(), basicType));
rm.done();
}
@ -1492,7 +1621,7 @@ public class MIExpressions extends AbstractDsfService implements IMIExpressions,
}
@DsfServiceEventHandler
public void eventDispatched(IRunControl.IResumedDMEvent e) {
public void eventDispatched(IResumedDMEvent e) {
fExpressionCache.setContextAvailable(e.getDMContext(), false);
if (e.getReason() != StateChangeReason.STEP) {
fExpressionCache.reset();
@ -1500,9 +1629,53 @@ public class MIExpressions extends AbstractDsfService implements IMIExpressions,
}
@DsfServiceEventHandler
public void eventDispatched(IRunControl.ISuspendedDMEvent e) {
public void eventDispatched(ISuspendedDMEvent e) {
fExpressionCache.setContextAvailable(e.getDMContext(), true);
fExpressionCache.reset();
handleReturnValueAliasing(e);
}
private void handleReturnValueAliasing(ISuspendedDMEvent e) {
// Process MIStoppedEvent from within the ISuspendedDMEvent
// to avoid any race conditions where the actual MIStoppedEvent
// can arrive faster that a preceding IResumedDMEvent
if (e instanceof IMIDMEvent) {
Object miEvent = ((IMIDMEvent)e).getMIEvent();
if (miEvent instanceof MIStoppedEvent) {
IMIExecutionDMContext stoppedEventThread = null;
if (e instanceof IContainerSuspendedDMEvent) {
// All-stop mode
IExecutionDMContext[] triggerContexts = ((IContainerSuspendedDMEvent)e).getTriggeringContexts();
if (triggerContexts.length != 0 && triggerContexts[0] instanceof IMIExecutionDMContext) {
stoppedEventThread = (IMIExecutionDMContext)triggerContexts[0];
}
} else {
// Non-stop mode
IDMContext dmc = e.getDMContext();
if (dmc instanceof IMIExecutionDMContext) {
stoppedEventThread = (IMIExecutionDMContext)dmc;
}
}
if (stoppedEventThread != null) {
if (miEvent instanceof MIFunctionFinishedEvent) {
// When getting an MIFunctionFinishedEvent we must set
// a proper alias for the convenience variable
String resultVar = ((MIFunctionFinishedEvent)miEvent).getGDBResultVar();
fReturnValueAliases.createAlias(stoppedEventThread, resultVar);
}
// Keep track of the latest method the thread is stopped in.
// Must do this after creating any alias, or else we will overwrite
// the previous function name, which we need for the alias
MIFrame frame = ((MIStoppedEvent)miEvent).getFrame();
if (frame != null) {
fReturnValueAliases.updateStoppedLocation(stoppedEventThread, frame.getFunction());
}
}
}
}
}
@DsfServiceEventHandler
@ -1520,6 +1693,20 @@ public class MIExpressions extends AbstractDsfService implements IMIExpressions,
fTraceVisualization = false;
}
}
/**
* @nooverride This method is not intended to be re-implemented or extended by clients.
* @noreference This method is not intended to be referenced by clients.
*/
@DsfServiceEventHandler
public void eventDispatched(IExitedDMEvent e) {
IDMContext ctx = e.getDMContext();
if (ctx instanceof IMIExecutionDMContext) {
// When a thread exits, clear the alias structure for that
// thread to avoid leaks
fReturnValueAliases.clearThread((IMIExecutionDMContext)ctx);
}
}
/**
* {@inheritDoc}

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2006, 2010 Wind River Systems and others.
* Copyright (c) 2006, 2013 Wind River Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@ -8,6 +8,7 @@
* Contributors:
* Wind River Systems - initial API and implementation
* Ericsson - Modified for handling of multiple execution contexts
* Marc Khouzam (Ericsson) - Show return value of the method when doing a step-return (Bug 341731)
*******************************************************************************/
package org.eclipse.cdt.dsf.mi.service;
@ -29,6 +30,9 @@ import org.eclipse.cdt.dsf.datamodel.DMContexts;
import org.eclipse.cdt.dsf.datamodel.IDMContext;
import org.eclipse.cdt.dsf.debug.service.ICachingService;
import org.eclipse.cdt.dsf.debug.service.IRunControl;
import org.eclipse.cdt.dsf.debug.service.IRunControl.IContainerDMContext;
import org.eclipse.cdt.dsf.debug.service.IRunControl.IContainerResumedDMEvent;
import org.eclipse.cdt.dsf.debug.service.IRunControl.IContainerSuspendedDMEvent;
import org.eclipse.cdt.dsf.debug.service.IRunControl.IExecutionDMContext;
import org.eclipse.cdt.dsf.debug.service.IRunControl.IResumedDMEvent;
import org.eclipse.cdt.dsf.debug.service.IRunControl.ISuspendedDMEvent;
@ -42,6 +46,7 @@ import org.eclipse.cdt.dsf.gdb.internal.GdbPlugin;
import org.eclipse.cdt.dsf.gdb.service.IGDBTraceControl.ITraceRecordSelectedChangedDMEvent;
import org.eclipse.cdt.dsf.mi.service.command.CommandFactory;
import org.eclipse.cdt.dsf.mi.service.command.events.IMIDMEvent;
import org.eclipse.cdt.dsf.mi.service.command.events.MIFunctionFinishedEvent;
import org.eclipse.cdt.dsf.mi.service.command.events.MIStoppedEvent;
import org.eclipse.cdt.dsf.mi.service.command.output.MIArg;
import org.eclipse.cdt.dsf.mi.service.command.output.MIFrame;
@ -92,7 +97,7 @@ public class MIStack extends AbstractDsfService
protected static class MIVariableDMC extends AbstractDMContext
implements IVariableDMContext
{
public enum Type { ARGUMENT, LOCAL }
public enum Type { ARGUMENT, LOCAL, /** @since 4.4 */RETURN_VALUES }
final private Type fType;
final private int fIndex;
@ -117,6 +122,7 @@ public class MIStack extends AbstractDsfService
int typeFactor = 0;
if (fType == Type.LOCAL) typeFactor = 2;
else if (fType == Type.ARGUMENT) typeFactor = 3;
else if (fType == Type.RETURN_VALUES) typeFactor = 4;
return super.baseHashCode() ^ typeFactor ^ fIndex;
}
@ -155,6 +161,33 @@ public class MIStack extends AbstractDsfService
};
}
}
/**
* Same as with frame objects, this is a base class for the IVariableDMData object that uses an MIArg object to
* provide the data. Sub-classes must supply the MIArg object.
*/
private class VariableData implements IVariableDMData {
private MIArg fMIArg;
public VariableData(MIArg arg){
fMIArg = arg;
}
@Override
public String getName() {
return fMIArg.getName();
}
@Override
public String getValue() {
return fMIArg.getValue();
}
@Override
public String toString() {
return fMIArg.toString();
}
}
private CommandCache fMICommandCache;
private CommandFactory fCommandFactory;
@ -176,6 +209,13 @@ public class MIStack extends AbstractDsfService
*/
private boolean fTraceVisualization;
/**
* A Map of a return value for each thread.
* A return value is stored when the user performs a step-return,
* and it cleared as soon as that thread executes again.
*/
private Map<IMIExecutionDMContext, VariableData> fThreadToReturnVariable = new HashMap<IMIExecutionDMContext, VariableData>();
public MIStack(DsfSession session)
{
super(session);
@ -614,23 +654,6 @@ public class MIStack extends AbstractDsfService
return;
}
/**
* Same as with frame objects, this is a base class for the IVariableDMData object that uses an MIArg object to
* provide the data. Sub-classes must supply the MIArg object.
*/
class VariableData implements IVariableDMData {
private MIArg dsfMIArg;
VariableData(MIArg arg){
dsfMIArg = arg;
}
@Override
public String getName() { return dsfMIArg.getName(); }
@Override
public String getValue() { return dsfMIArg.getValue(); }
@Override
public String toString() { return dsfMIArg.toString(); }
}
// Check if the stopped event can be used to extract the variable value.
if (execDmc != null && miVariableDmc.fType == MIVariableDMC.Type.ARGUMENT &&
frameDmc.fLevel == 0 && fCachedStoppedEvent != null && fCachedStoppedEvent.getFrame() != null &&
@ -694,8 +717,7 @@ public class MIStack extends AbstractDsfService
});
}
});
}//if
if (miVariableDmc.fType == MIVariableDMC.Type.LOCAL){
} else if (miVariableDmc.fType == MIVariableDMC.Type.LOCAL){
fMICommandCache.execute(
// Don't ask for value when we are visualizing trace data, since some
// data will not be there, and the command will fail
@ -735,7 +757,17 @@ public class MIStack extends AbstractDsfService
});
}
});
}//if
} else if (miVariableDmc.fType == MIVariableDMC.Type.RETURN_VALUES) {
VariableData var = fThreadToReturnVariable.get(execDmc);
if (var != null) {
rm.setData(var);
} else {
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INVALID_HANDLE, "Return value not found", null)); //$NON-NLS-1$
}
rm.done();
} else {
rm.done(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INVALID_HANDLE, "Invalid variable type " + miVariableDmc.fType, null)); //$NON-NLS-1$
}
}
@ -767,7 +799,24 @@ public class MIStack extends AbstractDsfService
return -1;
}
/**
* Retrieves variables which are used to store the return values of functions.
*/
private void getReturnValues(IFrameDMContext frameDmc, DataRequestMonitor<IVariableDMContext[]> rm) {
IVariableDMContext[] values = new IVariableDMContext[0];
// Return values are only relevant for the top stack-frame
if (!fTraceVisualization && frameDmc.getLevel() == 0) {
IMIExecutionDMContext threadDmc = DMContexts.getAncestorOfType(frameDmc, IMIExecutionDMContext.class);
VariableData var = fThreadToReturnVariable.get(threadDmc);
if (var != null) {
values = new IVariableDMContext[1];
values[0] = new MIVariableDMC(this, frameDmc, MIVariableDMC.Type.RETURN_VALUES, 0);
}
}
rm.done(values);
}
@Override
public void getLocals(final IFrameDMContext frameDmc, final DataRequestMonitor<IVariableDMContext[]> rm) {
@ -780,8 +829,20 @@ public class MIStack extends AbstractDsfService
rm.done();
}
};
countingRm.setDoneCount(2);
countingRm.setDoneCount(3);
// First show any return values of methods
getReturnValues(
frameDmc,
new DataRequestMonitor<IVariableDMContext[]>(getExecutor(), countingRm) {
@Override
protected void handleSuccess() {
localsList.addAll( Arrays.asList(getData()) );
countingRm.done();
}
});
// Then show arguments
getArguments(
frameDmc,
new DataRequestMonitor<IVariableDMContext[]>(getExecutor(), countingRm) {
@ -792,6 +853,7 @@ public class MIStack extends AbstractDsfService
}
});
// Finally get the local variables
fMICommandCache.execute(
// We don't actually need to ask for the values in this case, but since
// we will ask for them right after, it is more efficient to ask for them now
@ -914,6 +976,29 @@ public class MIStack extends AbstractDsfService
fMICommandCache.reset();
fStackDepthCache.clear();
}
handleReturnValues(e);
}
private void handleReturnValues(IResumedDMEvent e) {
// Whenever the execution resumes, we can clear any
// return values of previous methods for the resuming
// thread context. For all-stop mode, we get a container event here,
// and we can clear the entire list, which should contain at most one
// value for all-stop.
if (e instanceof IContainerResumedDMEvent) {
// All-stop mode
assert fThreadToReturnVariable.size() <= 1;
fThreadToReturnVariable.clear();
} else {
// Non-stop mode
IDMContext ctx = e.getDMContext();
if (ctx instanceof IMIExecutionDMContext) {
fThreadToReturnVariable.remove(ctx);
} else if (ctx instanceof IContainerDMContext) {
fThreadToReturnVariable.clear();
}
}
}
/**
@ -926,8 +1011,47 @@ public class MIStack extends AbstractDsfService
fMICommandCache.setContextAvailable(e.getDMContext(), true);
fMICommandCache.reset();
fStackDepthCache.clear();
handleReturnValues(e);
}
private void handleReturnValues(ISuspendedDMEvent e) {
// Process MIFunctionFinishedEvent from within the ISuspendedDMEvent
// instead of MIStoppedEvent.
// This avoids a race conditions where the actual MIFunctionFinishedEvent
// can arrive here, faster that a preceding IResumedDMEvent
if (e instanceof IMIDMEvent) {
Object miEvent = ((IMIDMEvent)e).getMIEvent();
if (miEvent instanceof MIFunctionFinishedEvent) {
// When returning out of a function, we want to show the return value
// for the thread that finished the call. To do that, we store
// the variable in which GDB stores that return value, and we do
// that for the proper thread.
IMIExecutionDMContext finishedEventThread = null;
if (e instanceof IContainerSuspendedDMEvent) {
// All-stop mode
IExecutionDMContext[] triggerContexts = ((IContainerSuspendedDMEvent)e).getTriggeringContexts();
if (triggerContexts.length != 0 && triggerContexts[0] instanceof IMIExecutionDMContext) {
finishedEventThread = (IMIExecutionDMContext)triggerContexts[0];
}
} else {
// Non-stop mode
IDMContext ctx = e.getDMContext();
if (ctx instanceof IMIExecutionDMContext) {
finishedEventThread = (IMIExecutionDMContext)ctx;
}
}
if (finishedEventThread != null) {
String name = ((MIFunctionFinishedEvent)miEvent).getGDBResultVar();
String value = ((MIFunctionFinishedEvent)miEvent).getReturnValue();
fThreadToReturnVariable.put(finishedEventThread, new VariableData(new MIArg(name, value)));
}
}
}
}
/**
* @nooverride This method is not intended to be re-implemented or extended by clients.

View file

@ -21,6 +21,7 @@ class Messages extends NLS {
public static String Breakpoint_attribute_problem;
public static String Breakpoint_installation_failed;
public static String MIExpressions_NotAvailableBecauseChildOfDynamicVarobj;
public static String MIExpressions_ReturnValueAlias;
static {
// initialize resource bundle

View file

@ -14,3 +14,4 @@ Breakpoint_attribute_problem=Breakpoint attribute problem: {0}
Breakpoint_installation_failed=installation failed
MIExpressions_NotAvailableBecauseChildOfDynamicVarobj=N/A (child of pretty-printed object)
MIExpressions_ReturnValueAlias={0} returned

View file

@ -21,14 +21,24 @@ char *gCharPtr2 = (char*)0x4321;
bool *gBoolPtr2 = (bool*)0x12ABCDEF;
class bar {
public:
public:
bar() {
d = 8;
e[0] = 18;
e[1] = 28;
}
int d;
private:
int e[2];
};
class bar2 {
public:
public:
bar2() {
f = 318;
g[0] = 228;
g[1] = 138;
}
int f;
private:
int g[2];
@ -36,6 +46,11 @@ private:
class foo: public bar, bar2 {
public:
foo() {
c = 8;
a[0] = 1000;
a[1] = 23;
}
int a[2];
bar b;
private:
@ -350,6 +365,28 @@ int testRTTI() {
}
// End of bug 376901 RTTI tests
int testSimpleReturn(int a) {
int b = 0;
b = a;
return b;
}
foo testComplexReturn() {
foo f;
int a = 8;
return f;
}
void testReturn() {
int a = 10;
bool b = false;
testSimpleReturn(6);
testComplexReturn();
a = 0;;
}
int main() {
printf("Running ExpressionTest App\n");
@ -377,10 +414,12 @@ int main() {
testArrays();
testRTTI();
testCasting();
testReturn();
// For bug 320277
BaseTest b; b.test();
return 0;
}

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2007, 2010 Ericsson and others.
* Copyright (c) 2007, 2013 Ericsson and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@ -12,15 +12,21 @@ package org.eclipse.cdt.tests.dsf.gdb.framework;
import static org.junit.Assert.fail;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.TimeUnit;
import junit.framework.Assert;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertEquals;
import org.eclipse.cdt.dsf.concurrent.CountingRequestMonitor;
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
import org.eclipse.cdt.dsf.concurrent.ImmediateDataRequestMonitor;
import org.eclipse.cdt.dsf.concurrent.ImmediateExecutor;
import org.eclipse.cdt.dsf.concurrent.Query;
import org.eclipse.cdt.dsf.concurrent.ThreadSafeAndProhibitedFromDsfExecutor;
import org.eclipse.cdt.dsf.datamodel.DMContexts;
@ -39,6 +45,8 @@ import org.eclipse.cdt.dsf.debug.service.IRunControl.IExecutionDMContext;
import org.eclipse.cdt.dsf.debug.service.IRunControl.StepType;
import org.eclipse.cdt.dsf.debug.service.IStack.IFrameDMContext;
import org.eclipse.cdt.dsf.debug.service.IStack.IFrameDMData;
import org.eclipse.cdt.dsf.debug.service.IStack.IVariableDMContext;
import org.eclipse.cdt.dsf.debug.service.IStack.IVariableDMData;
import org.eclipse.cdt.dsf.gdb.internal.GdbPlugin;
import org.eclipse.cdt.dsf.gdb.launching.GdbLaunch;
import org.eclipse.cdt.dsf.gdb.service.IGDBProcesses;
@ -607,10 +615,10 @@ public class SyncUtil {
protected void handleCompleted() {
if (isSuccess()) {
IDMContext[] contexts = getData();
Assert.assertNotNull("invalid return value from service", contexts);
Assert.assertEquals("unexpected number of processes", 1, contexts.length);
assertNotNull("invalid return value from service", contexts);
assertEquals("unexpected number of processes", 1, contexts.length);
IDMContext context = contexts[0];
Assert.assertNotNull("unexpected process context type ", context);
assertNotNull("unexpected process context type ", context);
rm.done((IContainerDMContext)context);
} else {
rm.done(getStatus());
@ -648,7 +656,7 @@ public class SyncUtil {
protected void handleCompleted() {
if (isSuccess()) {
IDMContext[] threads = getData();
Assert.assertNotNull("invalid return value from service", threads);
assertNotNull("invalid return value from service", threads);
rm.setData((IMIExecutionDMContext[])threads);
} else {
rm.setStatus(getStatus());
@ -673,8 +681,8 @@ public class SyncUtil {
@ThreadSafeAndProhibitedFromDsfExecutor("fSession.getExecutor()")
public static IMIExecutionDMContext getExecutionContext(int threadIndex) throws InterruptedException {
IMIExecutionDMContext[] threads = getExecutionContexts();
Assert.assertTrue("unexpected number of threads", threadIndex < threads.length);
Assert.assertNotNull("unexpected thread context type ", threads[threadIndex]);
assertTrue("unexpected number of threads", threadIndex < threads.length);
assertNotNull("unexpected thread context type ", threads[threadIndex]);
return threads[threadIndex];
}
@ -748,4 +756,45 @@ public class SyncUtil {
}
return event;
}
public static IVariableDMData[] getLocals(final IFrameDMContext frameDmc) throws Throwable {
Query<IVariableDMData[]> query = new Query<IVariableDMData[]>() {
@Override
protected void execute(final DataRequestMonitor<IVariableDMData[]> rm) {
fStack.getLocals(frameDmc, new ImmediateDataRequestMonitor<IVariableDMContext[]>() {
@Override
protected void handleCompleted() {
if (isSuccess()) {
IVariableDMContext[] varDmcs = getData();
final List<IVariableDMData> localsDMData = new ArrayList<IVariableDMData>();
final CountingRequestMonitor crm = new CountingRequestMonitor(ImmediateExecutor.getInstance(), rm) {
@Override
protected void handleSuccess() {
rm.done(localsDMData.toArray(new IVariableDMData[localsDMData.size()]));
};
};
for (IVariableDMContext varDmc : varDmcs) {
fStack.getVariableData(varDmc,
new ImmediateDataRequestMonitor<IVariableDMData>(crm) {
@Override
public void handleSuccess() {
localsDMData.add(getData());
crm.done();
}
});
}
crm.setDoneCount(varDmcs.length);
} else {
rm.done();
}
}
});
}
};
fSession.getExecutor().execute(query);
IVariableDMData[] result = query.get(500, TimeUnit.MILLISECONDS);
return result;
}
}

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2007, 2010 Ericsson and others.
* Copyright (c) 2007, 2013 Ericsson and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@ -40,6 +40,7 @@ import org.eclipse.cdt.dsf.debug.service.IFormattedValues.FormattedValueDMContex
import org.eclipse.cdt.dsf.debug.service.IFormattedValues.FormattedValueDMData;
import org.eclipse.cdt.dsf.debug.service.IRunControl.StepType;
import org.eclipse.cdt.dsf.debug.service.IStack.IFrameDMContext;
import org.eclipse.cdt.dsf.debug.service.IStack.IVariableDMData;
import org.eclipse.cdt.dsf.mi.service.ClassAccessor.MIExpressionDMCAccessor;
import org.eclipse.cdt.dsf.mi.service.MIExpressions;
import org.eclipse.cdt.dsf.mi.service.command.events.MIStoppedEvent;
@ -310,11 +311,13 @@ public class MIExpressionsTest extends BaseTestCase {
// Get the children of some variables
MIStoppedEvent stoppedEvent = SyncUtil.runToLocation("testChildren");
doTestChildren(stoppedEvent);
IFrameDMContext frameDmc = SyncUtil.getStackFrame(stoppedEvent.getDMContext(), 0);
IExpressionDMContext exprDMC = SyncUtil.createExpression(frameDmc, "f");
doTestChildren(exprDMC);
// Now do a step and get the children again, to test the internal cache
stoppedEvent = SyncUtil.step(1, StepType.STEP_OVER);
doTestChildren(stoppedEvent);
SyncUtil.step(1, StepType.STEP_OVER);
doTestChildren(exprDMC);
}
/**
@ -3188,12 +3191,8 @@ public class MIExpressionsTest extends BaseTestCase {
}
}
private void doTestChildren(MIStoppedEvent stoppedEvent) throws Throwable {
final IFrameDMContext frameDmc = SyncUtil.getStackFrame(stoppedEvent.getDMContext(), 0);
final IExpressionDMContext exprDMC = SyncUtil.createExpression(frameDmc, "f");
private void doTestChildren(IExpressionDMContext exprDMC) throws Throwable
{
IExpressionDMContext[] children =
getChildren(exprDMC, new String[] {"bar", "bar2", "a", "b", "c"});
@ -3598,20 +3597,15 @@ public class MIExpressionsTest extends BaseTestCase {
Query<String> query = new Query<String>() {
@Override
protected void execute(final DataRequestMonitor<String> rm) {
fExpService.getExecutor().submit(new Runnable() {
@Override
public void run() {
fExpService.getFormattedExpressionValue(
fExpService.getFormattedValueContext(children[0], IFormattedValues.NATURAL_FORMAT),
new ImmediateDataRequestMonitor<FormattedValueDMData>(rm) {
@Override
protected void handleCompleted() {
rm.done(getData().getFormattedValue());
}
});
}
});
}
fExpService.getFormattedExpressionValue(
fExpService.getFormattedValueContext(children[0], IFormattedValues.NATURAL_FORMAT),
new ImmediateDataRequestMonitor<FormattedValueDMData>(rm) {
@Override
protected void handleCompleted() {
rm.done(getData().getFormattedValue());
}
});
}
};
fSession.getExecutor().execute(query);
@ -3622,20 +3616,15 @@ public class MIExpressionsTest extends BaseTestCase {
query = new Query<String>() {
@Override
protected void execute(final DataRequestMonitor<String> rm) {
fExpService.getExecutor().submit(new Runnable() {
@Override
public void run() {
fExpService.getFormattedExpressionValue(
fExpService.getFormattedValueContext(castChildren[0], IFormattedValues.NATURAL_FORMAT),
new ImmediateDataRequestMonitor<FormattedValueDMData>(rm) {
@Override
protected void handleCompleted() {
rm.done(getData().getFormattedValue());
}
});
}
});
}
fExpService.getFormattedExpressionValue(
fExpService.getFormattedValueContext(castChildren[0], IFormattedValues.NATURAL_FORMAT),
new ImmediateDataRequestMonitor<FormattedValueDMData>(rm) {
@Override
protected void handleCompleted() {
rm.done(getData().getFormattedValue());
}
});
}
};
fSession.getExecutor().execute(query);
value = query.get(500, TimeUnit.MILLISECONDS);
@ -3675,20 +3664,15 @@ public class MIExpressionsTest extends BaseTestCase {
Query<String> query = new Query<String>() {
@Override
protected void execute(final DataRequestMonitor<String> rm) {
fExpService.getExecutor().submit(new Runnable() {
@Override
public void run() {
fExpService.getFormattedExpressionValue(
fExpService.getFormattedValueContext(child, IFormattedValues.NATURAL_FORMAT),
new ImmediateDataRequestMonitor<FormattedValueDMData>(rm) {
@Override
protected void handleCompleted() {
rm.done(getData().getFormattedValue());
}
});
}
});
}
fExpService.getFormattedExpressionValue(
fExpService.getFormattedValueContext(child, IFormattedValues.NATURAL_FORMAT),
new ImmediateDataRequestMonitor<FormattedValueDMData>(rm) {
@Override
protected void handleCompleted() {
rm.done(getData().getFormattedValue());
}
});
}
};
fSession.getExecutor().execute(query);
@ -3738,20 +3722,15 @@ public class MIExpressionsTest extends BaseTestCase {
Query<String> query = new Query<String>() {
@Override
protected void execute(final DataRequestMonitor<String> rm) {
fExpService.getExecutor().submit(new Runnable() {
@Override
public void run() {
fExpService.getFormattedExpressionValue(
fExpService.getFormattedValueContext(child, IFormattedValues.NATURAL_FORMAT),
new ImmediateDataRequestMonitor<FormattedValueDMData>(rm) {
@Override
protected void handleCompleted() {
rm.done(getData().getFormattedValue());
}
});
}
});
}
fExpService.getFormattedExpressionValue(
fExpService.getFormattedValueContext(child, IFormattedValues.NATURAL_FORMAT),
new ImmediateDataRequestMonitor<FormattedValueDMData>(rm) {
@Override
protected void handleCompleted() {
rm.done(getData().getFormattedValue());
}
});
}
};
fSession.getExecutor().execute(query);
@ -3801,20 +3780,15 @@ public class MIExpressionsTest extends BaseTestCase {
Query<String> query = new Query<String>() {
@Override
protected void execute(final DataRequestMonitor<String> rm) {
fExpService.getExecutor().submit(new Runnable() {
@Override
public void run() {
fExpService.getFormattedExpressionValue(
fExpService.getFormattedValueContext(child, IFormattedValues.NATURAL_FORMAT),
new ImmediateDataRequestMonitor<FormattedValueDMData>(rm) {
@Override
protected void handleCompleted() {
rm.done(getData().getFormattedValue());
}
});
}
});
}
fExpService.getFormattedExpressionValue(
fExpService.getFormattedValueContext(child, IFormattedValues.NATURAL_FORMAT),
new ImmediateDataRequestMonitor<FormattedValueDMData>(rm) {
@Override
protected void handleCompleted() {
rm.done(getData().getFormattedValue());
}
});
}
};
fSession.getExecutor().execute(query);
@ -3871,20 +3845,15 @@ public class MIExpressionsTest extends BaseTestCase {
Query<String> query = new Query<String>() {
@Override
protected void execute(final DataRequestMonitor<String> rm) {
fExpService.getExecutor().submit(new Runnable() {
@Override
public void run() {
fExpService.getFormattedExpressionValue(
fExpService.getFormattedValueContext(child, IFormattedValues.NATURAL_FORMAT),
new ImmediateDataRequestMonitor<FormattedValueDMData>(rm) {
@Override
protected void handleCompleted() {
rm.done(getData().getFormattedValue());
}
});
}
});
}
fExpService.getFormattedExpressionValue(
fExpService.getFormattedValueContext(child, IFormattedValues.NATURAL_FORMAT),
new ImmediateDataRequestMonitor<FormattedValueDMData>(rm) {
@Override
protected void handleCompleted() {
rm.done(getData().getFormattedValue());
}
});
}
};
fSession.getExecutor().execute(query);
@ -3947,20 +3916,15 @@ public class MIExpressionsTest extends BaseTestCase {
Query<String> query = new Query<String>() {
@Override
protected void execute(final DataRequestMonitor<String> rm) {
fExpService.getExecutor().submit(new Runnable() {
@Override
public void run() {
fExpService.getFormattedExpressionValue(
fExpService.getFormattedValueContext(child, IFormattedValues.NATURAL_FORMAT),
new ImmediateDataRequestMonitor<FormattedValueDMData>(rm) {
@Override
protected void handleCompleted() {
rm.done(getData().getFormattedValue());
}
});
}
});
}
fExpService.getFormattedExpressionValue(
fExpService.getFormattedValueContext(child, IFormattedValues.NATURAL_FORMAT),
new ImmediateDataRequestMonitor<FormattedValueDMData>(rm) {
@Override
protected void handleCompleted() {
rm.done(getData().getFormattedValue());
}
});
}
};
fSession.getExecutor().execute(query);
@ -4021,20 +3985,15 @@ public class MIExpressionsTest extends BaseTestCase {
Query<String> query = new Query<String>() {
@Override
protected void execute(final DataRequestMonitor<String> rm) {
fExpService.getExecutor().submit(new Runnable() {
@Override
public void run() {
fExpService.getFormattedExpressionValue(
fExpService.getFormattedValueContext(child, IFormattedValues.NATURAL_FORMAT),
new ImmediateDataRequestMonitor<FormattedValueDMData>(rm) {
@Override
protected void handleCompleted() {
rm.done(getData().getFormattedValue());
}
});
}
});
}
fExpService.getFormattedExpressionValue(
fExpService.getFormattedValueContext(child, IFormattedValues.NATURAL_FORMAT),
new ImmediateDataRequestMonitor<FormattedValueDMData>(rm) {
@Override
protected void handleCompleted() {
rm.done(getData().getFormattedValue());
}
});
}
};
fSession.getExecutor().execute(query);
@ -4046,6 +4005,105 @@ public class MIExpressionsTest extends BaseTestCase {
assertEquals(castExprDmc.getParents()[0], exprDmc);
}
/**
* This test verifies that we display the simple return value of a method after
* a step-return operation, but only for the first stack frame.
*/
@Test
public void testDisplaySimpleReturnValueForStepReturn() throws Throwable {
SyncUtil.runToLocation("testSimpleReturn");
MIStoppedEvent stoppedEvent = SyncUtil.step(1, StepType.STEP_RETURN);
// Check the return value is shown when looking at the first frame
final IFrameDMContext frameDmc = SyncUtil.getStackFrame(stoppedEvent.getDMContext(), 0);
IVariableDMData[] result = SyncUtil.getLocals(frameDmc);
assertEquals(3, result.length); // Two variables and one return value
// Return value
assertEquals("$1", result[0].getName());
assertEquals("6", result[0].getValue());
// first variable
assertEquals("a", result[1].getName());
assertEquals("10", result[1].getValue());
// Second variable
assertEquals("b", result[2].getName());
assertEquals("false", result[2].getValue());
// Now check how the return value will be displayed to the user
final IExpressionDMContext returnExprDmc = SyncUtil.createExpression(frameDmc, "$1");
Query<IExpressionDMData> query = new Query<IExpressionDMData>() {
@Override
protected void execute(final DataRequestMonitor<IExpressionDMData> rm) {
fExpService.getExpressionData(returnExprDmc, rm);
}
};
fSession.getExecutor().execute(query);
IExpressionDMData data = query.get(500, TimeUnit.MILLISECONDS);
assertEquals("testSimpleReturn() returned", data.getName());
// Now check the actual value using the expression service
String value = SyncUtil.getExpressionValue(returnExprDmc, IFormattedValues.DECIMAL_FORMAT);
assertEquals("6", value);
// Now make sure we don't show the return value for another frame
final IFrameDMContext frameDmc2 = SyncUtil.getStackFrame(stoppedEvent.getDMContext(), 1);
result = SyncUtil.getLocals(frameDmc2);
// only one variable
assertEquals(1, result.length);
assertEquals("b", result[0].getName());
}
/**
* This test verifies that we display the complex return value of a method after
* a step-return operation, but only for the first stack frame.
*/
@Test
public void testDisplayComplexReturnValueForStepReturn() throws Throwable {
SyncUtil.runToLocation("testComplexReturn");
MIStoppedEvent stoppedEvent = SyncUtil.step(1, StepType.STEP_RETURN);
// Check the return value is show when looking at the first frame
final IFrameDMContext frameDmc = SyncUtil.getStackFrame(stoppedEvent.getDMContext(), 0);
IVariableDMData[] result = SyncUtil.getLocals(frameDmc);
assertEquals(3, result.length); // Two variables and one return value
// Return value
assertEquals("$1", result[0].getName());
// first variable
assertEquals("a", result[1].getName());
assertEquals("10", result[1].getValue());
// Second variable
assertEquals("b", result[2].getName());
assertEquals("false", result[2].getValue());
// Now check how the return value will be displayed to the user
final IExpressionDMContext returnExprDmc = SyncUtil.createExpression(frameDmc, "$1");
Query<IExpressionDMData> query = new Query<IExpressionDMData>() {
@Override
protected void execute(final DataRequestMonitor<IExpressionDMData> rm) {
fExpService.getExpressionData(returnExprDmc, rm);
}
};
fSession.getExecutor().execute(query);
IExpressionDMData data = query.get(500, TimeUnit.MILLISECONDS);
assertEquals("testComplexReturn() returned", data.getName());
// Now check the content of the complex return expression
doTestChildren(returnExprDmc);
// Now make sure we don't show the return value for another frame
IFrameDMContext frameDmc2 = SyncUtil.getStackFrame(stoppedEvent.getDMContext(), 1);
result = SyncUtil.getLocals(frameDmc2);
// only one variable
assertEquals(1, result.length);
assertEquals("b", result[0].getName());
}
protected int getChildrenCount(final IExpressionDMContext parentDmc, final int expectedCount) throws Throwable {
final AsyncCompletionWaitor wait = new AsyncCompletionWaitor();
@ -4098,20 +4156,15 @@ public class MIExpressionsTest extends BaseTestCase {
Query<String> query = new Query<String>() {
@Override
protected void execute(final DataRequestMonitor<String> rm) {
fExpService.getExecutor().submit(new Runnable() {
@Override
public void run() {
fExpService.getExpressionData(
exprDmc,
new ImmediateDataRequestMonitor<IExpressionDMData>(rm) {
@Override
protected void handleCompleted() {
rm.done(getData().getTypeName());
}
});
}
});
}
fExpService.getExpressionData(
exprDmc,
new ImmediateDataRequestMonitor<IExpressionDMData>(rm) {
@Override
protected void handleCompleted() {
rm.done(getData().getTypeName());
}
});
}
};
fSession.getExecutor().execute(query);

View file

@ -0,0 +1,31 @@
/*******************************************************************************
* Copyright (c) 2013 Ericsson and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Marc Khouzam (Ericsson) - Initial Implementation
*******************************************************************************/
package org.eclipse.cdt.tests.dsf.gdb.tests.tests_7_0;
import org.eclipse.cdt.dsf.gdb.IGDBLaunchConfigurationConstants;
import org.eclipse.cdt.tests.dsf.gdb.framework.BackgroundRunner;
import org.eclipse.cdt.tests.dsf.gdb.tests.ITestConstants;
import org.junit.runner.RunWith;
@RunWith(BackgroundRunner.class)
public class MIExpressionsNonStopTest_7_0 extends MIExpressionsTest_7_0 {
@Override
protected void setGdbVersion() {
setGdbProgramNamesLaunchAttributes(ITestConstants.SUFFIX_GDB_7_0);
}
@Override
protected void setLaunchAttributes() {
super.setLaunchAttributes();
setLaunchAttribute(IGDBLaunchConfigurationConstants.ATTR_DEBUGGER_NON_STOP, true);
}
}

View file

@ -0,0 +1,31 @@
/*******************************************************************************
* Copyright (c) 2013 Ericsson and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Marc Khouzam (Ericsson) - Initial Implementation
*******************************************************************************/
package org.eclipse.cdt.tests.dsf.gdb.tests.tests_7_1;
import org.eclipse.cdt.dsf.gdb.IGDBLaunchConfigurationConstants;
import org.eclipse.cdt.tests.dsf.gdb.framework.BackgroundRunner;
import org.eclipse.cdt.tests.dsf.gdb.tests.ITestConstants;
import org.junit.runner.RunWith;
@RunWith(BackgroundRunner.class)
public class MIExpressionsNonStopTest_7_1 extends MIExpressionsTest_7_1 {
@Override
protected void setGdbVersion() {
setGdbProgramNamesLaunchAttributes(ITestConstants.SUFFIX_GDB_7_1);
}
@Override
protected void setLaunchAttributes() {
super.setLaunchAttributes();
setLaunchAttribute(IGDBLaunchConfigurationConstants.ATTR_DEBUGGER_NON_STOP, true);
}
}

View file

@ -0,0 +1,31 @@
/*******************************************************************************
* Copyright (c) 2013 Ericsson and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Marc Khouzam (Ericsson) - Initial Implementation
*******************************************************************************/
package org.eclipse.cdt.tests.dsf.gdb.tests.tests_7_2;
import org.eclipse.cdt.dsf.gdb.IGDBLaunchConfigurationConstants;
import org.eclipse.cdt.tests.dsf.gdb.framework.BackgroundRunner;
import org.eclipse.cdt.tests.dsf.gdb.tests.ITestConstants;
import org.junit.runner.RunWith;
@RunWith(BackgroundRunner.class)
public class MIExpressionsNonStopTest_7_2 extends MIExpressionsTest_7_2 {
@Override
protected void setGdbVersion() {
setGdbProgramNamesLaunchAttributes(ITestConstants.SUFFIX_GDB_7_2);
}
@Override
protected void setLaunchAttributes() {
super.setLaunchAttributes();
setLaunchAttribute(IGDBLaunchConfigurationConstants.ATTR_DEBUGGER_NON_STOP, true);
}
}

View file

@ -0,0 +1,31 @@
/*******************************************************************************
* Copyright (c) 2013 Ericsson and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Marc Khouzam (Ericsson) - Initial Implementation
*******************************************************************************/
package org.eclipse.cdt.tests.dsf.gdb.tests.tests_7_3;
import org.eclipse.cdt.dsf.gdb.IGDBLaunchConfigurationConstants;
import org.eclipse.cdt.tests.dsf.gdb.framework.BackgroundRunner;
import org.eclipse.cdt.tests.dsf.gdb.tests.ITestConstants;
import org.junit.runner.RunWith;
@RunWith(BackgroundRunner.class)
public class MIExpressionsNonStopTest_7_3 extends MIExpressionsTest_7_3 {
@Override
protected void setGdbVersion() {
setGdbProgramNamesLaunchAttributes(ITestConstants.SUFFIX_GDB_7_3);
}
@Override
protected void setLaunchAttributes() {
super.setLaunchAttributes();
setLaunchAttribute(IGDBLaunchConfigurationConstants.ATTR_DEBUGGER_NON_STOP, true);
}
}

View file

@ -0,0 +1,31 @@
/*******************************************************************************
* Copyright (c) 2013 Ericsson and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Marc Khouzam (Ericsson) - Initial Implementation
*******************************************************************************/
package org.eclipse.cdt.tests.dsf.gdb.tests.tests_7_4;
import org.eclipse.cdt.dsf.gdb.IGDBLaunchConfigurationConstants;
import org.eclipse.cdt.tests.dsf.gdb.framework.BackgroundRunner;
import org.eclipse.cdt.tests.dsf.gdb.tests.ITestConstants;
import org.junit.runner.RunWith;
@RunWith(BackgroundRunner.class)
public class MIExpressionsNonStopTest_7_4 extends MIExpressionsTest_7_4 {
@Override
protected void setGdbVersion() {
setGdbProgramNamesLaunchAttributes(ITestConstants.SUFFIX_GDB_7_4);
}
@Override
protected void setLaunchAttributes() {
super.setLaunchAttributes();
setLaunchAttribute(IGDBLaunchConfigurationConstants.ATTR_DEBUGGER_NON_STOP, true);
}
}

View file

@ -0,0 +1,31 @@
/*******************************************************************************
* Copyright (c) 2013 Ericsson and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Marc Khouzam (Ericsson) - Initial Implementation
*******************************************************************************/
package org.eclipse.cdt.tests.dsf.gdb.tests.tests_7_5;
import org.eclipse.cdt.dsf.gdb.IGDBLaunchConfigurationConstants;
import org.eclipse.cdt.tests.dsf.gdb.framework.BackgroundRunner;
import org.eclipse.cdt.tests.dsf.gdb.tests.ITestConstants;
import org.junit.runner.RunWith;
@RunWith(BackgroundRunner.class)
public class MIExpressionsNonStopTest_7_5 extends MIExpressionsTest_7_5 {
@Override
protected void setGdbVersion() {
setGdbProgramNamesLaunchAttributes(ITestConstants.SUFFIX_GDB_7_5);
}
@Override
protected void setLaunchAttributes() {
super.setLaunchAttributes();
setLaunchAttribute(IGDBLaunchConfigurationConstants.ATTR_DEBUGGER_NON_STOP, true);
}
}

View file

@ -0,0 +1,31 @@
/*******************************************************************************
* Copyright (c) 2013 Ericsson and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Marc Khouzam (Ericsson) - Initial Implementation
*******************************************************************************/
package org.eclipse.cdt.tests.dsf.gdb.tests.tests_7_6;
import org.eclipse.cdt.dsf.gdb.IGDBLaunchConfigurationConstants;
import org.eclipse.cdt.tests.dsf.gdb.framework.BackgroundRunner;
import org.eclipse.cdt.tests.dsf.gdb.tests.ITestConstants;
import org.junit.runner.RunWith;
@RunWith(BackgroundRunner.class)
public class MIExpressionsNonStopTest_7_6 extends MIExpressionsTest_7_6 {
@Override
protected void setGdbVersion() {
setGdbProgramNamesLaunchAttributes(ITestConstants.SUFFIX_GDB_7_6);
}
@Override
protected void setLaunchAttributes() {
super.setLaunchAttributes();
setLaunchAttribute(IGDBLaunchConfigurationConstants.ATTR_DEBUGGER_NON_STOP, true);
}
}