From 9150b06a8f745d78e202a2437475552506734b83 Mon Sep 17 00:00:00 2001 From: Marc Khouzam Date: Tue, 26 Feb 2008 20:04:41 +0000 Subject: [PATCH] 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. --- .../ui/viewmodel/variable/VariableVMNode.java | 55 ++++++++----------- .../dd/mi/service/MIVariableManager.java | 33 +++++++++-- 2 files changed, 51 insertions(+), 37 deletions(-) diff --git a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableVMNode.java b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableVMNode.java index 8e3883c4e36..077ed6ff17e 100644 --- a/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableVMNode.java +++ b/plugins/org.eclipse.dd.dsf.debug.ui/src/org/eclipse/dd/dsf/debug/ui/viewmodel/variable/VariableVMNode.java @@ -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.service.IExpressions; 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.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.IExpressionDMData; import org.eclipse.dd.dsf.debug.service.IFormattedValues.FormattedValueDMContext; @@ -77,13 +77,13 @@ public class VariableVMNode extends AbstractExpressionVMNode * @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; } - - if ( e instanceof IExpressions.IExpressionChangedDMEvent) { - return IModelDelta.STATE; - } if (e instanceof PropertyChangeEvent && ((PropertyChangeEvent)e).getProperty() == IDebugVMConstants.CURRENT_FORMAT_STORAGE) @@ -95,20 +95,15 @@ public class VariableVMNode extends AbstractExpressionVMNode } 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); } - 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 && ((PropertyChangeEvent)event).getProperty() == IDebugVMConstants.CURRENT_FORMAT_STORAGE) { @@ -492,14 +487,14 @@ public class VariableVMNode extends AbstractExpressionVMNode } public int getDeltaFlagsForExpression(IExpression expression, Object event) { - 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) { return IModelDelta.CONTENT; } - if (event instanceof IExpressionChangedDMEvent) { - return IModelDelta.CONTENT; - } - if (event instanceof PropertyChangeEvent && ((PropertyChangeEvent)event).getProperty() == IDebugVMConstants.CURRENT_FORMAT_STORAGE) { @@ -517,20 +512,14 @@ public class VariableVMNode extends AbstractExpressionVMNode public void buildDeltaForExpressionElement(Object element, int elementIdx, Object event, VMDelta parentDelta, 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); } - 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 && ((PropertyChangeEvent)event).getProperty() == IDebugVMConstants.CURRENT_FORMAT_STORAGE) { diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIVariableManager.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIVariableManager.java index a8cb20bf35d..b445a0619d4 100644 --- a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIVariableManager.java +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIVariableManager.java @@ -818,7 +818,7 @@ public class MIVariableManager extends AbstractDsfService implements ICommandCon * @param rm * 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 (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 // 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' - // into a decimal format. + // Note that there is no way to specify a binary format for GDB up to and including + // 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. // 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, @@ -854,6 +854,8 @@ public class MIVariableManager extends AbstractDsfService implements ICommandCon rm.done(); return; } + + formatId = IFormattedValues.DECIMAL_FORMAT; } else if (formatId.equals(IFormattedValues.DECIMAL_FORMAT)) { // nothing to do @@ -867,6 +869,16 @@ public class MIVariableManager extends AbstractDsfService implements ICommandCon rm.done(); 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 fCommandControl.queueCommand( @@ -874,7 +886,20 @@ public class MIVariableManager extends AbstractDsfService implements ICommandCon new DataRequestMonitor(getExecutor(), rm) { @Override 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(); } });