1 /* 2 * Copyright (c) 2006, 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 /** 25 * @test 26 * @bug 6485605 27 * @summary com.sun.jdi.InternalException: Inconsistent suspend policy in internal event handler 28 * 29 * @author jjh 30 * 31 * @run build TestScaffold VMConnection TargetListener TargetAdapter 32 * @run compile -g SuspendThreadTest.java 33 * @run driver SuspendThreadTest 34 */ 35 import com.sun.jdi.*; 36 import com.sun.jdi.event.*; 37 import com.sun.jdi.request.*; 38 39 40 /********** target program **********/ 41 42 class SuspendThreadTarg { 43 public static long count; 44 45 public static void bkpt() { 46 count++; 47 } 48 49 public static void main(String[] args){ 50 System.out.println("Howdy!"); 51 52 // We need this to be running so the bkpt 53 // can be hit immediately when it is enabled 54 // in the back-end. 55 while(count >= 0) { 56 bkpt(); 57 } 58 System.out.println("Goodbye from SuspendThreadTarg, count = " + count); 59 } 60 } 61 62 /********** test program **********/ 63 64 public class SuspendThreadTest extends TestScaffold { 65 ClassType targetClass; 66 ThreadReference mainThread; 67 68 SuspendThreadTest (String args[]) { 69 super(args); 70 } 71 72 public static void main(String[] args) throws Exception { 73 new SuspendThreadTest(args).startTests(); 74 } 75 76 /********** event handlers **********/ 77 78 // 1000 makes the test take over 2 mins on win32 79 static int maxBkpts = 200; 80 volatile int bkptCount; 81 // to guard against spurious wakeups from bkptSignal.wait() 82 boolean signalSent; 83 // signal that a breakpoint has happened 84 Object bkptSignal = new Object() {}; 85 BreakpointRequest bkptRequest; 86 Field debuggeeCountField; 87 88 // When we get a bkpt we want to disable the request, 89 // resume the debuggee, and then re-enable the request 90 public void breakpointReached(BreakpointEvent event) { 91 System.out.println("Got BreakpointEvent: " + bkptCount + 92 ", debuggeeCount = " + 93 ((LongValue)targetClass. 94 getValue(debuggeeCountField)).value() 95 ); 96 bkptRequest.disable(); 97 } 98 99 public void eventSetComplete(EventSet set) { 100 set.resume(); 101 102 // The main thread watchs the bkptCount to 103 // see if bkpts stop coming in. The 104 // test _should_ fail well before maxBkpts bkpts. 105 synchronized (bkptSignal) { 106 if (bkptCount++ < maxBkpts) { 107 bkptRequest.enable(); 108 } 109 signalSent = true; 110 bkptSignal.notifyAll(); 111 } 112 } 113 114 public void vmDisconnected(VMDisconnectEvent event) { 115 println("Got VMDisconnectEvent"); 116 } 117 118 /********** test core **********/ 119 120 protected void runTests() throws Exception { 121 /* 122 * Get to the top of main() 123 * to determine targetClass and mainThread 124 */ 125 BreakpointEvent bpe = startToMain("SuspendThreadTarg"); 126 targetClass = (ClassType)bpe.location().declaringType(); 127 mainThread = bpe.thread(); 128 EventRequestManager erm = vm().eventRequestManager(); 129 130 Location loc1 = findMethod(targetClass, "bkpt", "()V").location(); 131 132 bkptRequest = erm.createBreakpointRequest(loc1); 133 134 // Without this, it is a SUSPEND_ALL bkpt and the test will pass 135 bkptRequest.setSuspendPolicy(EventRequest.SUSPEND_EVENT_THREAD); 136 bkptRequest.enable(); 137 138 debuggeeCountField = targetClass.fieldByName("count"); 139 try { 140 addListener (this); 141 } catch (Exception ex){ 142 ex.printStackTrace(); 143 failure("failure: Could not add listener"); 144 throw new Exception("SuspendThreadTest: failed", ex); 145 } 146 147 int prevBkptCount; 148 vm().resume(); 149 synchronized (bkptSignal) { 150 while (bkptCount < maxBkpts) { 151 prevBkptCount = bkptCount; 152 // If we don't get a bkpt within 5 secs, 153 // the test fails 154 signalSent = false; 155 do { 156 try { 157 bkptSignal.wait(5000); 158 } catch (InterruptedException ee) { 159 } 160 } while (signalSent == false); 161 if (prevBkptCount == bkptCount) { 162 failure("failure: test hung"); 163 break; 164 } 165 } 166 } 167 println("done with loop"); 168 bkptRequest.disable(); 169 removeListener(this); 170 171 172 /* 173 * deal with results of test 174 * if anything has called failure("foo") testFailed will be true 175 */ 176 if (!testFailed) { 177 println("SuspendThreadTest: passed"); 178 } else { 179 throw new Exception("SuspendThreadTest: failed"); 180 } 181 } 182 }