mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-07-23 17:05:26 +02:00
Stop trying to side-step the fact that on Windows interrupting the target can leave it suspended prematurely, only to have it suspend again when you resume it. My previous attempt worked only some of the time. Trying to close the gap would be way too messy, so just skip the "while target running" tests on Windows.
This commit is contained in:
parent
2bedd8397b
commit
429c116b18
2 changed files with 141 additions and 166 deletions
|
@ -1205,7 +1205,16 @@ public class MIBreakpointsTest extends BaseTestCase {
|
|||
// ------------------------------------------------------------------------
|
||||
@Test
|
||||
public void insertBreakpoint_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 a line breakpoint
|
||||
Map<String, Object> breakpoint = new HashMap<String, Object>();
|
||||
breakpoint.put(BREAKPOINT_TYPE_TAG, BREAKPOINT_TAG);
|
||||
|
@ -1219,9 +1228,10 @@ public class MIBreakpointsTest extends BaseTestCase {
|
|||
MIBreakpointDMContext ref = (MIBreakpointDMContext) insertBreakpoint(fBreakpointsDmc, breakpoint);
|
||||
assertTrue(fWait.getMessage(), fWait.isOK());
|
||||
|
||||
// Wait for breakpoint to hit.
|
||||
MIStoppedEvent event = waitForBreakpointEventsAfterBreakpointOperationWhileTargetRunning(true, 2);
|
||||
|
||||
// Wait for breakpoint to hit and for the expected number of breakpoint events to have occurred
|
||||
MIStoppedEvent event = SyncUtil.waitForStop(3000);
|
||||
waitForBreakpointEvent(2);
|
||||
|
||||
// Ensure the correct BreakpointEvent was received
|
||||
MIBreakpointDMData breakpoint1 = (MIBreakpointDMData) getBreakpoint(ref);
|
||||
assertTrue("BreakpointEvent problem: expected " + 2 + " BREAKPOINT event(s), received "
|
||||
|
@ -1248,7 +1258,16 @@ public class MIBreakpointsTest extends BaseTestCase {
|
|||
// ------------------------------------------------------------------------
|
||||
@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 a line breakpoint
|
||||
Map<String, Object> breakpoint = new HashMap<String, Object>();
|
||||
breakpoint.put(BREAKPOINT_TYPE_TAG, BREAKPOINT_TAG);
|
||||
|
@ -1267,8 +1286,9 @@ public class MIBreakpointsTest extends BaseTestCase {
|
|||
breakpoint.put(FILE_NAME_TAG, SOURCE_FILE);
|
||||
MIBreakpointDMContext ref = (MIBreakpointDMContext) insertBreakpoint(fBreakpointsDmc, breakpoint);
|
||||
|
||||
// Wait for breakpoint to hit.
|
||||
MIStoppedEvent event = waitForBreakpointEventsAfterBreakpointOperationWhileTargetRunning(true, 2);
|
||||
// Wait for breakpoint to hit and for the expected number of breakpoint events to have occurred
|
||||
MIStoppedEvent event = SyncUtil.waitForStop(3000);
|
||||
waitForBreakpointEvent(2);
|
||||
|
||||
// Ensure the correct BreakpointEvent was received
|
||||
MIBreakpointDMData breakpoint1 = (MIBreakpointDMData) getBreakpoint(ref);
|
||||
|
@ -1436,6 +1456,15 @@ public class MIBreakpointsTest extends BaseTestCase {
|
|||
@Ignore("Not supported because the frame where we stop does not contain the expression")
|
||||
@Test
|
||||
public void insertWatchpoint_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 a write watchpoint
|
||||
Map<String, Object> watchpoint = new HashMap<String, Object>();
|
||||
|
@ -1450,8 +1479,9 @@ public class MIBreakpointsTest extends BaseTestCase {
|
|||
IBreakpointDMContext ref = insertBreakpoint(fBreakpointsDmc, watchpoint);
|
||||
assertTrue(fWait.getMessage(), fWait.isOK());
|
||||
|
||||
// Wait for breakpoint to hit
|
||||
MIStoppedEvent event = waitForBreakpointEventsAfterBreakpointOperationWhileTargetRunning(true, 2);
|
||||
// Wait for breakpoint to hit and for the expected number of breakpoint events to have occurred
|
||||
MIStoppedEvent event = SyncUtil.waitForStop(3000);
|
||||
waitForBreakpointEvent(2);
|
||||
|
||||
// Ensure that right BreakpointEvents were received
|
||||
assertTrue("BreakpointEvent problem: expected " + 2 + " BREAKPOINT event(s), received "
|
||||
|
@ -1716,6 +1746,15 @@ public class MIBreakpointsTest extends BaseTestCase {
|
|||
// ------------------------------------------------------------------------
|
||||
@Test
|
||||
public void removeBreakpoint_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 a line breakpoint
|
||||
Map<String, Object> breakpoint = new HashMap<String, Object>();
|
||||
|
@ -1741,8 +1780,9 @@ public class MIBreakpointsTest extends BaseTestCase {
|
|||
removeBreakpoint(ref);
|
||||
assertTrue(fWait.getMessage(), fWait.isOK());
|
||||
|
||||
// Wait for the breakpoint to hit
|
||||
MIStoppedEvent event = waitForBreakpointEventsAfterBreakpointOperationWhileTargetRunning(true, 4);
|
||||
// Wait for breakpoint to hit and for the expected number of breakpoint events to have occurred
|
||||
MIStoppedEvent event = SyncUtil.waitForStop(3000);
|
||||
waitForBreakpointEvent(4);
|
||||
|
||||
// Ensure the correct BreakpointEvent was received
|
||||
assertTrue("BreakpointEvent problem: expected " + 4 + " BREAKPOINT event(s), received "
|
||||
|
@ -1936,6 +1976,15 @@ public class MIBreakpointsTest extends BaseTestCase {
|
|||
// ------------------------------------------------------------------------
|
||||
@Test
|
||||
public void updateBreakpoint_ModifyCondition_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 a line breakpoint
|
||||
Map<String, Object> breakpoint = new HashMap<String, Object>();
|
||||
|
@ -1966,8 +2015,9 @@ public class MIBreakpointsTest extends BaseTestCase {
|
|||
updateBreakpoint(ref, delta);
|
||||
assertTrue(fWait.getMessage(), fWait.isOK());
|
||||
|
||||
// Wait for the breakpoint to hit
|
||||
MIStoppedEvent event = waitForBreakpointEventsAfterBreakpointOperationWhileTargetRunning(true, 2);
|
||||
// Wait for breakpoint to hit and for the expected number of breakpoint events to have occurred
|
||||
MIStoppedEvent event = SyncUtil.waitForStop(3000);
|
||||
waitForBreakpointEvent(2);
|
||||
|
||||
// Ensure that right BreakpointEvents were received
|
||||
assertTrue("BreakpointEvent problem: expected " + 2 + " BREAKPOINT event(s), received "
|
||||
|
@ -2303,6 +2353,15 @@ public class MIBreakpointsTest extends BaseTestCase {
|
|||
// ------------------------------------------------------------------------
|
||||
@Test
|
||||
public void updateBreakpoint_ModifyCount_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 a line breakpoint
|
||||
Map<String, Object> breakpoint = new HashMap<String, Object>();
|
||||
|
@ -2334,8 +2393,9 @@ public class MIBreakpointsTest extends BaseTestCase {
|
|||
updateBreakpoint(ref, delta);
|
||||
assertTrue(fWait.getMessage(), fWait.isOK());
|
||||
|
||||
// Wait for the breakpoint to hit
|
||||
MIStoppedEvent event = waitForBreakpointEventsAfterBreakpointOperationWhileTargetRunning(true, 2);
|
||||
// Wait for breakpoint to hit and for the expected number of breakpoint events to have occurred
|
||||
MIStoppedEvent event = SyncUtil.waitForStop(3000);
|
||||
waitForBreakpointEvent(2);
|
||||
|
||||
// Ensure that right BreakpointEvents were received
|
||||
assertTrue("BreakpointEvent problem: expected " + 2 + " BREAKPOINT event(s), received "
|
||||
|
@ -2440,6 +2500,15 @@ public class MIBreakpointsTest extends BaseTestCase {
|
|||
// ------------------------------------------------------------------------
|
||||
@Test
|
||||
public void updateBreakpoint_Disable_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 a line breakpoint
|
||||
Map<String, Object> breakpoint = new HashMap<String, Object>();
|
||||
|
@ -2476,10 +2545,9 @@ public class MIBreakpointsTest extends BaseTestCase {
|
|||
updateBreakpoint(ref, delta);
|
||||
assertTrue(fWait.getMessage(), fWait.isOK());
|
||||
|
||||
// Ensure that right BreakpointEvents were received
|
||||
MIStoppedEvent event = waitForBreakpointEventsAfterBreakpointOperationWhileTargetRunning(true, 2);
|
||||
assertTrue("BreakpointEvent problem: expected " + 2 + " BREAKPOINT event(s), received "
|
||||
+ fBreakpointEventCount, fBreakpointEventCount == 2);
|
||||
// Wait for breakpoint to hit and for the expected number of breakpoint events to have occurred
|
||||
MIStoppedEvent event = SyncUtil.waitForStop(3000);
|
||||
waitForBreakpointEvent(2);
|
||||
assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT_UPDATED event(s), received "
|
||||
+ getBreakpointEventCount(BP_UPDATED), getBreakpointEventCount(BP_UPDATED) == 1);
|
||||
assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT_HIT event(s), received "
|
||||
|
@ -2609,6 +2677,15 @@ public class MIBreakpointsTest extends BaseTestCase {
|
|||
// ------------------------------------------------------------------------
|
||||
@Test
|
||||
public void updateBreakpoint_Enable_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 a line breakpoint
|
||||
Map<String, Object> breakpoint = new HashMap<String, Object>();
|
||||
|
@ -2640,8 +2717,9 @@ public class MIBreakpointsTest extends BaseTestCase {
|
|||
updateBreakpoint(ref, delta);
|
||||
assertTrue(fWait.getMessage(), fWait.isOK());
|
||||
|
||||
// Wait for the breakpoint to hit
|
||||
MIStoppedEvent event = waitForBreakpointEventsAfterBreakpointOperationWhileTargetRunning(true, 2);
|
||||
// Wait for breakpoint to hit and for the expected number of breakpoint events to have occurred
|
||||
MIStoppedEvent event = SyncUtil.waitForStop(3000);
|
||||
waitForBreakpointEvent(2);
|
||||
|
||||
// Ensure that right BreakpointEvents were received
|
||||
assertTrue("BreakpointEvent problem: expected " + 2 + " BREAKPOINT event(s), received "
|
||||
|
@ -3298,73 +3376,4 @@ public class MIBreakpointsTest extends BaseTestCase {
|
|||
assertTrue("BreakpointEvent problem: expected watchpoint to be deleted after going out of scope",
|
||||
watchpoint1 == null);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method allows the while-target-running tests to side-step a bug in
|
||||
* Windows gdb. To perform a breakpoint operation while the target is
|
||||
* running, the DSF debugger temporarily suspends the target (gdb) with a
|
||||
* SIGINT, carries out the operation, and then resumes the target. On
|
||||
* Windows gdbs, there's a race condition problem with the SIGINT handling
|
||||
* resulting in the target suspending for a reason other than the SIGINT.
|
||||
* Resuming the target, though, will result in the target suspending
|
||||
* again...this time for the SIGINT.
|
||||
*
|
||||
* See http://sourceware.org/ml/gdb-patches/2008-05/msg00264.html
|
||||
*
|
||||
* I've looked at the latest gdb sources and the problem has not yet been
|
||||
* fixed. Search "FIXME: brobecker/2008-05-20" in windows-nat.c
|
||||
*
|
||||
* @param waitForStop
|
||||
* indicates whether we should first wait for the target to stop.
|
||||
* Otherwise we just wait until [eventCount] number of breakpoint
|
||||
* events have occurred. If this arg is true, we return the
|
||||
* MIStoppedEvent.
|
||||
* @param eventCount
|
||||
* the number of breakpoint events to wait for
|
||||
* @return the stopped event, if [waitForStop] is true; otherwise null
|
||||
* @throws Throwable
|
||||
*/
|
||||
MIStoppedEvent waitForBreakpointEventsAfterBreakpointOperationWhileTargetRunning(boolean waitForStop, int eventCount) throws Throwable {
|
||||
MIStoppedEvent event = null;
|
||||
if (waitForStop) {
|
||||
// The target program should be in the middle of a one second
|
||||
// sleep() call. Most tests involve setting a breakpoint at
|
||||
// some line after the sleep call. Allow up to three seconds
|
||||
// for the sleep() call to complete and the breakpoint to be
|
||||
// hit.
|
||||
event = SyncUtil.waitForStop(3000);
|
||||
}
|
||||
|
||||
if (Platform.getOS().equals(Platform.OS_WIN32)) {
|
||||
// Normally, we would now give a couple of seconds for any
|
||||
// additional expected breakpoint events to occur after the target's
|
||||
// sleep call returns and fail the test if they don't. But the
|
||||
// Windws gdb bug may have gotten in the way. If it has, the target
|
||||
// is in an unexpected suspended state instead of running or stopped
|
||||
// at the test breakpoint. We just don't know. So, we wait two
|
||||
// seconds in case everything is actually behaving normally, since
|
||||
// that's how patient waitForBreakpointEvent() is. If waitForStop is
|
||||
// false, we need to allow enough time for the sleep() to return AND
|
||||
// any subsequent breakpoint events to occur.
|
||||
Thread.sleep(TestsPlugin.massageTimeout(waitForStop ? 2000 : 5000));
|
||||
|
||||
assertTrue("We should have gotten at least one breakpoint event", fBreakpointEventCount >= 1);
|
||||
if (fBreakpointEventCount < eventCount) {
|
||||
// It's likely we ran into the gdb bug. We can ignore it (since
|
||||
// it's out of our control) and proceed to test whether the
|
||||
// breakpoint operation was properly carried out.
|
||||
System.out.println("Performing an additional resume to work around Windows gdb bug");
|
||||
SyncUtil.resume();
|
||||
if (waitForStop) {
|
||||
event = SyncUtil.waitForStop(4000);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// OK, at this point, all the expected breakpoint events should have
|
||||
// occurred, or we really have a problem (unrelated to the gdb bug)
|
||||
waitForBreakpointEvent(eventCount);
|
||||
|
||||
return event;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -79,8 +79,6 @@ import org.junit.runner.RunWith;
|
|||
*
|
||||
* Refer to the JUnit4 documentation for an explanation of the annotations.
|
||||
*
|
||||
* NOTE: the WhileTargetRunning tests intermittently fail with MinGW gdb 7.0 and
|
||||
* fail 100% with cygwin. Bug 304096 will address this.
|
||||
*/
|
||||
|
||||
@RunWith(BackgroundRunner.class)
|
||||
|
@ -731,6 +729,16 @@ public class MICatchpointsTest extends BaseTestCase {
|
|||
*/
|
||||
@Test
|
||||
public void insertCatchpoint_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;
|
||||
}
|
||||
|
||||
// Run the program. It will make a two second sleep() call, during which time...
|
||||
SyncUtil.resume();
|
||||
|
||||
|
@ -743,8 +751,10 @@ public class MICatchpointsTest extends BaseTestCase {
|
|||
assertTrue(fWait.getMessage(), fWait.isOK());
|
||||
|
||||
// After the sleep, the test app throws a C++ exception. Wait for the
|
||||
// catchpoint to hit.
|
||||
MIStoppedEvent event = waitForBreakpointEventsAfterBreakpointOperationWhileTargetRunning(true, 2);
|
||||
// catchpoint to hit and for the expected number of breakpoint events to
|
||||
// have occurred
|
||||
MIStoppedEvent event = SyncUtil.waitForStop(3000);
|
||||
waitForBreakpointEvent(2);
|
||||
|
||||
// Ensure that right breakpoint events were received. One indicating the
|
||||
// catchpoint was created, another indicating it was hit
|
||||
|
@ -916,6 +926,16 @@ public class MICatchpointsTest extends BaseTestCase {
|
|||
* one.
|
||||
*/
|
||||
private void removeCatchpoint_WhileTargetRunning(boolean removeThrow) 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;
|
||||
}
|
||||
|
||||
// Set a line breakpoint at the sleep() call. We need to get the program
|
||||
// past the initial loop that throws and catches C++ exceptions.
|
||||
IBreakpointDMContext refLineBkpt = setLineBreakpoint(LINE_NUMBER_SLEEP_CALL);
|
||||
|
@ -937,7 +957,10 @@ public class MICatchpointsTest extends BaseTestCase {
|
|||
|
||||
// After the sleep, the test app throws a C++ exception and catches it.
|
||||
// The catchpoint we DIDN'T remove should stop the program
|
||||
MIStoppedEvent event = waitForBreakpointEventsAfterBreakpointOperationWhileTargetRunning(true, 2);
|
||||
// Wait for catchpoint to hit and for the expected number of breakpoint
|
||||
// events to have occurred
|
||||
MIStoppedEvent event = SyncUtil.waitForStop(3000);
|
||||
waitForBreakpointEvent(2);
|
||||
assertTrue("stopped event is of an unexpected type: " + event.getClass().getName(), event instanceof MIBreakpointHitEvent);
|
||||
MIBreakpointHitEvent bkptHitEvent = (MIBreakpointHitEvent)event;
|
||||
MIBreakpointDMData bkptNotRemoved = (MIBreakpointDMData) getBreakpoint(removeThrow ? refCatch : refThrow);
|
||||
|
@ -1058,6 +1081,16 @@ public class MICatchpointsTest extends BaseTestCase {
|
|||
* one.
|
||||
*/
|
||||
private void updateCatchpoint_WhileTargetRunning(boolean modifyThrow) 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;
|
||||
}
|
||||
|
||||
// Set a line breakpoint at the sleep() call.
|
||||
IBreakpointDMContext refLineBkpt = setLineBreakpoint(LINE_NUMBER_SLEEP_CALL);
|
||||
|
||||
|
@ -1076,7 +1109,7 @@ public class MICatchpointsTest extends BaseTestCase {
|
|||
assertEquals("Target stopped as expected, but the responsible breakpoint was not the expected one", lineBkpt.getNumber(), fBreakpointRef);
|
||||
clearEventCounters();
|
||||
|
||||
// Resume the program. It will make a two second sleep() call, during which time...
|
||||
// Resume the program. It will make a one second sleep() call, during which time...
|
||||
SyncUtil.resume();
|
||||
|
||||
// ...we modify one of the catchpoints's condition
|
||||
|
@ -1084,7 +1117,9 @@ public class MICatchpointsTest extends BaseTestCase {
|
|||
|
||||
// After the sleep, the test app throws a C++ exception and catches it.
|
||||
// So, the catchpoint whose condition we modified should get hit
|
||||
MIStoppedEvent event = waitForBreakpointEventsAfterBreakpointOperationWhileTargetRunning(true, 2);
|
||||
// Wait for breakpoint to hit and for the expected number of breakpoint events to have occurred
|
||||
MIStoppedEvent event = SyncUtil.waitForStop(3000);
|
||||
waitForBreakpointEvent(2);
|
||||
assertTrue("stopped event is of an unexpected type: " + event.getClass().getName(), event instanceof MIBreakpointHitEvent);
|
||||
MIBreakpointHitEvent bkptHitEvent = (MIBreakpointHitEvent)event;
|
||||
MIBreakpointDMData bkptUpdated = (MIBreakpointDMData) getBreakpoint(modifyThrow ? refThrow : refCatch);
|
||||
|
@ -1208,75 +1243,6 @@ public class MICatchpointsTest extends BaseTestCase {
|
|||
assertNull(GdbCatchpoints.gdbCatchpointKeywordToEvent("signals"));
|
||||
}
|
||||
|
||||
/**
|
||||
* This method allows the while-target-running tests to side-step a bug in
|
||||
* Windows gdb. To perform a breakpoint operation while the target is
|
||||
* running, the DSF debugger temporarily suspends the target (gdb) with a
|
||||
* SIGINT, carries out the operation, and then resumes the target. On
|
||||
* Windows gdbs, there's a race condition problem with the SIGINT handling
|
||||
* resulting in the target suspending for a reason other than the SIGINT.
|
||||
* Resuming the target, though, will result in the target suspending
|
||||
* again...this time for the SIGINT.
|
||||
*
|
||||
* See http://sourceware.org/ml/gdb-patches/2008-05/msg00264.html
|
||||
*
|
||||
* I've looked at the latest gdb sources and the problem has not yet been
|
||||
* fixed. Search "FIXME: brobecker/2008-05-20" in windows-nat.c
|
||||
*
|
||||
* @param waitForStop
|
||||
* indicates whether we should first wait for the target to stop.
|
||||
* Otherwise we just wait until [eventCount] number of breakpoint
|
||||
* events have occurred. If this arg is true, we return the
|
||||
* MIStoppedEvent.
|
||||
* @param eventCount
|
||||
* the number of breakpoint events to wait for
|
||||
* @return the stopped event, if [waitForStop] is true; otherwise null
|
||||
* @throws Throwable
|
||||
*/
|
||||
MIStoppedEvent waitForBreakpointEventsAfterBreakpointOperationWhileTargetRunning(boolean waitForStop, int eventCount) throws Throwable {
|
||||
MIStoppedEvent event = null;
|
||||
if (waitForStop) {
|
||||
// The target program should be in the middle of a one second
|
||||
// sleep() call. Most tests involve setting a breakpoint at
|
||||
// some line after the sleep call. Allow up to three seconds
|
||||
// for the sleep() call to complete and the breakpoint to be
|
||||
// hit.
|
||||
event = SyncUtil.waitForStop(3000);
|
||||
}
|
||||
|
||||
if (Platform.getOS().equals(Platform.OS_WIN32)) {
|
||||
// Normally, we would now give a couple of seconds for any
|
||||
// additional expected breakpoint events to occur after the target's
|
||||
// sleep call returns and fail the test if they don't. But the
|
||||
// Windws gdb bug may have gotten in the way. If it has, the target
|
||||
// is in an unexpected suspended state instead of running or stopped
|
||||
// at the test breakpoint. We just don't know. So, we wait two
|
||||
// seconds in case everything is actually behaving normally, since
|
||||
// that's how patient waitForBreakpointEvent() is. If waitForStop is
|
||||
// false, we need to allow enough time for the sleep() to return AND
|
||||
// any subsequent breakpoint events to occur.
|
||||
Thread.sleep(TestsPlugin.massageTimeout(waitForStop ? 2000 : 5000));
|
||||
int eventsReceived = totalBreakpointEventsCount();
|
||||
assertTrue("We should have gotten at least one breakpoint event", eventsReceived >= 1);
|
||||
if (eventsReceived < eventCount) {
|
||||
// It's likely we ran into the gdb bug. We can ignore it (since
|
||||
// it's out of our control) and proceed to test whether the
|
||||
// breakpoint operation was properly carried out.
|
||||
System.out.println("Performing an additional resume to work around Windows gdb bug");
|
||||
SyncUtil.resume();
|
||||
if (waitForStop) {
|
||||
event = SyncUtil.waitForStop(4000);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// OK, at this point, all the expected breakpoint events should have
|
||||
// occurred, or we really have a problem (unrelated to the gdb bug)
|
||||
waitForBreakpointEvent(eventCount);
|
||||
|
||||
return event;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a line breakpoint and validate it was set correctly.
|
||||
*
|
||||
|
|
Loading…
Add table
Reference in a new issue