mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-29 19:45:01 +02:00
Fix for Bug 213061
Expressions and Variables views do a full refresh on MemoryChangedEvent and ExpressionChangedEvent. MIVariableManager sets all varObjects to out-of-date when any varObject is modified by the user.
This commit is contained in:
parent
e8d462f047
commit
9150b06a8f
2 changed files with 51 additions and 37 deletions
|
@ -26,9 +26,9 @@ import org.eclipse.dd.dsf.datamodel.IDMContext;
|
||||||
import org.eclipse.dd.dsf.debug.internal.ui.DsfDebugUIPlugin;
|
import org.eclipse.dd.dsf.debug.internal.ui.DsfDebugUIPlugin;
|
||||||
import org.eclipse.dd.dsf.debug.service.IExpressions;
|
import org.eclipse.dd.dsf.debug.service.IExpressions;
|
||||||
import org.eclipse.dd.dsf.debug.service.IFormattedValues;
|
import org.eclipse.dd.dsf.debug.service.IFormattedValues;
|
||||||
|
import org.eclipse.dd.dsf.debug.service.IMemory;
|
||||||
import org.eclipse.dd.dsf.debug.service.IRunControl;
|
import org.eclipse.dd.dsf.debug.service.IRunControl;
|
||||||
import org.eclipse.dd.dsf.debug.service.IStack;
|
import org.eclipse.dd.dsf.debug.service.IStack;
|
||||||
import org.eclipse.dd.dsf.debug.service.IExpressions.IExpressionChangedDMEvent;
|
|
||||||
import org.eclipse.dd.dsf.debug.service.IExpressions.IExpressionDMContext;
|
import org.eclipse.dd.dsf.debug.service.IExpressions.IExpressionDMContext;
|
||||||
import org.eclipse.dd.dsf.debug.service.IExpressions.IExpressionDMData;
|
import org.eclipse.dd.dsf.debug.service.IExpressions.IExpressionDMData;
|
||||||
import org.eclipse.dd.dsf.debug.service.IFormattedValues.FormattedValueDMContext;
|
import org.eclipse.dd.dsf.debug.service.IFormattedValues.FormattedValueDMContext;
|
||||||
|
@ -77,14 +77,14 @@ public class VariableVMNode extends AbstractExpressionVMNode
|
||||||
* @see buildDelta()
|
* @see buildDelta()
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (e instanceof IRunControl.ISuspendedDMEvent) {
|
// When an expression changes or memory, we must do a full refresh
|
||||||
|
// see Bug 213061 and Bug 214550
|
||||||
|
if (e instanceof IRunControl.ISuspendedDMEvent ||
|
||||||
|
e instanceof IExpressions.IExpressionChangedDMEvent ||
|
||||||
|
e instanceof IMemory.IMemoryChangedEvent) {
|
||||||
return IModelDelta.CONTENT;
|
return IModelDelta.CONTENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( e instanceof IExpressions.IExpressionChangedDMEvent) {
|
|
||||||
return IModelDelta.STATE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (e instanceof PropertyChangeEvent &&
|
if (e instanceof PropertyChangeEvent &&
|
||||||
((PropertyChangeEvent)e).getProperty() == IDebugVMConstants.CURRENT_FORMAT_STORAGE)
|
((PropertyChangeEvent)e).getProperty() == IDebugVMConstants.CURRENT_FORMAT_STORAGE)
|
||||||
{
|
{
|
||||||
|
@ -96,19 +96,14 @@ public class VariableVMNode extends AbstractExpressionVMNode
|
||||||
|
|
||||||
public void buildDelta(final Object event, final VMDelta parentDelta, final int nodeOffset, final RequestMonitor requestMonitor) {
|
public void buildDelta(final Object event, final VMDelta parentDelta, final int nodeOffset, final RequestMonitor requestMonitor) {
|
||||||
|
|
||||||
if (event instanceof IRunControl.ISuspendedDMEvent) {
|
// When an expression changes or memory, we must do a full refresh
|
||||||
|
// see Bug 213061 and Bug 214550
|
||||||
|
if (event instanceof IRunControl.ISuspendedDMEvent ||
|
||||||
|
event instanceof IExpressions.IExpressionChangedDMEvent ||
|
||||||
|
event instanceof IMemory.IMemoryChangedEvent) {
|
||||||
parentDelta.setFlags(parentDelta.getFlags() | IModelDelta.CONTENT);
|
parentDelta.setFlags(parentDelta.getFlags() | IModelDelta.CONTENT);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( event instanceof IExpressions.IExpressionChangedDMEvent) {
|
|
||||||
/*
|
|
||||||
* Logically one would think that STATE should be specified here. But we specifiy CONTENT
|
|
||||||
* as well so that if there sub expressions which are affected in some way ( such as with
|
|
||||||
* an expanded union then they will show the changes also.
|
|
||||||
*/
|
|
||||||
parentDelta.addNode( createVMContext(((IExpressions.IExpressionChangedDMEvent)event).getDMContext()), IModelDelta.CONTENT | IModelDelta.STATE );
|
|
||||||
}
|
|
||||||
|
|
||||||
if (event instanceof PropertyChangeEvent &&
|
if (event instanceof PropertyChangeEvent &&
|
||||||
((PropertyChangeEvent)event).getProperty() == IDebugVMConstants.CURRENT_FORMAT_STORAGE)
|
((PropertyChangeEvent)event).getProperty() == IDebugVMConstants.CURRENT_FORMAT_STORAGE)
|
||||||
{
|
{
|
||||||
|
@ -492,11 +487,11 @@ public class VariableVMNode extends AbstractExpressionVMNode
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getDeltaFlagsForExpression(IExpression expression, Object event) {
|
public int getDeltaFlagsForExpression(IExpression expression, Object event) {
|
||||||
if (event instanceof IRunControl.ISuspendedDMEvent) {
|
// When an expression changes or memory, we must do a full refresh
|
||||||
return IModelDelta.CONTENT;
|
// see Bug 213061 and Bug 214550
|
||||||
}
|
if (event instanceof IRunControl.ISuspendedDMEvent ||
|
||||||
|
event instanceof IExpressions.IExpressionChangedDMEvent ||
|
||||||
if (event instanceof IExpressionChangedDMEvent) {
|
event instanceof IMemory.IMemoryChangedEvent) {
|
||||||
return IModelDelta.CONTENT;
|
return IModelDelta.CONTENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -517,20 +512,14 @@ public class VariableVMNode extends AbstractExpressionVMNode
|
||||||
public void buildDeltaForExpressionElement(Object element, int elementIdx, Object event, VMDelta parentDelta,
|
public void buildDeltaForExpressionElement(Object element, int elementIdx, Object event, VMDelta parentDelta,
|
||||||
RequestMonitor rm)
|
RequestMonitor rm)
|
||||||
{
|
{
|
||||||
if (event instanceof IRunControl.ISuspendedDMEvent) {
|
// When an expression changes or memory, we must do a full refresh
|
||||||
|
// see Bug 213061 and Bug 214550
|
||||||
|
if (event instanceof IRunControl.ISuspendedDMEvent ||
|
||||||
|
event instanceof IExpressions.IExpressionChangedDMEvent ||
|
||||||
|
event instanceof IMemory.IMemoryChangedEvent) {
|
||||||
parentDelta.setFlags(parentDelta.getFlags() | IModelDelta.CONTENT);
|
parentDelta.setFlags(parentDelta.getFlags() | IModelDelta.CONTENT);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( event instanceof IExpressions.IExpressionChangedDMEvent) {
|
|
||||||
/*
|
|
||||||
* Logically one would think that STATE should be specified here. But we specify CONTENT
|
|
||||||
* as well so that if there sub expressions which are affected in some way ( such as with
|
|
||||||
* an expanded union then they will show the changes also.
|
|
||||||
*/
|
|
||||||
parentDelta.addNode(element, IModelDelta.CONTENT);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (event instanceof PropertyChangeEvent &&
|
if (event instanceof PropertyChangeEvent &&
|
||||||
((PropertyChangeEvent)event).getProperty() == IDebugVMConstants.CURRENT_FORMAT_STORAGE)
|
((PropertyChangeEvent)event).getProperty() == IDebugVMConstants.CURRENT_FORMAT_STORAGE)
|
||||||
{
|
{
|
||||||
|
|
|
@ -818,7 +818,7 @@ public class MIVariableManager extends AbstractDsfService implements ICommandCon
|
||||||
* @param rm
|
* @param rm
|
||||||
* The request monitor to indicate the operation is finished
|
* The request monitor to indicate the operation is finished
|
||||||
*/
|
*/
|
||||||
private void writeValue(String value, final String formatId, final RequestMonitor rm) {
|
private void writeValue(String value, String formatId, final RequestMonitor rm) {
|
||||||
|
|
||||||
// If the variable is a complex structure (including an array), then we cannot write to it
|
// If the variable is a complex structure (including an array), then we cannot write to it
|
||||||
if (isComplex()) {
|
if (isComplex()) {
|
||||||
|
@ -830,8 +830,8 @@ public class MIVariableManager extends AbstractDsfService implements ICommandCon
|
||||||
|
|
||||||
// First deal with the format. For GDB, the way to specify a format is to prefix the value with
|
// First deal with the format. For GDB, the way to specify a format is to prefix the value with
|
||||||
// 0x for hex, 0 for octal etc So we need to make sure that 'value' has this prefix.
|
// 0x for hex, 0 for octal etc So we need to make sure that 'value' has this prefix.
|
||||||
// Note that there is no way to specify a binary format for GDB so we convert 'value'
|
// Note that there is no way to specify a binary format for GDB up to and including
|
||||||
// into a decimal format.
|
// GDB 6.7.1, so we convert 'value' into a decimal format.
|
||||||
// If the formatId is NATURAL, we do nothing for now because it is more complicated.
|
// If the formatId is NATURAL, we do nothing for now because it is more complicated.
|
||||||
// For example for a bool, a value of "true" is correct and should be left as is,
|
// For example for a bool, a value of "true" is correct and should be left as is,
|
||||||
// but for a pointer a value of 16 should be sent to GDB as 0x16. To figure this out,
|
// but for a pointer a value of 16 should be sent to GDB as 0x16. To figure this out,
|
||||||
|
@ -854,6 +854,8 @@ public class MIVariableManager extends AbstractDsfService implements ICommandCon
|
||||||
rm.done();
|
rm.done();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
formatId = IFormattedValues.DECIMAL_FORMAT;
|
||||||
}
|
}
|
||||||
else if (formatId.equals(IFormattedValues.DECIMAL_FORMAT)) {
|
else if (formatId.equals(IFormattedValues.DECIMAL_FORMAT)) {
|
||||||
// nothing to do
|
// nothing to do
|
||||||
|
@ -868,13 +870,36 @@ public class MIVariableManager extends AbstractDsfService implements ICommandCon
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If the value has not changed, no need to set it.
|
||||||
|
// Return a status info so that handleOK is not called and we don't send
|
||||||
|
// an ExpressionChanged event
|
||||||
|
if (value.equals(getValue(formatId))) {
|
||||||
|
rm.setStatus(new Status(IStatus.INFO, MIPlugin.PLUGIN_ID, IDsfService.NOT_SUPPORTED,
|
||||||
|
"Setting to the same value of: " + value, null)); //$NON-NLS-1$
|
||||||
|
rm.done();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// No need to be in ready state or to lock the object
|
// No need to be in ready state or to lock the object
|
||||||
fCommandControl.queueCommand(
|
fCommandControl.queueCommand(
|
||||||
new MIVarAssign(fControlDmc, getGdbName(), value),
|
new MIVarAssign(fControlDmc, getGdbName(), value),
|
||||||
new DataRequestMonitor<MIVarAssignInfo>(getExecutor(), rm) {
|
new DataRequestMonitor<MIVarAssignInfo>(getExecutor(), rm) {
|
||||||
@Override
|
@Override
|
||||||
protected void handleOK() {
|
protected void handleOK() {
|
||||||
resetValues(getData().getValue());
|
// We must also mark all variable objects
|
||||||
|
// as out-of-date. This is because some variable objects may be affected
|
||||||
|
// by this one having changed.
|
||||||
|
// e.g.,
|
||||||
|
// int i;
|
||||||
|
// int* pi = &i;
|
||||||
|
// Here, if 'i' is changed by the user, then 'pi' will also change
|
||||||
|
// Since there is no way to know this unless we keep track of all addresses,
|
||||||
|
// we must mark everything as out-of-date. See bug 213061
|
||||||
|
markAllOutOfDate();
|
||||||
|
|
||||||
|
// Useless since we just marked everything as out-of-date
|
||||||
|
// resetValues(getData().getValue());
|
||||||
|
|
||||||
rm.done();
|
rm.done();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
Loading…
Add table
Reference in a new issue