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