/**
* @test
* @bug 6459476
* @summary Debuggee is blocked, looks like running
*
* @author jjh
*
* @run build TestScaffold VMConnection TargetListener TargetAdapter
* @run compile -g InterruptHangTest.java
* @run main InterruptHangTest
*/
import com.sun.jdi.*;
import com.sun.jdi.event.*;
import com.sun.jdi.request.*;
/*
* Debuggee has two threads. Debugger keeps stepping in
* the first thread. The second thread keeps interrupting the first
* thread. If a long time goes by with the debugger not getting
* a step event, the test fails.
*/
class InterruptHangTarg {
public static String sync = "sync";
public static void main(String[] args){
int answer = 0;
System.out.println("Howdy!");
Interruptor interruptorThread = new Interruptor(Thread.currentThread());
synchronized(sync) {
interruptorThread.start();
try {
sync.wait();
} catch (InterruptedException ee) {
System.out.println("Debuggee interruptee: interrupted before starting loop");
}
}
// Debugger will keep stepping thru this loop
for (int ii = 0; ii < 200; ii++) {
answer++;
try {
// Give other thread a chance to run
Thread.sleep(100);
} catch (InterruptedException ee) {
System.out.println("Debuggee interruptee: interrupted at iteration: "
+ ii);
}
}
// Kill the interrupter thread
interruptorThread.interrupt();
System.out.println("Goodbye from InterruptHangTarg!");
}
}
class Interruptor extends Thread {
Thread interruptee;
Interruptor(Thread interruptee) {
this.interruptee = interruptee;
}
public void run() {
synchronized(InterruptHangTarg.sync) {
InterruptHangTarg.sync.notify();
}
int ii = 0;
while(true) {
ii++;
interruptee.interrupt();
try {
Thread.sleep(10);
} catch (InterruptedException ee) {
System.out.println("Debuggee Interruptor: finished after " +
ii + " iterrupts");
break;
}
}
}
}
/********** test program **********/
public class InterruptHangTest extends TestScaffold {
ThreadReference mainThread;
Thread timerThread;
String sync = "sync";
static int nSteps = 0;
InterruptHangTest (String args[]) {
super(args);
}
public static void main(String[] args) throws Exception {
new InterruptHangTest(args).startTests();
}
/********** event handlers **********/
public void stepCompleted(StepEvent event) {
synchronized(sync) {
nSteps++;
}
println("Got StepEvent " + nSteps + " at line " +
event.location().method() + ":" +
event.location().lineNumber());
if (nSteps == 1) {
timerThread.start();
}
}
/********** test core **********/
protected void runTests() throws Exception {
BreakpointEvent bpe = startToMain("InterruptHangTarg");
mainThread = bpe.thread();
EventRequestManager erm = vm().eventRequestManager();
/*
* Set event requests
*/
StepRequest request = erm.createStepRequest(mainThread,
StepRequest.STEP_LINE,
StepRequest.STEP_OVER);
request.enable();
// Will be started by the step event handler
timerThread = new Thread("test timer") {
public void run() {
int mySteps = 0;
while (true) {
try {
Thread.sleep(20000);
synchronized(sync) {
System.out.println("steps = " + nSteps);
if (mySteps == nSteps) {
// no step for 10 secs
failure("failure: Debuggee appears to be hung");
vm().exit(-1);
break;
}
}
mySteps = nSteps;
} catch (InterruptedException ee) {
break;
}
}
}
};
/*
* resume the target listening for events
*/
listenUntilVMDisconnect();
timerThread.interrupt();
/*
* deal with results of test
* if anything has called failure("foo") testFailed will be true
*/
if (!testFailed) {
println("InterruptHangTest: passed");
} else {
throw new Exception("InterruptHangTest: failed");
}
}
}