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