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