1 /* 2 * Copyright (c) 2006, 2015, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 import com.sun.jdi.*; 25 import com.sun.jdi.event.*; 26 import com.sun.jdi.request.*; 27 28 /** 29 * @test 30 * @bug 6459476 31 * @summary Debuggee is blocked, looks like running 32 * 33 * @author jjh 34 * 35 * @modules jdk.jdi 36 * @run build TestScaffold VMConnection TargetListener TargetAdapter 37 * @run compile -g InterruptHangTest.java 38 * @run driver InterruptHangTest 39 */ 40 41 /** 42 * Debuggee has two threads. Debugger keeps stepping in 43 * the first thread. The second thread keeps interrupting the first 44 * thread. If a long time goes by with the debugger not getting 45 * a step event, the test fails. 46 */ 47 class InterruptHangTarg { 48 public static String sync = "sync"; 49 public static void main(String[] args){ 50 int answer = 0; 51 System.out.println("Howdy!"); 52 Interruptor interruptorThread = new Interruptor(Thread.currentThread()); 53 54 synchronized(sync) { 55 interruptorThread.start(); 56 try { 57 sync.wait(); 58 } catch (InterruptedException ee) { 59 System.out.println("Debuggee interruptee: interrupted before starting loop"); 60 } 61 } 62 63 // Debugger will keep stepping thru this loop 64 for (int ii = 0; ii < 200; ii++) { 65 answer++; 66 try { 67 // Give other thread a chance to run 68 Thread.sleep(100); 69 } catch (InterruptedException ee) { 70 System.out.println("Debuggee interruptee: interrupted at iteration: " 71 + ii); 72 } 73 } 74 // Kill the interrupter thread 75 interruptorThread.interrupt(); 76 System.out.println("Goodbye from InterruptHangTarg!"); 77 } 78 } 79 80 class Interruptor extends Thread { 81 Thread interruptee; 82 Interruptor(Thread interruptee) { 83 this.interruptee = interruptee; 84 } 85 86 public void run() { 87 synchronized(InterruptHangTarg.sync) { 88 InterruptHangTarg.sync.notify(); 89 } 90 91 int ii = 0; 92 while(true) { 93 ii++; 94 interruptee.interrupt(); 95 try { 96 Thread.sleep(10); 97 } catch (InterruptedException ee) { 98 System.out.println("Debuggee Interruptor: finished after " + 99 ii + " iterrupts"); 100 break; 101 } 102 103 } 104 } 105 } 106 107 /********** test program **********/ 108 109 public class InterruptHangTest extends TestScaffold { 110 ThreadReference mainThread; 111 Thread timerThread; 112 String sync = "sync"; 113 static int nSteps = 0; 114 115 InterruptHangTest (String args[]) { 116 super(args); 117 } 118 119 public static void main(String[] args) throws Exception { 120 new InterruptHangTest(args).startTests(); 121 } 122 123 /********** event handlers **********/ 124 125 public void stepCompleted(StepEvent event) { 126 synchronized(sync) { 127 nSteps++; 128 } 129 println("Got StepEvent " + nSteps + " at line " + 130 event.location().method() + ":" + 131 event.location().lineNumber()); 132 if (nSteps == 1) { 133 timerThread.start(); 134 } 135 } 136 137 /********** test core **********/ 138 139 protected void runTests() throws Exception { 140 BreakpointEvent bpe = startToMain("InterruptHangTarg"); 141 mainThread = bpe.thread(); 142 EventRequestManager erm = vm().eventRequestManager(); 143 144 /* 145 * Set event requests 146 */ 147 StepRequest request = erm.createStepRequest(mainThread, 148 StepRequest.STEP_LINE, 149 StepRequest.STEP_OVER); 150 request.enable(); 151 152 // Will be started by the step event handler 153 timerThread = new Thread("test timer") { 154 public void run() { 155 int mySteps = 0; 156 float timeoutFactor = Float.parseFloat(System.getProperty("test.timeout.factor", "1.0")); 157 long sleepSeconds = (long)(20 * timeoutFactor); 158 println("Timer watching for steps every " + sleepSeconds + " seconds"); 159 while (true) { 160 try { 161 Thread.sleep(sleepSeconds * 1000); 162 synchronized(sync) { 163 println("steps = " + nSteps); 164 if (mySteps == nSteps) { 165 // no step for a long time 166 failure("failure: Debuggee appears to be hung (no steps for " + sleepSeconds + "s)"); 167 vm().exit(-1); 168 break; 169 } 170 } 171 mySteps = nSteps; 172 } catch (InterruptedException ee) { 173 break; 174 } 175 } 176 } 177 }; 178 179 /* 180 * resume the target listening for events 181 */ 182 183 listenUntilVMDisconnect(); 184 timerThread.interrupt(); 185 186 /* 187 * deal with results of test 188 * if anything has called failure("foo") testFailed will be true 189 */ 190 if (!testFailed) { 191 println("InterruptHangTest: passed"); 192 } else { 193 throw new Exception("InterruptHangTest: failed"); 194 } 195 } 196 }