1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-06-07 17:56:01 +02:00

Bug 248595: Add support pending breakpoints introduced in GDB 6.8. This allows to set breakpoints in dlls before they are loaded. Note that the installation marker does not get updated after the breakoint is first set.

This commit is contained in:
Marc Khouzam 2010-08-26 17:58:47 +00:00
parent 5294511318
commit 0070cb3914
13 changed files with 466 additions and 100 deletions

View file

@ -24,6 +24,7 @@ import org.eclipse.cdt.dsf.debug.service.IRunControl;
import org.eclipse.cdt.dsf.debug.service.ISourceLookup; import org.eclipse.cdt.dsf.debug.service.ISourceLookup;
import org.eclipse.cdt.dsf.debug.service.IStack; import org.eclipse.cdt.dsf.debug.service.IStack;
import org.eclipse.cdt.dsf.debug.service.command.ICommandControl; import org.eclipse.cdt.dsf.debug.service.command.ICommandControl;
import org.eclipse.cdt.dsf.gdb.service.command.CommandFactory_6_8;
import org.eclipse.cdt.dsf.gdb.service.command.GDBControl; 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.gdb.service.command.GDBControl_7_0;
import org.eclipse.cdt.dsf.mi.service.CSourceLookup; import org.eclipse.cdt.dsf.mi.service.CSourceLookup;
@ -42,6 +43,7 @@ import org.eclipse.debug.core.ILaunchConfiguration;
public class GdbDebugServicesFactory extends AbstractDsfDebugServicesFactory { public class GdbDebugServicesFactory extends AbstractDsfDebugServicesFactory {
private static final String GDB_6_8_VERSION = "6.8"; //$NON-NLS-1$
// This should eventually be "7.0" once GDB 7.0 is released // This should eventually be "7.0" once GDB 7.0 is released
private static final String GDB_7_0_VERSION = "6.8.50.20090218"; //$NON-NLS-1$ private static final String GDB_7_0_VERSION = "6.8.50.20090218"; //$NON-NLS-1$
private static final String GDB_7_1_VERSION = "7.1"; //$NON-NLS-1$ private static final String GDB_7_1_VERSION = "7.1"; //$NON-NLS-1$
@ -99,7 +101,10 @@ public class GdbDebugServicesFactory extends AbstractDsfDebugServicesFactory {
protected ICommandControl createCommandControl(DsfSession session, ILaunchConfiguration config) { protected ICommandControl createCommandControl(DsfSession session, ILaunchConfiguration config) {
if (GDB_7_0_VERSION.compareTo(fVersion) <= 0) { if (GDB_7_0_VERSION.compareTo(fVersion) <= 0) {
return new GDBControl_7_0(session, config, new CommandFactory()); return new GDBControl_7_0(session, config, new CommandFactory_6_8());
}
if (GDB_6_8_VERSION.compareTo(fVersion) <= 0) {
return new GDBControl(session, config, new CommandFactory_6_8());
} }
return new GDBControl(session, config, new CommandFactory()); return new GDBControl(session, config, new CommandFactory());
} }

View file

@ -0,0 +1,40 @@
/*******************************************************************************
* 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.command;
import org.eclipse.cdt.dsf.debug.service.IBreakpoints.IBreakpointsTargetDMContext;
import org.eclipse.cdt.dsf.debug.service.command.ICommand;
import org.eclipse.cdt.dsf.mi.service.command.CommandFactory;
import org.eclipse.cdt.dsf.mi.service.command.commands.MIBreakInsert;
import org.eclipse.cdt.dsf.mi.service.command.output.MIBreakInsertInfo;
/**
* A command factory for commands that should only be used starting with GDB 6.8
* @since 4.0 */
public class CommandFactory_6_8 extends CommandFactory {
@Override
public ICommand<MIBreakInsertInfo> createMIBreakInsert(IBreakpointsTargetDMContext ctx, String func) {
return new MIBreakInsert(ctx, func, true);
}
@Override
public ICommand<MIBreakInsertInfo> createMIBreakInsert(IBreakpointsTargetDMContext ctx, boolean isTemporary,
boolean isHardware, String condition, int ignoreCount, String line, int tid) {
return new MIBreakInsert(ctx, isTemporary, isHardware, condition, ignoreCount, line, tid, true);
}
@Override
public ICommand<MIBreakInsertInfo> createMIBreakInsert(IBreakpointsTargetDMContext ctx, boolean isTemporary,
boolean isHardware, String condition, int ignoreCount, String location, int tid, boolean disabled, boolean isTracepoint) {
return new MIBreakInsert(ctx, isTemporary, isHardware, condition, ignoreCount, location, tid, disabled, isTracepoint, true);
}
}

View file

@ -353,4 +353,10 @@ public class MIBreakpointDMData implements IBreakpointDMData {
return fBreakpoint.isAccessWatchpoint(); return fBreakpoint.isAccessWatchpoint();
} }
/**
* @since 4.0
*/
public boolean isPending() {
return fBreakpoint.isPending();
}
} }

View file

@ -44,6 +44,7 @@ import org.eclipse.cdt.dsf.datamodel.DMContexts;
import org.eclipse.cdt.dsf.datamodel.IDMContext; import org.eclipse.cdt.dsf.datamodel.IDMContext;
import org.eclipse.cdt.dsf.debug.service.IBreakpoints; import org.eclipse.cdt.dsf.debug.service.IBreakpoints;
import org.eclipse.cdt.dsf.debug.service.IBreakpoints.IBreakpointDMContext; import org.eclipse.cdt.dsf.debug.service.IBreakpoints.IBreakpointDMContext;
import org.eclipse.cdt.dsf.debug.service.IBreakpoints.IBreakpointDMData;
import org.eclipse.cdt.dsf.debug.service.IBreakpoints.IBreakpointsTargetDMContext; import org.eclipse.cdt.dsf.debug.service.IBreakpoints.IBreakpointsTargetDMContext;
import org.eclipse.cdt.dsf.debug.service.IDsfBreakpointExtension; import org.eclipse.cdt.dsf.debug.service.IDsfBreakpointExtension;
import org.eclipse.cdt.dsf.debug.service.IRunControl; import org.eclipse.cdt.dsf.debug.service.IRunControl;
@ -588,12 +589,27 @@ public class MIBreakpointsManager extends AbstractDsfService implements IBreakpo
// Remove breakpoint problem marker (if any) // Remove breakpoint problem marker (if any)
removeBreakpointProblemMarker(breakpoint); removeBreakpointProblemMarker(breakpoint);
// Finally, update the platform breakpoint // Check for a pending breakpoint before showing that it was properly installed
try { fBreakpoints.getBreakpointDMData(targetBP, new DataRequestMonitor<IBreakpointDMData>(getExecutor(), null) {
breakpoint.incrementInstallCount(); @Override
} catch (CoreException e) { protected void handleCompleted() {
} boolean pending = false;
installRM.done(); if (isSuccess()) {
IBreakpointDMData data = getData();
if (data instanceof MIBreakpointDMData) {
pending = ((MIBreakpointDMData)data).isPending();
}
}
// Finally, update the platform breakpoint to show it was installed, unless we have a pending breakpoint
if (!pending) {
try {
breakpoint.incrementInstallCount();
} catch (CoreException e) {
}
}
installRM.done();
}
});
} }
@Override @Override
@ -712,7 +728,7 @@ public class MIBreakpointsManager extends AbstractDsfService implements IBreakpo
// Remove completion monitor // Remove completion monitor
// Upon completion, update the mappings // Upon completion, update the mappings
CountingRequestMonitor removeRM = new CountingRequestMonitor(getExecutor(), rm) { final CountingRequestMonitor removeRM = new CountingRequestMonitor(getExecutor(), rm) {
@Override @Override
protected void handleSuccess() { protected void handleSuccess() {
// Update the mappings // Update the mappings
@ -738,18 +754,44 @@ public class MIBreakpointsManager extends AbstractDsfService implements IBreakpo
Vector<IBreakpointDMContext> list = breakpointIDs.get(breakpoint); Vector<IBreakpointDMContext> list = breakpointIDs.get(breakpoint);
int count = 0; int count = 0;
if (list != null) { if (list != null) {
for (IBreakpointDMContext bp : list) { for (final IBreakpointDMContext bp : list) {
fBreakpoints.removeBreakpoint(bp, removeRM); decrementInstallCount(bp, breakpoint, new RequestMonitor(getExecutor(), removeRM) {
try { @Override
breakpoint.decrementInstallCount(); protected void handleCompleted() {
} catch (CoreException e) { fBreakpoints.removeBreakpoint(bp, removeRM);
} }
});
} }
count = list.size(); count = list.size();
} }
removeRM.setDoneCount(count); removeRM.setDoneCount(count);
} }
private void decrementInstallCount(IBreakpointDMContext targetDmc, final ICBreakpoint breakpoint, final RequestMonitor rm) {
fBreakpoints.getBreakpointDMData(targetDmc, new DataRequestMonitor<IBreakpointDMData>(getExecutor(), rm) {
@Override
protected void handleCompleted() {
boolean pending = false;
if (isSuccess()) {
IBreakpointDMData data = getData();
if (data instanceof MIBreakpointDMData) {
pending = ((MIBreakpointDMData)data).isPending();
}
}
// Finally, update the platform breakpoint to show it was un-installed.
// But we don't do this for pending breakpoints since they were
// not marked as installed.
if (!pending) {
try {
breakpoint.decrementInstallCount();
} catch (CoreException e) {
}
}
rm.done();
}
});
}
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
// modifyBreakpoint // modifyBreakpoint
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
@ -911,12 +953,14 @@ public class MIBreakpointsManager extends AbstractDsfService implements IBreakpo
// Get the list of new back-end breakpoints contexts // Get the list of new back-end breakpoints contexts
newTargetBPs.addAll(getData()); newTargetBPs.addAll(getData());
threadsIDs.put(breakpoint, newThreads); threadsIDs.put(breakpoint, newThreads);
for (IBreakpointDMContext ref : oldTargetBPs) { for (final IBreakpointDMContext ref : oldTargetBPs) {
fBreakpoints.removeBreakpoint(ref, removeRM); decrementInstallCount(ref, breakpoint, // A tad early but it should work...
try { new RequestMonitor(getExecutor(), removeRM) {
breakpoint.decrementInstallCount(); // A tad early but it should work... @Override
} catch (CoreException e) { protected void handleCompleted() {
} fBreakpoints.removeBreakpoint(ref, removeRM);
}
});
} }
removeRM.setDoneCount(oldTargetBPs.size()); removeRM.setDoneCount(oldTargetBPs.size());
} }
@ -991,11 +1035,28 @@ public class MIBreakpointsManager extends AbstractDsfService implements IBreakpo
protected void handleSuccess() { protected void handleSuccess() {
// Add the new back-end breakpoint context to the list // Add the new back-end breakpoint context to the list
breakpointList.add(getData()); breakpointList.add(getData());
try {
breakpoint.incrementInstallCount(); // Check for a pending breakpoint before showing that it was properly installed
} catch (CoreException e) { fBreakpoints.getBreakpointDMData(getData(), new DataRequestMonitor<IBreakpointDMData>(getExecutor(), null) {
} @Override
installRM.done(); protected void handleCompleted() {
boolean pending = false;
if (isSuccess()) {
IBreakpointDMData data = getData();
if (data instanceof MIBreakpointDMData) {
pending = ((MIBreakpointDMData)data).isPending();
}
}
// Finally, update the platform breakpoint to show it was installed, unless we have a pending breakpoint
if (!pending) {
try {
breakpoint.incrementInstallCount();
} catch (CoreException e) {
}
}
installRM.done();
}
});
} }
@Override @Override
@ -1341,8 +1402,8 @@ public class MIBreakpointsManager extends AbstractDsfService implements IBreakpo
Map<ICBreakpoint, Vector<IBreakpointDMContext>> breakpoints = fBreakpointIDs.get(ctx); Map<ICBreakpoint, Vector<IBreakpointDMContext>> breakpoints = fBreakpointIDs.get(ctx);
for (ICBreakpoint breakpoint : breakpoints.keySet()) { for (ICBreakpoint breakpoint : breakpoints.keySet()) {
Vector<IBreakpointDMContext> targetBps = breakpoints.get(breakpoint); Vector<IBreakpointDMContext> targetBps = breakpoints.get(breakpoint);
for (int i=0; i<targetBps.size(); i++) { for (IBreakpointDMContext targetBp : targetBps) {
breakpoint.decrementInstallCount(); decrementInstallCount(targetBp, breakpoint, new RequestMonitor(getExecutor(), null));
} }
} }
} }

View file

@ -285,19 +285,19 @@ public class CommandFactory {
} }
public ICommand<MIBreakInsertInfo> createMIBreakInsert(IBreakpointsTargetDMContext ctx, String func) { public ICommand<MIBreakInsertInfo> createMIBreakInsert(IBreakpointsTargetDMContext ctx, String func) {
return new MIBreakInsert(ctx, func); return new MIBreakInsert(ctx, func, false);
} }
public ICommand<MIBreakInsertInfo> createMIBreakInsert(IBreakpointsTargetDMContext ctx, boolean isTemporary, public ICommand<MIBreakInsertInfo> createMIBreakInsert(IBreakpointsTargetDMContext ctx, boolean isTemporary,
boolean isHardware, String condition, int ignoreCount, boolean isHardware, String condition, int ignoreCount,
String line, int tid) { String line, int tid) {
return new MIBreakInsert(ctx, isTemporary, isHardware, condition, ignoreCount, line, tid); return new MIBreakInsert(ctx, isTemporary, isHardware, condition, ignoreCount, line, tid, false);
} }
public ICommand<MIBreakInsertInfo> createMIBreakInsert(IBreakpointsTargetDMContext ctx, boolean isTemporary, public ICommand<MIBreakInsertInfo> createMIBreakInsert(IBreakpointsTargetDMContext ctx, boolean isTemporary,
boolean isHardware, String condition, int ignoreCount, boolean isHardware, String condition, int ignoreCount,
String location, int tid, boolean disabled, boolean isTracepoint) { String location, int tid, boolean disabled, boolean isTracepoint) {
return new MIBreakInsert(ctx, isTemporary, isHardware, condition, ignoreCount, location, tid, disabled, isTracepoint); return new MIBreakInsert(ctx, isTemporary, isHardware, condition, ignoreCount, location, tid, disabled, isTracepoint, false);
} }
public ICommand<MIBreakListInfo> createMIBreakList(IBreakpointsTargetDMContext ctx) { public ICommand<MIBreakListInfo> createMIBreakList(IBreakpointsTargetDMContext ctx) {

View file

@ -64,23 +64,26 @@ import org.eclipse.cdt.dsf.mi.service.command.output.MIOutput;
*/ */
public class MIBreakInsert extends MICommand<MIBreakInsertInfo> public class MIBreakInsert extends MICommand<MIBreakInsertInfo>
{ {
public MIBreakInsert(IBreakpointsTargetDMContext ctx, String func) { /** @since 4.0 */
this(ctx, false, false, null, 0, func, 0); public MIBreakInsert(IBreakpointsTargetDMContext ctx, String func, boolean allowPending) {
this(ctx, false, false, null, 0, func, 0, allowPending);
} }
/** @since 4.0 */
public MIBreakInsert(IBreakpointsTargetDMContext ctx, boolean isTemporary, boolean isHardware, public MIBreakInsert(IBreakpointsTargetDMContext ctx, boolean isTemporary, boolean isHardware,
String condition, int ignoreCount, String line, int tid) { String condition, int ignoreCount, String line, int tid, boolean allowPending) {
this(ctx, isTemporary, isHardware, condition, ignoreCount, line, tid, false, false); this(ctx, isTemporary, isHardware, condition, ignoreCount, line, tid, false, false, allowPending);
} }
/** /**
* This constructor allows to specify if the breakpoint should actually be * This constructor allows to specify if the breakpoint should actually be
* a tracepoint (this will only work starting with GDB 7.1) * a tracepoint (this will only work starting with GDB 7.1)
* It also includes if a breakpoint should be created disabled (starting GDB 7.0) * It also includes if a breakpoint should be created disabled (starting GDB 7.0)
* @since 3.0 * @since 4.0
*/ */
public MIBreakInsert(IBreakpointsTargetDMContext ctx, boolean isTemporary, boolean isHardware, public MIBreakInsert(IBreakpointsTargetDMContext ctx, boolean isTemporary, boolean isHardware,
String condition, int ignoreCount, String location, int tid, boolean disabled, boolean isTracepoint) { String condition, int ignoreCount, String location, int tid, boolean disabled, boolean isTracepoint,
boolean allowPending) {
super(ctx, "-break-insert"); //$NON-NLS-1$ super(ctx, "-break-insert"); //$NON-NLS-1$
// For a tracepoint, force certain parameters to what is allowed // For a tracepoint, force certain parameters to what is allowed
@ -118,6 +121,10 @@ public class MIBreakInsert extends MICommand<MIBreakInsertInfo>
if (isTracepoint) { if (isTracepoint) {
i++; i++;
} }
if (allowPending) {
i ++;
}
String[] opts = new String[i]; String[] opts = new String[i];
// Fill in the optional parameters // Fill in the optional parameters
@ -157,6 +164,10 @@ public class MIBreakInsert extends MICommand<MIBreakInsertInfo>
opts[i] = "-a"; //$NON-NLS-1$ opts[i] = "-a"; //$NON-NLS-1$
i++; i++;
} }
if (allowPending) {
opts[i] = "-f"; //$NON-NLS-1$
i ++;
}
if (opts.length > 0) { if (opts.length > 0) {
setOptions(opts); setOptions(opts);

View file

@ -49,7 +49,14 @@ import java.util.StringTokenizer;
* bkpt={number="5",type="tracepoint",disp="keep",enabled="y",addr="0x0804846b",func="main",file="hello.c",line="4",thread="0",thread="0",times="0"} * bkpt={number="5",type="tracepoint",disp="keep",enabled="y",addr="0x0804846b",func="main",file="hello.c",line="4",thread="0",thread="0",times="0"}
* bkpt={number="1",type="tracepoint",disp="keep",enabled="y",addr="0x0041bca0",func="main",file="hello.c",line="4",times="0",pass="4",original-location="hello.c:4"}, * bkpt={number="1",type="tracepoint",disp="keep",enabled="y",addr="0x0041bca0",func="main",file="hello.c",line="4",times="0",pass="4",original-location="hello.c:4"},
* bkpt={number="5",type="fast tracepoint",disp="keep",enabled="y",addr="0x0804852d",func="testTracepoints()",file="TracepointTestApp.cc",fullname="/local/src/TracepointTestApp.cc",line="84",times="0",original-location="TracepointTestApp.cc:84"} * bkpt={number="5",type="fast tracepoint",disp="keep",enabled="y",addr="0x0804852d",func="testTracepoints()",file="TracepointTestApp.cc",fullname="/local/src/TracepointTestApp.cc",line="84",times="0",original-location="TracepointTestApp.cc:84"}
* */ *
* Pending breakpoint
* -break-insert -f NotLoadedLibrary.c:26
* &"No source file named NotLoadedLibrary.c.\n"
* ^done,bkpt={number="9",type="breakpoint",disp="keep",enabled="y",addr="<PENDING>",pending="NotLoadedLibrary.c:26",times="0",original-location="NotLoadedLibrary.c:26"}
*
* Note that any breakpoint that fails to install will be marked as pending when the -f option is used.
*/
public class MIBreakpoint { public class MIBreakpoint {
int number = -1; int number = -1;
@ -87,6 +94,14 @@ public class MIBreakpoint {
/** See {@link #getCatchpointType()} */ /** See {@link #getCatchpointType()} */
private String catchpointType; private String catchpointType;
/**
* A pending breakpoint is a breakpoint that did not install properly,
* but that will be kept in the hopes that it installs later, triggered by
* the loading of a library.
* This concept is only supported starting with GDB 6.8
*/
private boolean pending;
public MIBreakpoint() { public MIBreakpoint() {
} }
@ -115,6 +130,7 @@ public class MIBreakpoint {
isTpt = other.isTpt; isTpt = other.isTpt;
isCatchpoint = other.isCatchpoint; isCatchpoint = other.isCatchpoint;
catchpointType = other.catchpointType; catchpointType = other.catchpointType;
pending = other.pending;
} }
public MIBreakpoint(MITuple tuple) { public MIBreakpoint(MITuple tuple) {
@ -382,6 +398,15 @@ public class MIBreakpoint {
commands = cmds; commands = cmds;
} }
/**
* Returns wether this breakpoint is pending
*
* @since 4.0
*/
public boolean isPending() {
return pending;
}
// Parse the result string // Parse the result string
void parse(MITuple tuple) { void parse(MITuple tuple) {
MIResult[] results = tuple.getMIResults(); MIResult[] results = tuple.getMIResults();
@ -468,6 +493,9 @@ public class MIBreakpoint {
} }
} else if (var.equals("cond")) { //$NON-NLS-1$ } else if (var.equals("cond")) { //$NON-NLS-1$
cond = str; cond = str;
} else if (var.equals("pending")) { //$NON-NLS-1$
// Only supported starting with GDB 6.8
pending = true;
} }
} }
} }

View file

@ -28,7 +28,7 @@ public class TestMIBreakInsertCommand {
@Test @Test
public void pathShouldNotContainDoubleBackSlashes() { public void pathShouldNotContainDoubleBackSlashes() {
MIBreakInsert target = new MIBreakInsert(new TestContext(), false, MIBreakInsert target = new MIBreakInsert(new TestContext(), false,
false, null, 1, "c:\\test\\this\\path:14", 4); false, null, 1, "c:\\test\\this\\path:14", 4, false);
assertEquals("Wrong syntax for command", assertEquals("Wrong syntax for command",
"-break-insert -i 1 -p 4 c:\\test\\this\\path:14\n", target "-break-insert -i 1 -p 4 c:\\test\\this\\path:14\n", target
@ -38,7 +38,7 @@ public class TestMIBreakInsertCommand {
@Test @Test
public void pathWithSlashesShouldNotBeSubstituted() { public void pathWithSlashesShouldNotBeSubstituted() {
MIBreakInsert target = new MIBreakInsert(new TestContext(), false, MIBreakInsert target = new MIBreakInsert(new TestContext(), false,
false, null, 1, "/test/this/path:14", 4); false, null, 1, "/test/this/path:14", 4, false);
assertEquals("Wrong syntax for command", assertEquals("Wrong syntax for command",
"-break-insert -i 1 -p 4 /test/this/path:14\n", target "-break-insert -i 1 -p 4 /test/this/path:14\n", target

View file

@ -88,58 +88,57 @@ public class MIBreakpointsTest extends BaseTestCase {
public static final String SOURCE_FILE = "BreakpointTestApp.cc"; //$NON-NLS-1$ public static final String SOURCE_FILE = "BreakpointTestApp.cc"; //$NON-NLS-1$
// Asynchronous Completion // Asynchronous Completion
private final AsyncCompletionWaitor fWait = new AsyncCompletionWaitor(); protected final AsyncCompletionWaitor fWait = new AsyncCompletionWaitor();
// Services references // Services references
private DsfSession fSession; protected DsfSession fSession;
private IBreakpointsTargetDMContext fBreakpointsDmc; protected IBreakpointsTargetDMContext fBreakpointsDmc;
private DsfServicesTracker fServicesTracker; protected DsfServicesTracker fServicesTracker;
private MIRunControl fRunControl; protected MIRunControl fRunControl;
private IBreakpoints fBreakpointService; protected IBreakpoints fBreakpointService;
// Event Management // Event Management
private static Boolean lock = true; protected static Boolean lock = true;
enum Events { BP_ADDED, BP_UPDATED, BP_REMOVED, BP_HIT, WP_HIT, WP_OOS } protected enum Events { BP_ADDED, BP_UPDATED, BP_REMOVED, BP_HIT, WP_HIT, WP_OOS }
final int BP_ADDED = Events.BP_ADDED.ordinal(); protected final int BP_ADDED = Events.BP_ADDED.ordinal();
final int BP_UPDATED = Events.BP_UPDATED.ordinal(); protected final int BP_UPDATED = Events.BP_UPDATED.ordinal();
final int BP_REMOVED = Events.BP_REMOVED.ordinal(); protected final int BP_REMOVED = Events.BP_REMOVED.ordinal();
final int BP_HIT = Events.BP_HIT.ordinal(); protected final int BP_HIT = Events.BP_HIT.ordinal();
final int WP_HIT = Events.WP_HIT.ordinal(); protected final int WP_HIT = Events.WP_HIT.ordinal();
final int WP_OOS = Events.WP_OOS.ordinal(); protected final int WP_OOS = Events.WP_OOS.ordinal();
private int[] fBreakpointEvents = new int[Events.values().length]; protected int[] fBreakpointEvents = new int[Events.values().length];
private int fBreakpointEventCount; protected int fBreakpointEventCount;
private int fBreakpointRef; protected int fBreakpointRef;
// Some useful constants // Some useful constants
final String BREAKPOINT_TYPE_TAG = MIBreakpoints.BREAKPOINT_TYPE; protected final String BREAKPOINT_TYPE_TAG = MIBreakpoints.BREAKPOINT_TYPE;
final String BREAKPOINT_TAG = MIBreakpoints.BREAKPOINT; protected final String BREAKPOINT_TAG = MIBreakpoints.BREAKPOINT;
final String WATCHPOINT_TAG = MIBreakpoints.WATCHPOINT; protected final String WATCHPOINT_TAG = MIBreakpoints.WATCHPOINT;
final String FILE_NAME_TAG = MIBreakpoints.FILE_NAME; protected final String FILE_NAME_TAG = MIBreakpoints.FILE_NAME;
final String LINE_NUMBER_TAG = MIBreakpoints.LINE_NUMBER; protected final String LINE_NUMBER_TAG = MIBreakpoints.LINE_NUMBER;
final String FUNCTION_TAG = MIBreakpoints.FUNCTION; protected final String FUNCTION_TAG = MIBreakpoints.FUNCTION;
final String ADDRESS_TAG = MIBreakpoints.ADDRESS; protected final String ADDRESS_TAG = MIBreakpoints.ADDRESS;
final String CONDITION_TAG = MIBreakpoints.CONDITION; protected final String CONDITION_TAG = MIBreakpoints.CONDITION;
final String IGNORE_COUNT_TAG = MIBreakpoints.IGNORE_COUNT; protected final String IGNORE_COUNT_TAG = MIBreakpoints.IGNORE_COUNT;
final String IS_ENABLED_TAG = MIBreakpoints.IS_ENABLED; protected final String IS_ENABLED_TAG = MIBreakpoints.IS_ENABLED;
final String THREAD_ID_TAG = MIBreakpointDMData.THREAD_ID; protected final String THREAD_ID_TAG = MIBreakpointDMData.THREAD_ID;
final String NUMBER_TAG = MIBreakpointDMData.NUMBER; protected final String NUMBER_TAG = MIBreakpointDMData.NUMBER;
final String EXPRESSION_TAG = MIBreakpoints.EXPRESSION; protected final String EXPRESSION_TAG = MIBreakpoints.EXPRESSION;
final String READ_TAG = MIBreakpoints.READ; protected final String READ_TAG = MIBreakpoints.READ;
final String WRITE_TAG = MIBreakpoints.WRITE; protected final String WRITE_TAG = MIBreakpoints.WRITE;
// Target application 'special' locations // Target application 'special' locations
private final int LINE_NUMBER_1 = 20; protected final int LINE_NUMBER_1 = 20;
private final int LINE_NUMBER_2 = 21; protected final int LINE_NUMBER_2 = 21;
@SuppressWarnings("unused") protected final int LINE_NUMBER_3 = 27;
private final int LINE_NUMBER_3 = 27; protected final int LINE_NUMBER_4 = 36;
private final int LINE_NUMBER_4 = 36; protected final int LINE_NUMBER_5 = 49;
private final int LINE_NUMBER_5 = 49; protected final int LINE_NUMBER_6 = 50;
private final int LINE_NUMBER_6 = 50; protected final String FUNCTION = "zeroBlocks";
private final String FUNCTION = "zeroBlocks"; protected final String SIGNED_FUNCTION = "zeroBlocks(int)";
private final String SIGNED_FUNCTION = "zeroBlocks(int)"; protected final String NO_CONDITION = "";
private final String NO_CONDITION = "";
// NOTE: The back-end can reformat the condition. In order for the // NOTE: The back-end can reformat the condition. In order for the
// comparison to work, better specify the condition as the back-end // comparison to work, better specify the condition as the back-end
@ -157,10 +156,10 @@ public class MIBreakpointsTest extends BaseTestCase {
private final String EXPRESSION_3 = "a"; private final String EXPRESSION_3 = "a";
// Error messages // Error messages
final String UNKNOWN_EXECUTION_CONTEXT = "Unknown execution context"; protected final String UNKNOWN_EXECUTION_CONTEXT = "Unknown execution context";
final String INVALID_BREAKPOINT_LOCATION = "Invalid breakpoint location"; protected final String INVALID_BREAKPOINT_LOCATION = "Invalid breakpoint location";
final String BREAKPOINT_INSERTION_FAILURE = "Breakpoint insertion failure"; protected final String BREAKPOINT_INSERTION_FAILURE = "Breakpoint insertion failure";
final String UNKNOWN_BREAKPOINT = "Unknown breakpoint"; protected final String UNKNOWN_BREAKPOINT = "Unknown breakpoint";
// ======================================================================== // ========================================================================
// Housekeeping stuff // Housekeeping stuff
@ -292,7 +291,7 @@ public class MIBreakpointsTest extends BaseTestCase {
} }
// Clears the counters // Clears the counters
private void clearEventCounters() { protected void clearEventCounters() {
synchronized (lock) { synchronized (lock) {
for (int i = 0; i < fBreakpointEvents.length; i++) { for (int i = 0; i < fBreakpointEvents.length; i++) {
fBreakpointEvents[i] = 0; fBreakpointEvents[i] = 0;
@ -302,7 +301,7 @@ public class MIBreakpointsTest extends BaseTestCase {
} }
// Get the breakpoint hit count // Get the breakpoint hit count
private int getBreakpointEventCount(int event) { protected int getBreakpointEventCount(int event) {
int count = 0; int count = 0;
synchronized (lock) { synchronized (lock) {
count = fBreakpointEvents[event]; count = fBreakpointEvents[event];
@ -340,7 +339,7 @@ public class MIBreakpointsTest extends BaseTestCase {
/** /**
* Simplified variant that just waits up to two seconds * Simplified variant that just waits up to two seconds
*/ */
private void waitForBreakpointEvent(int count) throws Exception { protected void waitForBreakpointEvent(int count) throws Exception {
waitForBreakpointEvent(count, TestsPlugin.massageTimeout(2000)); waitForBreakpointEvent(count, TestsPlugin.massageTimeout(2000));
} }
@ -413,7 +412,7 @@ public class MIBreakpointsTest extends BaseTestCase {
* @param context the execution context * @param context the execution context
* ------------------------------------------------------------------------ * ------------------------------------------------------------------------
*/ */
private IBreakpointDMContext[] getBreakpoints(final IBreakpointsTargetDMContext context) throws InterruptedException protected IBreakpointDMContext[] getBreakpoints(final IBreakpointsTargetDMContext context) throws InterruptedException
{ {
// Clear the completion waiter // Clear the completion waiter
fWait.waitReset(); fWait.waitReset();
@ -455,7 +454,7 @@ public class MIBreakpointsTest extends BaseTestCase {
* @param breakpoint the breakpoint to retrieve * @param breakpoint the breakpoint to retrieve
* ------------------------------------------------------------------------ * ------------------------------------------------------------------------
*/ */
private IBreakpointDMData getBreakpoint(final IBreakpointDMContext breakpoint) throws InterruptedException protected IBreakpointDMData getBreakpoint(final IBreakpointDMContext breakpoint) throws InterruptedException
{ {
// Clear the completion waiter // Clear the completion waiter
fWait.waitReset(); fWait.waitReset();
@ -534,7 +533,7 @@ public class MIBreakpointsTest extends BaseTestCase {
* @param attributes the breakpoint attributes * @param attributes the breakpoint attributes
* ------------------------------------------------------------------------ * ------------------------------------------------------------------------
*/ */
private IBreakpointDMContext insertBreakpoint(final IBreakpointsTargetDMContext context, protected IBreakpointDMContext insertBreakpoint(final IBreakpointsTargetDMContext context,
final Map<String,Object> attributes) throws InterruptedException final Map<String,Object> attributes) throws InterruptedException
{ {
// Clear the completion waiter // Clear the completion waiter
@ -821,6 +820,8 @@ public class MIBreakpointsTest extends BaseTestCase {
breakpoint1.getIgnoreCount() == 0); breakpoint1.getIgnoreCount() == 0);
assertTrue("BreakpointService problem: breakpoint mismatch (wrong state)", assertTrue("BreakpointService problem: breakpoint mismatch (wrong state)",
breakpoint1.isEnabled()); breakpoint1.isEnabled());
assertTrue("BreakpointService problem: breakpoint mismatch (pending)",
!breakpoint1.isPending());
// Ensure the BreakpointService holds only the right breakpoints // Ensure the BreakpointService holds only the right breakpoints
IBreakpointDMContext[] breakpoints = getBreakpoints(fBreakpointsDmc); IBreakpointDMContext[] breakpoints = getBreakpoints(fBreakpointsDmc);
@ -869,6 +870,8 @@ public class MIBreakpointsTest extends BaseTestCase {
breakpoint1.getIgnoreCount() == 0); breakpoint1.getIgnoreCount() == 0);
assertTrue("BreakpointService problem: breakpoint mismatch (wrong state)", assertTrue("BreakpointService problem: breakpoint mismatch (wrong state)",
breakpoint1.isEnabled()); breakpoint1.isEnabled());
assertTrue("BreakpointService problem: breakpoint mismatch (pending)",
!breakpoint1.isPending());
// Ensure the BreakpointService holds only the right breakpoints // Ensure the BreakpointService holds only the right breakpoints
IBreakpointDMContext[] breakpoints = getBreakpoints(fBreakpointsDmc); IBreakpointDMContext[] breakpoints = getBreakpoints(fBreakpointsDmc);
@ -918,6 +921,8 @@ public class MIBreakpointsTest extends BaseTestCase {
breakpoint1.getIgnoreCount() == 0); breakpoint1.getIgnoreCount() == 0);
assertTrue("BreakpointService problem: breakpoint mismatch (wrong state)", assertTrue("BreakpointService problem: breakpoint mismatch (wrong state)",
!breakpoint1.isEnabled()); !breakpoint1.isEnabled());
assertTrue("BreakpointService problem: breakpoint mismatch (pending)",
!breakpoint1.isPending());
// Ensure the BreakpointService holds only the right breakpoints // Ensure the BreakpointService holds only the right breakpoints
IBreakpointDMContext[] breakpoints = getBreakpoints(fBreakpointsDmc); IBreakpointDMContext[] breakpoints = getBreakpoints(fBreakpointsDmc);
@ -964,6 +969,8 @@ public class MIBreakpointsTest extends BaseTestCase {
breakpoint1.getCondition().equals(NO_CONDITION)); breakpoint1.getCondition().equals(NO_CONDITION));
assertTrue("BreakpointService problem: breakpoint mismatch (wrong ignore count)", assertTrue("BreakpointService problem: breakpoint mismatch (wrong ignore count)",
breakpoint1.getIgnoreCount() == 0); breakpoint1.getIgnoreCount() == 0);
assertTrue("BreakpointService problem: breakpoint mismatch (pending)",
!breakpoint1.isPending());
// Ensure the BreakpointService holds only the right breakpoints // Ensure the BreakpointService holds only the right breakpoints
IBreakpointDMContext[] breakpoints = getBreakpoints(fBreakpointsDmc); IBreakpointDMContext[] breakpoints = getBreakpoints(fBreakpointsDmc);
@ -1011,6 +1018,8 @@ public class MIBreakpointsTest extends BaseTestCase {
breakpoint1.getCondition().equals(CONDITION_1)); breakpoint1.getCondition().equals(CONDITION_1));
assertTrue("BreakpointService problem: breakpoint mismatch (wrong ignore count)", assertTrue("BreakpointService problem: breakpoint mismatch (wrong ignore count)",
breakpoint1.getIgnoreCount() == 0); breakpoint1.getIgnoreCount() == 0);
assertTrue("BreakpointService problem: breakpoint mismatch (pending)",
!breakpoint1.isPending());
// Ensure the BreakpointService holds only the right breakpoints // Ensure the BreakpointService holds only the right breakpoints
IBreakpointDMContext[] breakpoints = getBreakpoints(fBreakpointsDmc); IBreakpointDMContext[] breakpoints = getBreakpoints(fBreakpointsDmc);
@ -1058,6 +1067,8 @@ public class MIBreakpointsTest extends BaseTestCase {
breakpoint1.getCondition().equals(NO_CONDITION)); breakpoint1.getCondition().equals(NO_CONDITION));
assertTrue("BreakpointService problem: breakpoint mismatch (wrong ignore count)", assertTrue("BreakpointService problem: breakpoint mismatch (wrong ignore count)",
breakpoint1.getIgnoreCount() == IGNORE_COUNT_1); breakpoint1.getIgnoreCount() == IGNORE_COUNT_1);
assertTrue("BreakpointService problem: breakpoint mismatch (pending)",
!breakpoint1.isPending());
// Ensure the BreakpointService holds only the right breakpoints // Ensure the BreakpointService holds only the right breakpoints
IBreakpointDMContext[] breakpoints = getBreakpoints(fBreakpointsDmc); IBreakpointDMContext[] breakpoints = getBreakpoints(fBreakpointsDmc);
@ -1104,6 +1115,8 @@ public class MIBreakpointsTest extends BaseTestCase {
breakpoint1.getCondition().equals(NO_CONDITION)); breakpoint1.getCondition().equals(NO_CONDITION));
assertTrue("BreakpointService problem: breakpoint mismatch (wrong ignore count)", assertTrue("BreakpointService problem: breakpoint mismatch (wrong ignore count)",
breakpoint1.getIgnoreCount() == 0); breakpoint1.getIgnoreCount() == 0);
assertTrue("BreakpointService problem: breakpoint mismatch (pending)",
!breakpoint1.isPending());
// Create a function breakpoint // Create a function breakpoint
breakpoint = new HashMap<String, Object>(); breakpoint = new HashMap<String, Object>();
@ -1133,6 +1146,8 @@ public class MIBreakpointsTest extends BaseTestCase {
breakpoint2.getCondition().equals(NO_CONDITION)); breakpoint2.getCondition().equals(NO_CONDITION));
assertTrue("BreakpointService problem: breakpoint mismatch (wrong ignore count)", assertTrue("BreakpointService problem: breakpoint mismatch (wrong ignore count)",
breakpoint2.getIgnoreCount() == 0); breakpoint2.getIgnoreCount() == 0);
assertTrue("BreakpointService problem: breakpoint mismatch (pending)",
!breakpoint2.isPending());
// Ensure the BreakpointService holds only the right breakpoints // Ensure the BreakpointService holds only the right breakpoints
IBreakpointDMContext[] breakpoints = getBreakpoints(fBreakpointsDmc); IBreakpointDMContext[] breakpoints = getBreakpoints(fBreakpointsDmc);
@ -1190,6 +1205,8 @@ public class MIBreakpointsTest extends BaseTestCase {
breakpoint1.getCondition().equals(NO_CONDITION)); breakpoint1.getCondition().equals(NO_CONDITION));
assertTrue("BreakpointService problem: breakpoint mismatch (wrong ignore count)", assertTrue("BreakpointService problem: breakpoint mismatch (wrong ignore count)",
breakpoint1.getIgnoreCount() == 0); breakpoint1.getIgnoreCount() == 0);
assertTrue("BreakpointService problem: breakpoint mismatch (pending)",
!breakpoint1.isPending());
// Create a second line breakpoint, same attributes... // Create a second line breakpoint, same attributes...
ref = insertBreakpoint(fBreakpointsDmc, breakpoint); ref = insertBreakpoint(fBreakpointsDmc, breakpoint);
@ -1213,6 +1230,8 @@ public class MIBreakpointsTest extends BaseTestCase {
breakpoint2.getCondition().equals(NO_CONDITION)); breakpoint2.getCondition().equals(NO_CONDITION));
assertTrue("BreakpointService problem: breakpoint mismatch (wrong ignore count)", assertTrue("BreakpointService problem: breakpoint mismatch (wrong ignore count)",
breakpoint2.getIgnoreCount() == 0); breakpoint2.getIgnoreCount() == 0);
assertTrue("BreakpointService problem: breakpoint mismatch (pending)",
!breakpoint2.isPending());
// Ensure the BreakpointService holds only the right breakpoints // Ensure the BreakpointService holds only the right breakpoints
IBreakpointDMContext[] breakpoints = getBreakpoints(fBreakpointsDmc); IBreakpointDMContext[] breakpoints = getBreakpoints(fBreakpointsDmc);
@ -1276,6 +1295,8 @@ public class MIBreakpointsTest extends BaseTestCase {
+ getBreakpointEventCount(BP_HIT), getBreakpointEventCount(BP_HIT) == 1); + getBreakpointEventCount(BP_HIT), getBreakpointEventCount(BP_HIT) == 1);
assertTrue("BreakpointService problem: breakpoint mismatch", assertTrue("BreakpointService problem: breakpoint mismatch",
fBreakpointRef == breakpoint1.getNumber()); fBreakpointRef == breakpoint1.getNumber());
assertTrue("BreakpointService problem: breakpoint mismatch (pending)",
!breakpoint1.isPending());
clearEventCounters(); clearEventCounters();
assertTrue("Did not stop because of breakpoint, but stopped because of: " + assertTrue("Did not stop because of breakpoint, but stopped because of: " +
@ -1334,6 +1355,8 @@ public class MIBreakpointsTest extends BaseTestCase {
+ getBreakpointEventCount(BP_HIT), getBreakpointEventCount(BP_HIT) == 1); + getBreakpointEventCount(BP_HIT), getBreakpointEventCount(BP_HIT) == 1);
assertTrue("BreakpointService problem: breakpoint mismatch", assertTrue("BreakpointService problem: breakpoint mismatch",
fBreakpointRef == breakpoint1.getNumber()); fBreakpointRef == breakpoint1.getNumber());
assertTrue("BreakpointService problem: breakpoint mismatch (pending)",
!breakpoint1.isPending());
clearEventCounters(); clearEventCounters();
assertTrue("Did not stop because of breakpoint, but stopped because of: " + assertTrue("Did not stop because of breakpoint, but stopped because of: " +
@ -1382,6 +1405,9 @@ public class MIBreakpointsTest extends BaseTestCase {
watchpoint1.isWriteWatchpoint()); watchpoint1.isWriteWatchpoint());
assertTrue("BreakpointService problem: watchpoint mismatch (wrong access state)", assertTrue("BreakpointService problem: watchpoint mismatch (wrong access state)",
!watchpoint1.isAccessWatchpoint()); !watchpoint1.isAccessWatchpoint());
assertTrue("BreakpointService problem: breakpoint mismatch (pending)",
!watchpoint1.isPending());
// Ensure the BreakpointService holds only the right watchpoints // Ensure the BreakpointService holds only the right watchpoints
IBreakpointDMContext[] watchpoints = getBreakpoints(fBreakpointsDmc); IBreakpointDMContext[] watchpoints = getBreakpoints(fBreakpointsDmc);
@ -1428,6 +1454,8 @@ public class MIBreakpointsTest extends BaseTestCase {
!watchpoint1.isWriteWatchpoint()); !watchpoint1.isWriteWatchpoint());
assertTrue("BreakpointService problem: watchpoint mismatch (wrong access state)", assertTrue("BreakpointService problem: watchpoint mismatch (wrong access state)",
!watchpoint1.isAccessWatchpoint()); !watchpoint1.isAccessWatchpoint());
assertTrue("BreakpointService problem: breakpoint mismatch (pending)",
!watchpoint1.isPending());
// Ensure the BreakpointService holds only the right watchpoints // Ensure the BreakpointService holds only the right watchpoints
IBreakpointDMContext[] watchpoints = getBreakpoints(fBreakpointsDmc); IBreakpointDMContext[] watchpoints = getBreakpoints(fBreakpointsDmc);
@ -1475,6 +1503,8 @@ public class MIBreakpointsTest extends BaseTestCase {
!watchpoint1.isWriteWatchpoint()); !watchpoint1.isWriteWatchpoint());
assertTrue("BreakpointService problem: watchpoint mismatch (wrong access state)", assertTrue("BreakpointService problem: watchpoint mismatch (wrong access state)",
watchpoint1.isAccessWatchpoint()); watchpoint1.isAccessWatchpoint());
assertTrue("BreakpointService problem: breakpoint mismatch (pending)",
!watchpoint1.isPending());
// Ensure the BreakpointService holds only the right watchpoints // Ensure the BreakpointService holds only the right watchpoints
IBreakpointDMContext[] watchpoints = getBreakpoints(fBreakpointsDmc); IBreakpointDMContext[] watchpoints = getBreakpoints(fBreakpointsDmc);
@ -1538,6 +1568,8 @@ public class MIBreakpointsTest extends BaseTestCase {
watchpoint1.isWriteWatchpoint()); watchpoint1.isWriteWatchpoint());
assertTrue("BreakpointService problem: watchpoint mismatch (wrong access state)", assertTrue("BreakpointService problem: watchpoint mismatch (wrong access state)",
!watchpoint1.isAccessWatchpoint()); !watchpoint1.isAccessWatchpoint());
assertTrue("BreakpointService problem: breakpoint mismatch (pending)",
!watchpoint1.isPending());
// Ensure the BreakpointService holds only the right watchpoints // Ensure the BreakpointService holds only the right watchpoints
IBreakpointDMContext[] watchpoints = getBreakpoints(fBreakpointsDmc); IBreakpointDMContext[] watchpoints = getBreakpoints(fBreakpointsDmc);
@ -2792,6 +2824,8 @@ public class MIBreakpointsTest extends BaseTestCase {
+ getBreakpointEventCount(BP_HIT), getBreakpointEventCount(BP_HIT) == 1); + getBreakpointEventCount(BP_HIT), getBreakpointEventCount(BP_HIT) == 1);
assertTrue("BreakpointService problem: breakpoint mismatch", assertTrue("BreakpointService problem: breakpoint mismatch",
fBreakpointRef == breakpoint1.getNumber()); fBreakpointRef == breakpoint1.getNumber());
assertTrue("BreakpointService problem: breakpoint mismatch (pending)",
!breakpoint1.isPending());
clearEventCounters(); clearEventCounters();
} }
@ -2832,6 +2866,8 @@ public class MIBreakpointsTest extends BaseTestCase {
+ getBreakpointEventCount(BP_HIT), getBreakpointEventCount(BP_HIT) == 1); + getBreakpointEventCount(BP_HIT), getBreakpointEventCount(BP_HIT) == 1);
assertTrue("BreakpointService problem: breakpoint mismatch", assertTrue("BreakpointService problem: breakpoint mismatch",
fBreakpointRef == breakpoint1.getNumber()); fBreakpointRef == breakpoint1.getNumber());
assertTrue("BreakpointService problem: breakpoint mismatch (pending)",
!breakpoint1.isPending());
clearEventCounters(); clearEventCounters();
} }
@ -2876,6 +2912,8 @@ public class MIBreakpointsTest extends BaseTestCase {
+ getBreakpointEventCount(BP_HIT), getBreakpointEventCount(BP_HIT) == 1); + getBreakpointEventCount(BP_HIT), getBreakpointEventCount(BP_HIT) == 1);
assertTrue("BreakpointService problem: breakpoint mismatch", assertTrue("BreakpointService problem: breakpoint mismatch",
fBreakpointRef == breakpoint1.getNumber()); fBreakpointRef == breakpoint1.getNumber());
assertTrue("BreakpointService problem: breakpoint mismatch (pending)",
!breakpoint1.isPending());
clearEventCounters(); clearEventCounters();
// Verify that the condition is met // Verify that the condition is met
@ -2937,6 +2975,8 @@ public class MIBreakpointsTest extends BaseTestCase {
+ getBreakpointEventCount(BP_HIT), getBreakpointEventCount(BP_HIT) == 1); + getBreakpointEventCount(BP_HIT), getBreakpointEventCount(BP_HIT) == 1);
assertTrue("BreakpointService problem: breakpoint mismatch", assertTrue("BreakpointService problem: breakpoint mismatch",
fBreakpointRef == breakpoint1.getNumber()); fBreakpointRef == breakpoint1.getNumber());
assertTrue("BreakpointService problem: breakpoint mismatch (pending)",
!breakpoint1.isPending());
clearEventCounters(); clearEventCounters();
// Verify that the condition is met // Verify that the condition is met
@ -2985,6 +3025,8 @@ public class MIBreakpointsTest extends BaseTestCase {
+ getBreakpointEventCount(BP_HIT), getBreakpointEventCount(BP_HIT) == 1); + getBreakpointEventCount(BP_HIT), getBreakpointEventCount(BP_HIT) == 1);
assertTrue("BreakpointService problem: breakpoint mismatch", assertTrue("BreakpointService problem: breakpoint mismatch",
fBreakpointRef == breakpoint1.getNumber()); fBreakpointRef == breakpoint1.getNumber());
assertTrue("BreakpointService problem: breakpoint mismatch (pending)",
!breakpoint1.isPending());
clearEventCounters(); clearEventCounters();
// Verify that the condition is met // Verify that the condition is met
@ -3046,6 +3088,8 @@ public class MIBreakpointsTest extends BaseTestCase {
+ getBreakpointEventCount(BP_HIT), getBreakpointEventCount(BP_HIT) == 1); + getBreakpointEventCount(BP_HIT), getBreakpointEventCount(BP_HIT) == 1);
assertTrue("BreakpointService problem: breakpoint mismatch", assertTrue("BreakpointService problem: breakpoint mismatch",
fBreakpointRef == breakpoint1.getNumber()); fBreakpointRef == breakpoint1.getNumber());
assertTrue("BreakpointService problem: breakpoint mismatch (pending)",
!breakpoint1.isPending());
clearEventCounters(); clearEventCounters();
// Verify that the condition is met // Verify that the condition is met
@ -3092,6 +3136,8 @@ public class MIBreakpointsTest extends BaseTestCase {
+ getBreakpointEventCount(WP_HIT), getBreakpointEventCount(WP_HIT) == 1); + getBreakpointEventCount(WP_HIT), getBreakpointEventCount(WP_HIT) == 1);
assertTrue("BreakpointService problem: watchpoint mismatch", assertTrue("BreakpointService problem: watchpoint mismatch",
fBreakpointRef == watchpoint1.getNumber()); fBreakpointRef == watchpoint1.getNumber());
assertTrue("BreakpointService problem: breakpoint mismatch (pending)",
!watchpoint1.isPending());
clearEventCounters(); clearEventCounters();
// Verify that the condition is met // Verify that the condition is met
@ -3138,6 +3184,8 @@ public class MIBreakpointsTest extends BaseTestCase {
+ getBreakpointEventCount(WP_HIT), getBreakpointEventCount(WP_HIT) == 1); + getBreakpointEventCount(WP_HIT), getBreakpointEventCount(WP_HIT) == 1);
assertTrue("BreakpointService problem: watchpoint mismatch", assertTrue("BreakpointService problem: watchpoint mismatch",
fBreakpointRef == watchpoint1.getNumber()); fBreakpointRef == watchpoint1.getNumber());
assertTrue("BreakpointService problem: breakpoint mismatch (pending)",
!watchpoint1.isPending());
clearEventCounters(); clearEventCounters();
// Verify that the condition is met // Verify that the condition is met
@ -3185,6 +3233,8 @@ public class MIBreakpointsTest extends BaseTestCase {
+ getBreakpointEventCount(WP_HIT), getBreakpointEventCount(WP_HIT) == 1); + getBreakpointEventCount(WP_HIT), getBreakpointEventCount(WP_HIT) == 1);
assertTrue("BreakpointService problem: watchpoint mismatch", assertTrue("BreakpointService problem: watchpoint mismatch",
fBreakpointRef == watchpoint1.getNumber()); fBreakpointRef == watchpoint1.getNumber());
assertTrue("BreakpointService problem: breakpoint mismatch (pending)",
!watchpoint1.isPending());
clearEventCounters(); clearEventCounters();
// Verify that the condition is met // Verify that the condition is met
@ -3247,6 +3297,8 @@ public class MIBreakpointsTest extends BaseTestCase {
+ getBreakpointEventCount(WP_HIT), getBreakpointEventCount(WP_HIT) == 1); + getBreakpointEventCount(WP_HIT), getBreakpointEventCount(WP_HIT) == 1);
assertTrue("BreakpointService problem: watchpoint mismatch", assertTrue("BreakpointService problem: watchpoint mismatch",
fBreakpointRef == watchpoint1.getNumber()); fBreakpointRef == watchpoint1.getNumber());
assertTrue("BreakpointService problem: breakpoint mismatch (pending)",
!watchpoint1.isPending());
clearEventCounters(); clearEventCounters();
// Verify that the condition is met // Verify that the condition is met
@ -3310,6 +3362,8 @@ public class MIBreakpointsTest extends BaseTestCase {
+ getBreakpointEventCount(WP_HIT), getBreakpointEventCount(WP_HIT) == 1); + getBreakpointEventCount(WP_HIT), getBreakpointEventCount(WP_HIT) == 1);
assertTrue("BreakpointService problem: watchpoint mismatch", assertTrue("BreakpointService problem: watchpoint mismatch",
fBreakpointRef == watchpoint1.getNumber()); fBreakpointRef == watchpoint1.getNumber());
assertTrue("BreakpointService problem: breakpoint mismatch (pending)",
!watchpoint1.isPending());
clearEventCounters(); clearEventCounters();
// Verify that the condition is met // Verify that the condition is met
@ -3362,6 +3416,8 @@ public class MIBreakpointsTest extends BaseTestCase {
+ getBreakpointEventCount(WP_OOS), getBreakpointEventCount(WP_OOS) == 1); + getBreakpointEventCount(WP_OOS), getBreakpointEventCount(WP_OOS) == 1);
assertTrue("BreakpointService problem: watchpoint mismatch", assertTrue("BreakpointService problem: watchpoint mismatch",
fBreakpointRef == watchpoint1.getNumber()); fBreakpointRef == watchpoint1.getNumber());
assertTrue("BreakpointService problem: breakpoint mismatch (pending)",
!watchpoint1.isPending());
clearEventCounters(); clearEventCounters();
// Ensure the watchpoint is gone // Ensure the watchpoint is gone

View file

@ -10,11 +10,20 @@
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.tests.dsf.gdb.tests.tests_6_8; package org.eclipse.cdt.tests.dsf.gdb.tests.tests_6_8;
import static org.junit.Assert.assertTrue;
import java.util.HashMap;
import java.util.Map;
import org.eclipse.cdt.dsf.debug.service.IBreakpoints.IBreakpointDMContext;
import org.eclipse.cdt.dsf.mi.service.MIBreakpointDMData;
import org.eclipse.cdt.dsf.mi.service.MIBreakpoints.MIBreakpointDMContext;
import org.eclipse.cdt.tests.dsf.gdb.framework.BackgroundRunner; import org.eclipse.cdt.tests.dsf.gdb.framework.BackgroundRunner;
import org.eclipse.cdt.tests.dsf.gdb.framework.SyncUtil;
import org.eclipse.cdt.tests.dsf.gdb.tests.ITestConstants; import org.eclipse.cdt.tests.dsf.gdb.tests.ITestConstants;
import org.eclipse.cdt.tests.dsf.gdb.tests.MIBreakpointsTest; import org.eclipse.cdt.tests.dsf.gdb.tests.MIBreakpointsTest;
import org.eclipse.core.runtime.Platform;
import org.junit.BeforeClass; import org.junit.BeforeClass;
import org.junit.Ignore;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
@ -25,9 +34,159 @@ public class MIBreakpointsTest_6_8 extends MIBreakpointsTest {
public static void beforeClassMethod_6_8() { public static void beforeClassMethod_6_8() {
setGdbProgramNamesLaunchAttributes(ITestConstants.SUFFIX_GDB_6_8); setGdbProgramNamesLaunchAttributes(ITestConstants.SUFFIX_GDB_6_8);
} }
@Override @Override
@Ignore("This GDB 6.8 only has a bug which ignores watchpoint conditions")
@Test @Test
public void breakpointHit_watchpointUpdateCondition() throws Throwable { public void breakpointHit_watchpointUpdateCondition() throws Throwable {
// GDB 6.8 has a bug that ignores watchpoint conditions,which makes this
// test fail. We therefore ignore this test for GDB 6.8 only, but run it
// for all other versions
if (getClass().equals(MIBreakpointsTest_6_8.class) == false) {
super.breakpointHit_watchpointUpdateCondition();
}
}
/**
* Starting with GDB 6.8, we request failed breakpoints to be pending in
* GDB. So we no longer get an installation error from GDB.
*/
@Override
@Test
public void insertBreakpoint_InvalidFileName() throws Throwable {
// Create an invalid line breakpoint
Map<String, Object> breakpoint = new HashMap<String, Object>();
breakpoint.put(BREAKPOINT_TYPE_TAG, BREAKPOINT_TAG);
breakpoint.put(FILE_NAME_TAG, SOURCE_FILE + "_bad");
breakpoint.put(LINE_NUMBER_TAG, LINE_NUMBER_1);
// Perform the test, which we still expect to succeed
// giving us a pending breakpoint
IBreakpointDMContext ref = insertBreakpoint(fBreakpointsDmc, breakpoint);
assertTrue(fWait.getMessage(), fWait.isOK());
// Ensure that right BreakpointEvents were received
waitForBreakpointEvent(1);
assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT event(s), received "
+ fBreakpointEventCount, fBreakpointEventCount == 1);
assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT_ADDED event(s), received "
+ getBreakpointEventCount(BP_ADDED), getBreakpointEventCount(BP_ADDED) == 1);
clearEventCounters();
// Ensure that the breakpoint was correctly installed
MIBreakpointDMData breakpoint1 = (MIBreakpointDMData) getBreakpoint(ref);
assertTrue("BreakpointService problem: breakpoint mismatch (wrong file name)",
breakpoint1.getFileName().equals(""));
assertTrue("BreakpointService problem: breakpoint mismatch (wrong line number)",
breakpoint1.getLineNumber() == -1);
assertTrue("BreakpointService problem: breakpoint mismatch (wrong condition)",
breakpoint1.getCondition().equals(NO_CONDITION));
assertTrue("BreakpointService problem: breakpoint mismatch (wrong ignore count)",
breakpoint1.getIgnoreCount() == 0);
assertTrue("BreakpointService problem: breakpoint mismatch (wrong state)",
breakpoint1.isEnabled());
assertTrue("BreakpointService problem: breakpoint mismatch (not pending)",
breakpoint1.isPending());
// Ensure the BreakpointService holds only the right breakpoints
IBreakpointDMContext[] breakpoints = getBreakpoints(fBreakpointsDmc);
assertTrue("BreakpointService problem: expected " + 1 + " breakpoint(s), received "
+ breakpoints.length, breakpoints.length == 1);
MIBreakpointDMData breakpoint2 = (MIBreakpointDMData) getBreakpoint(breakpoints[0]);
assertTrue("BreakpointService problem: breakpoint mismatch",
breakpoint1.equals(breakpoint2));
}
/**
* Starting with GDB 6.8, we request failed breakpoints to be pending in
* GDB. So we no longer get an installation error from GDB.
*/
@Override
@Test
public void insertBreakpoint_InvalidFunctionName() throws Throwable {
// Create an invalid function breakpoint
Map<String, Object> breakpoint = new HashMap<String, Object>();
breakpoint.put(BREAKPOINT_TYPE_TAG, BREAKPOINT_TAG);
breakpoint.put(FILE_NAME_TAG, SOURCE_FILE);
breakpoint.put(FUNCTION_TAG, "invalid-function-name");
// Perform the test, which we still expect to succeed
// giving us a pending breakpoint
IBreakpointDMContext ref = insertBreakpoint(fBreakpointsDmc, breakpoint);
assertTrue(fWait.getMessage(), fWait.isOK());
// Ensure that right BreakpointEvents were received
waitForBreakpointEvent(1);
assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT event(s), received "
+ fBreakpointEventCount, fBreakpointEventCount == 1);
assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT_ADDED event(s), received "
+ getBreakpointEventCount(BP_ADDED), getBreakpointEventCount(BP_ADDED) == 1);
clearEventCounters();
// Ensure that the breakpoint was correctly installed
MIBreakpointDMData breakpoint1 = (MIBreakpointDMData) getBreakpoint(ref);
assertTrue("BreakpointService problem: breakpoint mismatch (wrong file name)",
breakpoint1.getFileName().equals(""));
assertTrue("BreakpointService problem: breakpoint mismatch (wrong function)",
breakpoint1.getFunctionName().equals(""));
assertTrue("BreakpointService problem: breakpoint mismatch (wrong condition)",
breakpoint1.getCondition().equals(NO_CONDITION));
assertTrue("BreakpointService problem: breakpoint mismatch (wrong ignore count)",
breakpoint1.getIgnoreCount() == 0);
assertTrue("BreakpointService problem: breakpoint mismatch (not pending)",
breakpoint1.isPending());
// Ensure the BreakpointService holds only the right breakpoints
IBreakpointDMContext[] breakpoints = getBreakpoints(fBreakpointsDmc);
assertTrue("BreakpointService problem: expected " + 1 + " breakpoint(s), received "
+ breakpoints.length, breakpoints.length == 1);
MIBreakpointDMData breakpoint2 = (MIBreakpointDMData) getBreakpoint(breakpoints[0]);
assertTrue("BreakpointService problem: breakpoint mismatch",
breakpoint1.equals(breakpoint2));
}
/**
* Starting with GDB 6.8, we request failed breakpoints to be pending in
* GDB. So we no longer get an installation error from GDB.
*/
@Override
@Test
public void insertInvalidBreakpoint_WhileTargetRunning() throws Throwable {
// Interrupting the target on Windows is susceptible to an additional,
// unwanted suspension. That means that silently interrupting the target
// to set/modify/remove a breakpoint then resuming it can leave the
// target in a suspended state. Unfortunately, there is nothing
// practical CDT can do to address this issue except wait for the gdb
// folks to resolve it. See https://bugs.eclipse.org/bugs/show_bug.cgi?id=304096#c27
if (Platform.getOS().equals(Platform.OS_WIN32)) {
return;
}
// Create an invalid line breakpoint
Map<String, Object> breakpoint = new HashMap<String, Object>();
breakpoint.put(BREAKPOINT_TYPE_TAG, BREAKPOINT_TAG);
breakpoint.put(FILE_NAME_TAG, "Bad file name");
breakpoint.put(LINE_NUMBER_TAG, LINE_NUMBER_5);
// Run the program. It will make a two second sleep() call, during which time...
SyncUtil.resume();
// ...we install the breakpoint
MIBreakpointDMContext ref = (MIBreakpointDMContext) insertBreakpoint(fBreakpointsDmc, breakpoint);
assertTrue(fWait.getMessage(), fWait.isOK());
waitForBreakpointEvent(1);
// Ensure the correct BreakpointEvent was received
MIBreakpointDMData breakpoint1 = (MIBreakpointDMData) getBreakpoint(ref);
assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT event(s), received "
+ fBreakpointEventCount, fBreakpointEventCount == 1);
assertTrue("BreakpointEvent problem: expected " + 0 + " BREAKPOINT_HIT event(s), received "
+ getBreakpointEventCount(BP_HIT), getBreakpointEventCount(BP_HIT) == 0);
assertTrue("BreakpointService problem: breakpoint mismatch",
fBreakpointRef == breakpoint1.getNumber());
assertTrue("BreakpointService problem: breakpoint mismatch (not pending)",
breakpoint1.isPending());
clearEventCounters();
} }
} }

View file

@ -12,12 +12,12 @@ package org.eclipse.cdt.tests.dsf.gdb.tests.tests_7_0;
import org.eclipse.cdt.tests.dsf.gdb.framework.BackgroundRunner; import org.eclipse.cdt.tests.dsf.gdb.framework.BackgroundRunner;
import org.eclipse.cdt.tests.dsf.gdb.tests.ITestConstants; import org.eclipse.cdt.tests.dsf.gdb.tests.ITestConstants;
import org.eclipse.cdt.tests.dsf.gdb.tests.MIBreakpointsTest; import org.eclipse.cdt.tests.dsf.gdb.tests.tests_6_8.MIBreakpointsTest_6_8;
import org.junit.BeforeClass; import org.junit.BeforeClass;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
@RunWith(BackgroundRunner.class) @RunWith(BackgroundRunner.class)
public class MIBreakpointsTest_7_0 extends MIBreakpointsTest { public class MIBreakpointsTest_7_0 extends MIBreakpointsTest_6_8 {
@BeforeClass @BeforeClass
public static void beforeClassMethod_7_0() { public static void beforeClassMethod_7_0() {
setGdbProgramNamesLaunchAttributes(ITestConstants.SUFFIX_GDB_7_0); setGdbProgramNamesLaunchAttributes(ITestConstants.SUFFIX_GDB_7_0);

View file

@ -12,12 +12,12 @@ package org.eclipse.cdt.tests.dsf.gdb.tests.tests_7_1;
import org.eclipse.cdt.tests.dsf.gdb.framework.BackgroundRunner; import org.eclipse.cdt.tests.dsf.gdb.framework.BackgroundRunner;
import org.eclipse.cdt.tests.dsf.gdb.tests.ITestConstants; import org.eclipse.cdt.tests.dsf.gdb.tests.ITestConstants;
import org.eclipse.cdt.tests.dsf.gdb.tests.MIBreakpointsTest; import org.eclipse.cdt.tests.dsf.gdb.tests.tests_7_0.MIBreakpointsTest_7_0;
import org.junit.BeforeClass; import org.junit.BeforeClass;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
@RunWith(BackgroundRunner.class) @RunWith(BackgroundRunner.class)
public class MIBreakpointsTest_7_1 extends MIBreakpointsTest { public class MIBreakpointsTest_7_1 extends MIBreakpointsTest_7_0 {
@BeforeClass @BeforeClass
public static void beforeClassMethod_7_1() { public static void beforeClassMethod_7_1() {
setGdbProgramNamesLaunchAttributes(ITestConstants.SUFFIX_GDB_7_1); setGdbProgramNamesLaunchAttributes(ITestConstants.SUFFIX_GDB_7_1);

View file

@ -12,12 +12,12 @@ package org.eclipse.cdt.tests.dsf.gdb.tests.tests_7_2;
import org.eclipse.cdt.tests.dsf.gdb.framework.BackgroundRunner; import org.eclipse.cdt.tests.dsf.gdb.framework.BackgroundRunner;
import org.eclipse.cdt.tests.dsf.gdb.tests.ITestConstants; import org.eclipse.cdt.tests.dsf.gdb.tests.ITestConstants;
import org.eclipse.cdt.tests.dsf.gdb.tests.MIBreakpointsTest; import org.eclipse.cdt.tests.dsf.gdb.tests.tests_7_1.MIBreakpointsTest_7_1;
import org.junit.BeforeClass; import org.junit.BeforeClass;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
@RunWith(BackgroundRunner.class) @RunWith(BackgroundRunner.class)
public class MIBreakpointsTest_7_2 extends MIBreakpointsTest { public class MIBreakpointsTest_7_2 extends MIBreakpointsTest_7_1 {
@BeforeClass @BeforeClass
public static void beforeClassMethod_7_2() { public static void beforeClassMethod_7_2() {
setGdbProgramNamesLaunchAttributes(ITestConstants.SUFFIX_GDB_7_2); setGdbProgramNamesLaunchAttributes(ITestConstants.SUFFIX_GDB_7_2);