mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-06-09 18:56:02 +02:00
[304561] While-target-running breakpoint tests are failing because of Windows gdb bug
This commit is contained in:
parent
7c8b6387d7
commit
fa79d364cc
1 changed files with 82 additions and 16 deletions
|
@ -53,6 +53,7 @@ import org.eclipse.cdt.tests.dsf.gdb.framework.BackgroundRunner;
|
||||||
import org.eclipse.cdt.tests.dsf.gdb.framework.BaseTestCase;
|
import org.eclipse.cdt.tests.dsf.gdb.framework.BaseTestCase;
|
||||||
import org.eclipse.cdt.tests.dsf.gdb.framework.SyncUtil;
|
import org.eclipse.cdt.tests.dsf.gdb.framework.SyncUtil;
|
||||||
import org.eclipse.cdt.tests.dsf.gdb.launching.TestsPlugin;
|
import org.eclipse.cdt.tests.dsf.gdb.launching.TestsPlugin;
|
||||||
|
import org.eclipse.core.runtime.Platform;
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
import org.junit.AfterClass;
|
import org.junit.AfterClass;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
|
@ -1218,12 +1219,10 @@ public class MIBreakpointsTest extends BaseTestCase {
|
||||||
MIBreakpointDMContext ref = (MIBreakpointDMContext) insertBreakpoint(fBreakpointsDmc, breakpoint);
|
MIBreakpointDMContext ref = (MIBreakpointDMContext) insertBreakpoint(fBreakpointsDmc, breakpoint);
|
||||||
assertTrue(fWait.getMessage(), fWait.isOK());
|
assertTrue(fWait.getMessage(), fWait.isOK());
|
||||||
|
|
||||||
// Wait for breakpoint to hit. The program terminates after the sleep()
|
// Wait for breakpoint to hit.
|
||||||
// call, so waiting four seconds is more than enough
|
MIStoppedEvent event = waitForBreakpointEventsAfterBreakpointOperationWhileTargetRunning(true, 2);
|
||||||
MIStoppedEvent event = SyncUtil.waitForStop(4000);
|
|
||||||
|
|
||||||
// Ensure the correct BreakpointEvent was received
|
// Ensure the correct BreakpointEvent was received
|
||||||
waitForBreakpointEvent(2);
|
|
||||||
MIBreakpointDMData breakpoint1 = (MIBreakpointDMData) getBreakpoint(ref);
|
MIBreakpointDMData breakpoint1 = (MIBreakpointDMData) getBreakpoint(ref);
|
||||||
assertTrue("BreakpointEvent problem: expected " + 2 + " BREAKPOINT event(s), received "
|
assertTrue("BreakpointEvent problem: expected " + 2 + " BREAKPOINT event(s), received "
|
||||||
+ fBreakpointEventCount, fBreakpointEventCount == 2);
|
+ fBreakpointEventCount, fBreakpointEventCount == 2);
|
||||||
|
@ -1404,10 +1403,9 @@ public class MIBreakpointsTest extends BaseTestCase {
|
||||||
assertTrue(fWait.getMessage(), fWait.isOK());
|
assertTrue(fWait.getMessage(), fWait.isOK());
|
||||||
|
|
||||||
// Wait for breakpoint to hit
|
// Wait for breakpoint to hit
|
||||||
MIStoppedEvent event = SyncUtil.waitForStop();
|
MIStoppedEvent event = waitForBreakpointEventsAfterBreakpointOperationWhileTargetRunning(true, 2);
|
||||||
|
|
||||||
// Ensure that right BreakpointEvents were received
|
// Ensure that right BreakpointEvents were received
|
||||||
waitForBreakpointEvent(2);
|
|
||||||
assertTrue("BreakpointEvent problem: expected " + 2 + " BREAKPOINT event(s), received "
|
assertTrue("BreakpointEvent problem: expected " + 2 + " BREAKPOINT event(s), received "
|
||||||
+ fBreakpointEventCount, fBreakpointEventCount == 2);
|
+ fBreakpointEventCount, fBreakpointEventCount == 2);
|
||||||
assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT_ADDED event(s), received "
|
assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT_ADDED event(s), received "
|
||||||
|
@ -1695,10 +1693,10 @@ public class MIBreakpointsTest extends BaseTestCase {
|
||||||
removeBreakpoint(ref);
|
removeBreakpoint(ref);
|
||||||
assertTrue(fWait.getMessage(), fWait.isOK());
|
assertTrue(fWait.getMessage(), fWait.isOK());
|
||||||
|
|
||||||
MIStoppedEvent event = SyncUtil.waitForStop();
|
// Wait for the breakpoint to hit
|
||||||
|
MIStoppedEvent event = waitForBreakpointEventsAfterBreakpointOperationWhileTargetRunning(true, 4);
|
||||||
|
|
||||||
// Ensure the correct BreakpointEvent was received
|
// Ensure the correct BreakpointEvent was received
|
||||||
waitForBreakpointEvent(4);
|
|
||||||
assertTrue("BreakpointEvent problem: expected " + 4 + " BREAKPOINT event(s), received "
|
assertTrue("BreakpointEvent problem: expected " + 4 + " BREAKPOINT event(s), received "
|
||||||
+ fBreakpointEventCount, fBreakpointEventCount == 4);
|
+ fBreakpointEventCount, fBreakpointEventCount == 4);
|
||||||
assertTrue("BreakpointEvent problem: expected " + 2 + " BREAKPOINT_HIT event(s), received "
|
assertTrue("BreakpointEvent problem: expected " + 2 + " BREAKPOINT_HIT event(s), received "
|
||||||
|
@ -1920,10 +1918,10 @@ public class MIBreakpointsTest extends BaseTestCase {
|
||||||
updateBreakpoint(ref, delta);
|
updateBreakpoint(ref, delta);
|
||||||
assertTrue(fWait.getMessage(), fWait.isOK());
|
assertTrue(fWait.getMessage(), fWait.isOK());
|
||||||
|
|
||||||
MIStoppedEvent event = SyncUtil.waitForStop();
|
// Wait for the breakpoint to hit
|
||||||
|
MIStoppedEvent event = waitForBreakpointEventsAfterBreakpointOperationWhileTargetRunning(true, 2);
|
||||||
|
|
||||||
// Ensure that right BreakpointEvents were received
|
// Ensure that right BreakpointEvents were received
|
||||||
waitForBreakpointEvent(2);
|
|
||||||
assertTrue("BreakpointEvent problem: expected " + 2 + " BREAKPOINT event(s), received "
|
assertTrue("BreakpointEvent problem: expected " + 2 + " BREAKPOINT event(s), received "
|
||||||
+ fBreakpointEventCount, fBreakpointEventCount == 2);
|
+ fBreakpointEventCount, fBreakpointEventCount == 2);
|
||||||
assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT_UPDATED event(s), received "
|
assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT_UPDATED event(s), received "
|
||||||
|
@ -2288,10 +2286,10 @@ public class MIBreakpointsTest extends BaseTestCase {
|
||||||
updateBreakpoint(ref, delta);
|
updateBreakpoint(ref, delta);
|
||||||
assertTrue(fWait.getMessage(), fWait.isOK());
|
assertTrue(fWait.getMessage(), fWait.isOK());
|
||||||
|
|
||||||
MIStoppedEvent event = SyncUtil.waitForStop();
|
// Wait for the breakpoint to hit
|
||||||
|
MIStoppedEvent event = waitForBreakpointEventsAfterBreakpointOperationWhileTargetRunning(true, 2);
|
||||||
|
|
||||||
// Ensure that right BreakpointEvents were received
|
// Ensure that right BreakpointEvents were received
|
||||||
waitForBreakpointEvent(2);
|
|
||||||
assertTrue("BreakpointEvent problem: expected " + 2 + " BREAKPOINT event(s), received "
|
assertTrue("BreakpointEvent problem: expected " + 2 + " BREAKPOINT event(s), received "
|
||||||
+ fBreakpointEventCount, fBreakpointEventCount == 2);
|
+ fBreakpointEventCount, fBreakpointEventCount == 2);
|
||||||
assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT_UPDATED event(s), received "
|
assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT_UPDATED event(s), received "
|
||||||
|
@ -2411,7 +2409,7 @@ public class MIBreakpointsTest extends BaseTestCase {
|
||||||
assertTrue(fWait.getMessage(), fWait.isOK());
|
assertTrue(fWait.getMessage(), fWait.isOK());
|
||||||
|
|
||||||
// Ensure that right BreakpointEvents were received
|
// Ensure that right BreakpointEvents were received
|
||||||
waitForBreakpointEvent(2);
|
waitForBreakpointEventsAfterBreakpointOperationWhileTargetRunning(false, 2);
|
||||||
assertTrue("BreakpointEvent problem: expected " + 2 + " BREAKPOINT event(s), received "
|
assertTrue("BreakpointEvent problem: expected " + 2 + " BREAKPOINT event(s), received "
|
||||||
+ fBreakpointEventCount, fBreakpointEventCount == 2);
|
+ fBreakpointEventCount, fBreakpointEventCount == 2);
|
||||||
assertTrue("BreakpointEvent problem: expected " + 2 + " BREAKPOINT_ADDED event(s), received "
|
assertTrue("BreakpointEvent problem: expected " + 2 + " BREAKPOINT_ADDED event(s), received "
|
||||||
|
@ -2595,10 +2593,10 @@ public class MIBreakpointsTest extends BaseTestCase {
|
||||||
updateBreakpoint(ref, delta);
|
updateBreakpoint(ref, delta);
|
||||||
assertTrue(fWait.getMessage(), fWait.isOK());
|
assertTrue(fWait.getMessage(), fWait.isOK());
|
||||||
|
|
||||||
MIStoppedEvent event = SyncUtil.waitForStop();
|
// Wait for the breakpoint to hit
|
||||||
|
MIStoppedEvent event = waitForBreakpointEventsAfterBreakpointOperationWhileTargetRunning(true, 2);
|
||||||
|
|
||||||
// Ensure that right BreakpointEvents were received
|
// Ensure that right BreakpointEvents were received
|
||||||
waitForBreakpointEvent(2);
|
|
||||||
assertTrue("BreakpointEvent problem: expected " + 2 + " BREAKPOINT event(s), received "
|
assertTrue("BreakpointEvent problem: expected " + 2 + " BREAKPOINT event(s), received "
|
||||||
+ fBreakpointEventCount, fBreakpointEventCount == 2);
|
+ fBreakpointEventCount, fBreakpointEventCount == 2);
|
||||||
assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT_UPDATED event(s), received "
|
assertTrue("BreakpointEvent problem: expected " + 1 + " BREAKPOINT_UPDATED event(s), received "
|
||||||
|
@ -3254,4 +3252,72 @@ public class MIBreakpointsTest extends BaseTestCase {
|
||||||
watchpoint1 == null);
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue