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 * @author jjh 33 * 34 * @run build TestScaffold VMConnection TargetListener TargetAdapter 35 * @run compile -g InterruptHangTest.java 36 * @run driver InterruptHangTest 37 */ 38 39 /** 40 * Debuggee has two threads. Debugger keeps stepping in 41 * the first thread. The second thread keeps interrupting the first 42 * thread. If a long time goes by with the debugger not getting 43 * a step event, the test fails. 44 */ 45 class InterruptHangTarg { 46 public static String sync = "sync"; main(String[] args)47 public static void main(String[] args){ 48 int answer = 0; 49 System.out.println("Howdy!"); 50 Interruptor interruptorThread = new Interruptor(Thread.currentThread()); 51 52 synchronized(sync) { 53 interruptorThread.start(); 54 try { 55 sync.wait(); 56 } catch (InterruptedException ee) { 57 System.out.println("Debuggee interruptee: interrupted before starting loop"); 58 } 59 } 60 61 // Debugger will keep stepping thru this loop 62 for (int ii = 0; ii < 200; ii++) { 63 answer++; 64 try { 65 // Give other thread a chance to run 66 Thread.sleep(100); 67 } catch (InterruptedException ee) { 68 System.out.println("Debuggee interruptee: interrupted at iteration: " 69 + ii); 70 } 71 } 72 // Kill the interrupter thread 73 interruptorThread.interrupt(); 74 System.out.println("Goodbye from InterruptHangTarg!"); 75 } 76 } 77 78 class Interruptor extends Thread { 79 Thread interruptee; Interruptor(Thread interruptee)80 Interruptor(Thread interruptee) { 81 this.interruptee = interruptee; 82 } 83 run()84 public void run() { 85 synchronized(InterruptHangTarg.sync) { 86 InterruptHangTarg.sync.notify(); 87 } 88 89 int ii = 0; 90 while(true) { 91 ii++; 92 interruptee.interrupt(); 93 try { 94 Thread.sleep(10); 95 } catch (InterruptedException ee) { 96 System.out.println("Debuggee Interruptor: finished after " + 97 ii + " iterrupts"); 98 break; 99 } 100 101 } 102 } 103 } 104 105 /********** test program **********/ 106 107 public class InterruptHangTest extends TestScaffold { 108 ThreadReference mainThread; 109 Thread timerThread; 110 String sync = "sync"; 111 static int nSteps = 0; 112 InterruptHangTest(String args[])113 InterruptHangTest (String args[]) { 114 super(args); 115 } 116 main(String[] args)117 public static void main(String[] args) throws Exception { 118 new InterruptHangTest(args).startTests(); 119 } 120 121 /********** event handlers **********/ 122 stepCompleted(StepEvent event)123 public void stepCompleted(StepEvent event) { 124 synchronized(sync) { 125 nSteps++; 126 } 127 println("Got StepEvent " + nSteps + " at line " + 128 event.location().method() + ":" + 129 event.location().lineNumber()); 130 if (nSteps == 1) { 131 timerThread.start(); 132 } 133 } 134 135 /********** test core **********/ 136 runTests()137 protected void runTests() throws Exception { 138 BreakpointEvent bpe = startToMain("InterruptHangTarg"); 139 mainThread = bpe.thread(); 140 EventRequestManager erm = vm().eventRequestManager(); 141 142 /* 143 * Set event requests 144 */ 145 StepRequest request = erm.createStepRequest(mainThread, 146 StepRequest.STEP_LINE, 147 StepRequest.STEP_OVER); 148 request.enable(); 149 150 // Will be started by the step event handler 151 timerThread = new Thread("test timer") { 152 public void run() { 153 int mySteps = 0; 154 float timeoutFactor = Float.parseFloat(System.getProperty("test.timeout.factor", "1.0")); 155 long sleepSeconds = (long)(20 * timeoutFactor); 156 println("Timer watching for steps every " + sleepSeconds + " seconds"); 157 while (true) { 158 try { 159 Thread.sleep(sleepSeconds * 1000); 160 synchronized(sync) { 161 println("steps = " + nSteps); 162 if (mySteps == nSteps) { 163 // no step for a long time 164 failure("failure: Debuggee appears to be hung (no steps for " + sleepSeconds + "s)"); 165 vm().exit(-1); 166 break; 167 } 168 } 169 mySteps = nSteps; 170 } catch (InterruptedException ee) { 171 break; 172 } 173 } 174 } 175 }; 176 177 /* 178 * resume the target listening for events 179 */ 180 181 listenUntilVMDisconnect(); 182 timerThread.interrupt(); 183 184 /* 185 * deal with results of test 186 * if anything has called failure("foo") testFailed will be true 187 */ 188 if (!testFailed) { 189 println("InterruptHangTest: passed"); 190 } else { 191 throw new Exception("InterruptHangTest: failed"); 192 } 193 } 194 } 195