1 /** 2 * @test 3 * @bug 6459476 4 * @summary Debuggee is blocked, looks like running 5 * 6 * @author jjh 7 * 8 * @run build TestScaffold VMConnection TargetListener TargetAdapter 9 * @run compile -g InterruptHangTest.java 10 * @run driver InterruptHangTest 11 */ 12 import com.sun.jdi.*; 13 import com.sun.jdi.event.*; 14 import com.sun.jdi.request.*; 15 16 /* 17 * Debuggee has two threads. Debugger keeps stepping in 18 * the first thread. The second thread keeps interrupting the first 19 * thread. If a long time goes by with the debugger not getting 20 * a step event, the test fails. 21 */ 22 class InterruptHangTarg { 23 public static String sync = "sync"; 24 public static void main(String[] args){ 25 int answer = 0; 26 System.out.println("Howdy!"); 27 Interruptor interruptorThread = new Interruptor(Thread.currentThread()); 28 29 synchronized(sync) { 30 interruptorThread.start(); 31 try { 32 sync.wait(); 33 } catch (InterruptedException ee) { 34 System.out.println("Debuggee interruptee: interrupted before starting loop"); 35 } 36 } 37 38 // Debugger will keep stepping thru this loop 39 for (int ii = 0; ii < 200; ii++) { 40 answer++; 41 try { 42 // Give other thread a chance to run 43 Thread.sleep(100); 44 } catch (InterruptedException ee) { 45 System.out.println("Debuggee interruptee: interrupted at iteration: " 46 + ii); 47 } 48 } 49 // Kill the interrupter thread 50 interruptorThread.interrupt(); 51 System.out.println("Goodbye from InterruptHangTarg!"); 52 } 53 } 54 55 class Interruptor extends Thread { 56 Thread interruptee; 57 Interruptor(Thread interruptee) { 58 this.interruptee = interruptee; 59 } 60 61 public void run() { 62 synchronized(InterruptHangTarg.sync) { 63 InterruptHangTarg.sync.notify(); 64 } 65 66 int ii = 0; 67 while(true) { 68 ii++; 69 interruptee.interrupt(); 70 try { 71 Thread.sleep(10); 72 } catch (InterruptedException ee) { 73 System.out.println("Debuggee Interruptor: finished after " + 74 ii + " iterrupts"); 75 break; 76 } 77 78 } 79 } 80 } 81 82 /********** test program **********/ 83 84 public class InterruptHangTest extends TestScaffold { 85 ThreadReference mainThread; 86 Thread timerThread; 87 String sync = "sync"; 88 static int nSteps = 0; 89 90 InterruptHangTest (String args[]) { 91 super(args); 92 } 93 94 public static void main(String[] args) throws Exception { 95 new InterruptHangTest(args).startTests(); 96 } 97 98 /********** event handlers **********/ 99 100 public void stepCompleted(StepEvent event) { 101 synchronized(sync) { 102 nSteps++; 103 } 104 println("Got StepEvent " + nSteps + " at line " + 105 event.location().method() + ":" + 106 event.location().lineNumber()); 107 if (nSteps == 1) { 108 timerThread.start(); 109 } 110 } 111 112 /********** test core **********/ 113 114 protected void runTests() throws Exception { 115 BreakpointEvent bpe = startToMain("InterruptHangTarg"); 116 mainThread = bpe.thread(); 117 EventRequestManager erm = vm().eventRequestManager(); 118 119 /* 120 * Set event requests 121 */ 122 StepRequest request = erm.createStepRequest(mainThread, 123 StepRequest.STEP_LINE, 124 StepRequest.STEP_OVER); 125 request.enable(); 126 127 // Will be started by the step event handler 128 timerThread = new Thread("test timer") { 129 public void run() { 130 int mySteps = 0; 131 while (true) { 132 try { 133 Thread.sleep(20000); 134 synchronized(sync) { 135 System.out.println("steps = " + nSteps); 136 if (mySteps == nSteps) { 137 // no step for 10 secs 138 failure("failure: Debuggee appears to be hung"); 139 vm().exit(-1); 140 break; 141 } 142 } 143 mySteps = nSteps; 144 } catch (InterruptedException ee) { 145 break; 146 } 147 } 148 } 149 }; 150 151 /* 152 * resume the target listening for events 153 */ 154 155 listenUntilVMDisconnect(); 156 timerThread.interrupt(); 157 158 /* 159 * deal with results of test 160 * if anything has called failure("foo") testFailed will be true 161 */ 162 if (!testFailed) { 163 println("InterruptHangTest: passed"); 164 } else { 165 throw new Exception("InterruptHangTest: failed"); 166 } 167 } 168 }