From d06db08a303110c5debcc902235e4fb0e15a8555 Mon Sep 17 00:00:00 2001 From: Alvaro Sanchez-Leon Date: Mon, 17 Oct 2016 10:11:48 -0400 Subject: [PATCH] Bug 506073 - Support address "range" when adding a memory watchpoint Change-Id: If3130ed52df95b0481d95477727fc2f419251ade Signed-off-by: Alvaro Sanchez-Leon --- .../AbstractToggleBreakpointAdapter.java | 4 +++ .../dsf/gdb/service/GDBBreakpoints_7_0.java | 29 +++++++++++++++++++ .../cdt/dsf/mi/service/MIBreakpoints.java | 27 +++++++++++++---- .../dsf/mi/service/MIBreakpointsManager.java | 3 ++ 4 files changed, 58 insertions(+), 5 deletions(-) diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpoints/AbstractToggleBreakpointAdapter.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpoints/AbstractToggleBreakpointAdapter.java index d461ef758f5..932c9eb150a 100644 --- a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpoints/AbstractToggleBreakpointAdapter.java +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpoints/AbstractToggleBreakpointAdapter.java @@ -33,6 +33,7 @@ import org.eclipse.cdt.debug.core.model.ICBreakpoint; import org.eclipse.cdt.debug.core.model.ICFunctionBreakpoint; import org.eclipse.cdt.debug.core.model.ICLineBreakpoint; import org.eclipse.cdt.debug.core.model.ICWatchpoint; +import org.eclipse.cdt.debug.core.model.provisional.IMemorySpaceAwareMemoryBlock; import org.eclipse.cdt.debug.internal.core.CRequest; import org.eclipse.cdt.debug.internal.ui.CDebugUIUtils; import org.eclipse.cdt.debug.internal.ui.IInternalCDebugUIConstants; @@ -487,6 +488,9 @@ abstract public class AbstractToggleBreakpointAdapter private String getMemorySpace(IMemoryBlock memBlock, String def) { // XXX: In pre-CDI removal this retrieved memory space from CMemoryBlockExtension + if (memBlock != null && memBlock instanceof IMemorySpaceAwareMemoryBlock) { + return ((IMemorySpaceAwareMemoryBlock) memBlock).getMemorySpaceID(); + } return def; } diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBBreakpoints_7_0.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBBreakpoints_7_0.java index 33532245339..a59244eb645 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBBreakpoints_7_0.java +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBBreakpoints_7_0.java @@ -87,6 +87,35 @@ public class GDBBreakpoints_7_0 extends MIBreakpoints rm.done(); } + @Override + protected String adjustWatchPointExpression(final Map attributes, String origExpression) { + String adjustedExpression = origExpression; + if (!origExpression.isEmpty()) { + // Resolve the address range + String sRange = (String) getProperty(attributes, RANGE, NULL_STRING); + int addressRange = 0; + if (!sRange.equals(NULL_STRING)) { + try { + addressRange = Integer.valueOf(sRange); + } catch (NumberFormatException e) { + // No expression adjustment for an unexpected format + } + } + + if (addressRange > 1 && Character.isDigit(origExpression.charAt(0))) { + // Monitoring a range of addresses, + // The following line formats the string to a valid GDB expression + // i.e. casting to an array of char with the size given by range + // Taking the size of the character type to resolve the addressable size + adjustedExpression = String.format("*((char (*)[ %d ]) %s)", addressRange, origExpression); //$NON-NLS-1$ + } else if (Character.isDigit(origExpression.charAt(0))) { + // If expression is a single address, we need the '*' prefix. + adjustedExpression = "*" + origExpression; //$NON-NLS-1$ + } + } + return adjustedExpression; + } + @Override public void shutdown(RequestMonitor requestMonitor) { unregister(); diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/MIBreakpoints.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/MIBreakpoints.java index c58993e22a6..8e54bb5d970 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/MIBreakpoints.java +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/MIBreakpoints.java @@ -98,6 +98,11 @@ public class MIBreakpoints extends AbstractDsfService implements IBreakpoints, I public static final String EXPRESSION = PREFIX + ".expression"; //$NON-NLS-1$ public static final String READ = PREFIX + ".read"; //$NON-NLS-1$ public static final String WRITE = PREFIX + ".write"; //$NON-NLS-1$ + /** @since 5.3 */ + public static final String RANGE = PREFIX + ".range"; //$NON-NLS-1$ + /** @since 5.3 */ + public static final String MEMSPACE = PREFIX + ".memoryspace"; //$NON-NLS-1$ + // Catchpoint properties @@ -753,11 +758,8 @@ public class MIBreakpoints extends AbstractDsfService implements IBreakpoints, I boolean isRead = (Boolean) getProperty(attributes, READ, false); boolean isWrite = (Boolean) getProperty(attributes, WRITE, false); - if (!expression.isEmpty() && Character.isDigit(expression.charAt(0))) { - // If expression is an address, we need the '*' prefix. - expression = "*" + expression; //$NON-NLS-1$ - } - + expression = adjustWatchPointExpression(attributes, expression); + // The DataRequestMonitor for the add request DataRequestMonitor addWatchpointDRM = new DataRequestMonitor(getExecutor(), drm) { @@ -808,6 +810,21 @@ public class MIBreakpoints extends AbstractDsfService implements IBreakpoints, I fConnection.queueCommand(fCommandFactory.createMIBreakWatch(context, isRead, isWrite, expression), addWatchpointDRM); } + /** + * Adjust the expression to a format suitable for the debugger back end e.g. adding memory space, range, + * etc.. + * + * @since 5.3 + */ + protected String adjustWatchPointExpression(final Map attributes, String origExpression) { + String adjustedExpression = origExpression; + if (!origExpression.isEmpty() && Character.isDigit(origExpression.charAt(0))) { + // If expression is a single address, we need the '*' prefix. + adjustedExpression = "*" + origExpression; //$NON-NLS-1$ + } + return adjustedExpression; + } + /** * @since 3.0 */ diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/MIBreakpointsManager.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/MIBreakpointsManager.java index 91e06ae4465..b1f76e42b67 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/MIBreakpointsManager.java +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/MIBreakpointsManager.java @@ -45,6 +45,7 @@ import org.eclipse.cdt.debug.core.model.ICFunctionBreakpoint; import org.eclipse.cdt.debug.core.model.ICLineBreakpoint; import org.eclipse.cdt.debug.core.model.ICTracepoint; import org.eclipse.cdt.debug.core.model.ICWatchpoint; +import org.eclipse.cdt.debug.core.model.ICWatchpoint2; import org.eclipse.cdt.debug.internal.core.breakpoints.BreakpointProblems; import org.eclipse.cdt.dsf.concurrent.CountingRequestMonitor; import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor; @@ -2090,6 +2091,8 @@ public class MIBreakpointsManager extends AbstractDsfService implements IBreakpo properties.put(MIBreakpoints.EXPRESSION, attributes.get(ICWatchpoint.EXPRESSION)); properties.put(MIBreakpoints.READ, attributes.get(ICWatchpoint.READ)); properties.put(MIBreakpoints.WRITE, attributes.get(ICWatchpoint.WRITE)); + properties.put(MIBreakpoints.RANGE, attributes.get(ICWatchpoint2.RANGE)); + properties.put(MIBreakpoints.MEMSPACE, attributes.get(ICWatchpoint2.MEMORYSPACE)); } else if (breakpoint instanceof ICLineBreakpoint) { properties.put(MIBreakpoints.BREAKPOINT_TYPE, MIBreakpoints.BREAKPOINT);