1 /* 2 * Copyright (c) 2001, 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 25 /** 26 * @test 27 * @bug 4359247 28 * @summary Breakpoints on multiple threads have problems. 29 * 30 * @author tbell, jjh 31 * 32 * @modules jdk.jdi 33 * @build TestScaffold VMConnection TargetListener TargetAdapter 34 * @run compile -g MultiBreakpointsTest.java 35 * @run driver MultiBreakpointsTest 36 */ 37 38 /* 39 * This test runs a debuggee with n threads each of which just loops 40 * doing some printlns and calling a method. The debugger sets 41 * bkpts on these methods and verifies that they are all hit. 42 * The default number of threads is 4. To change it to say 10, 43 * pass this to the testcase on the cmd line: 44 * -Dnthreads=10 45 * The current max allowed value of nthreads is 30. 46 * You can also do this, for example, 47 * -Dnhits=30 48 * to change the number of times the bkpts are to be hit from 49 * the default of 100 to 30. 50 */ 51 import com.sun.jdi.*; 52 import com.sun.jdi.event.*; 53 import com.sun.jdi.request.*; 54 55 import java.util.*; 56 57 /********** target program **********/ 58 59 import java.io.*; 60 import java.text.*; 61 62 class MultiBreakpointsTarg { 63 64 MultiBreakpointsTarg(int numThreads, int numHits) { 65 for (int ii = 0; ii < numThreads; ii++) { 66 console(ii, numHits); 67 } 68 } 69 70 public static void main(String args[]) { 71 72 int nthreads; 73 int nhits; 74 String nStr = System.getProperty("nthreads"); 75 76 if (nStr == null) { 77 throw new RuntimeException("nthreads = null in debuggee"); 78 } 79 nthreads = Integer.parseInt(nStr); 80 81 nStr = System.getProperty("nhits"); 82 if (nStr == null) { 83 throw new RuntimeException("nhits = null in debuggee"); 84 } 85 nhits = Integer.parseInt(nStr); 86 87 System.out.println("Debuggee: nthreads = " + nthreads + ", nhits = " + nhits); 88 89 MultiBreakpointsTarg ptr = new MultiBreakpointsTarg(nthreads, nhits); 90 91 // for (int i = 0; i < nthreads; i++) { 92 // ptr.console(i); 93 // } 94 } 95 96 // The brute force approach for simplicity - don't use reflection 97 // nor set thread specific bkpts. Use of those features would 98 // make for interesting tests too, and maybe would prove that 99 // we don't really have to bother doing it this dumb way. 100 101 void bkpt0() {} 102 void bkpt1() {} 103 void bkpt2() {} 104 void bkpt3() {} 105 void bkpt4() {} 106 void bkpt5() {} 107 void bkpt6() {} 108 void bkpt7() {} 109 void bkpt8() {} 110 void bkpt9() {} 111 void bkpt10() {} 112 void bkpt11() {} 113 void bkpt12() {} 114 void bkpt13() {} 115 void bkpt14() {} 116 void bkpt15() {} 117 void bkpt16() {} 118 void bkpt17() {} 119 void bkpt18() {} 120 void bkpt19() {} 121 void bkpt20() {} 122 void bkpt21() {} 123 void bkpt22() {} 124 void bkpt23() {} 125 void bkpt24() {} 126 void bkpt25() {} 127 void bkpt26() {} 128 void bkpt27() {} 129 void bkpt28() {} 130 void bkpt29() {} 131 132 void console(final int num, final int nhits) { 133 final InputStreamReader isr = new InputStreamReader(System.in); 134 final BufferedReader br = new BufferedReader(isr); 135 136 // Create the threads 137 // 138 //final String threadName = "DebuggeeThread: " + num; 139 final String threadName = "" + num; 140 Thread thrd = new Thread( threadName ) { 141 public void run() { 142 synchronized( isr ) { 143 boolean done = false; 144 try { 145 // For each thread, run until numHits bkpts have been hit 146 for( int i = 0; i < nhits; i++ ) { 147 // This is a tendril from the original jdb test. 148 // It could probably be deleted. 149 System.out.println("Thread " + threadName + " Enter a string: "); 150 String s = "test" + num; 151 switch (num) { 152 case 0: bkpt0(); break; 153 case 1: bkpt1(); break; 154 case 2: bkpt2(); break; 155 case 3: bkpt3(); break; 156 case 4: bkpt4(); break; 157 case 5: bkpt5(); break; 158 case 6: bkpt6(); break; 159 case 7: bkpt7(); break; 160 case 8: bkpt8(); break; 161 case 9: bkpt9(); break; 162 case 10: bkpt10(); break; 163 case 11: bkpt11(); break; 164 case 12: bkpt12(); break; 165 case 13: bkpt13(); break; 166 case 14: bkpt14(); break; 167 case 15: bkpt15(); break; 168 case 16: bkpt16(); break; 169 case 17: bkpt17(); break; 170 case 18: bkpt18(); break; 171 case 19: bkpt19(); break; 172 case 20: bkpt20(); break; 173 case 21: bkpt21(); break; 174 case 22: bkpt22(); break; 175 case 23: bkpt23(); break; 176 case 24: bkpt24(); break; 177 case 25: bkpt25(); break; 178 case 26: bkpt26(); break; 179 case 27: bkpt27(); break; 180 case 28: bkpt28(); break; 181 case 29: bkpt29(); break; 182 } 183 System.out.println("Thread " + threadName + " You entered : " + s); 184 185 if( s.compareTo( "quit" ) == 0 ) 186 done = true; 187 } 188 } catch(Exception e) { 189 System.out.println("WOOPS"); 190 } 191 } 192 } 193 }; 194 thrd.setPriority(Thread.MAX_PRIORITY-1); 195 thrd.start(); 196 } 197 } 198 199 /********** test program **********/ 200 201 public class MultiBreakpointsTest extends TestScaffold { 202 ReferenceType targetClass; 203 ThreadReference mainThread; 204 EventRequestManager erm; 205 206 static int nthreads; 207 static int nhits; 208 209 BreakpointRequest bkpts[]; 210 int hits[]; 211 212 MultiBreakpointsTest (String args[]) { 213 super(args); 214 bkpts = new BreakpointRequest[nthreads]; 215 hits = new int[nthreads]; 216 } 217 218 public static void main(String[] args) throws Exception { 219 String countStr = System.getProperty("nthreads"); 220 if (countStr == null) { 221 nthreads = 4; 222 } else { 223 nthreads = Integer.parseInt(countStr); 224 } 225 if ( nthreads > 30) { 226 throw new RuntimeException("nthreads is greater than 30: " + nthreads); 227 } 228 countStr = System.getProperty("nhits"); 229 if (countStr == null) { 230 nhits = 100; 231 } else { 232 nhits = Integer.parseInt(countStr); 233 } 234 235 args = new String[] { "-J-Dnthreads=" + nthreads, "-J-Dnhits=" + nhits} ; 236 new MultiBreakpointsTest(args).startTests(); 237 } 238 239 /********** event handlers **********/ 240 241 242 public void breakpointReached(BreakpointEvent event) { 243 BreakpointRequest req = (BreakpointRequest)event.request(); 244 for ( int ii = 0; ii < nthreads; ii++) { 245 if (req == bkpts[ii]) { 246 println("Hit bkpt on thread: " +ii+ ": " + ++hits[ii]); 247 break; 248 } 249 } 250 } 251 252 253 public BreakpointRequest setBreakpoint(String clsName, 254 String methodName, 255 String methodSignature) { 256 ReferenceType rt = findReferenceType(clsName); 257 if (rt == null) { 258 rt = resumeToPrepareOf(clsName).referenceType(); 259 } 260 261 Method method = findMethod(rt, methodName, methodSignature); 262 if (method == null) { 263 throw new IllegalArgumentException("Bad method name/signature"); 264 } 265 BreakpointRequest bpr = erm.createBreakpointRequest(method.location()); 266 bpr.setSuspendPolicy(EventRequest.SUSPEND_ALL); 267 //bpr.setSuspendPolicy(EventRequest.SUSPEND_EVENT_THREAD); 268 bpr.enable(); 269 return bpr; 270 } 271 272 /********** test core **********/ 273 274 protected void runTests() throws Exception { 275 /* 276 * Get to the top of main() 277 * to determine targetClass and mainThread 278 */ 279 280 BreakpointEvent bpe = startToMain("MultiBreakpointsTarg"); 281 282 targetClass = bpe.location().declaringType(); 283 mainThread = bpe.thread(); 284 erm = vm().eventRequestManager(); 285 286 for (int ii = 0 ; ii < nthreads; ii++) { 287 bkpts[ii] = setBreakpoint("MultiBreakpointsTarg", 288 "bkpt" + ii, 289 "()V"); 290 } 291 /* 292 * resume the target listening for events 293 */ 294 listenUntilVMDisconnect(); 295 296 for ( int ii = 0; ii < nthreads; ii++) { 297 if (hits[ii] != nhits) { 298 failure("FAILED: Expected " + nhits + " breakpoints for thread " + ii + " but only got " + hits[ii]); 299 } 300 } 301 302 /* 303 * deal with results of test 304 * if anything has called failure("foo") testFailed will be true 305 */ 306 if (!testFailed) { 307 println("MultiBreakpointsTest: passed"); 308 } else { 309 throw new Exception("MultiBreakpointsTest: failed"); 310 } 311 } 312 }