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 * @test 26 * @bug 4407397 27 * @key intermittent 28 * @summary Test the requesting of exception events 29 * @author Robert Field 30 * 31 * @run build TestScaffold VMConnection 32 * @run compile -g ExceptionEvents.java 33 * 34 * @run driver ExceptionEvents N A StackOverflowCaughtTarg java.lang.Exception 35 * @run driver ExceptionEvents C A StackOverflowCaughtTarg null 36 * @run driver ExceptionEvents C A StackOverflowCaughtTarg java.lang.Error 37 * @run driver ExceptionEvents C A StackOverflowCaughtTarg java.lang.StackOverflowError 38 * @run driver ExceptionEvents N A StackOverflowCaughtTarg java.lang.NullPointerException 39 40 * @run driver ExceptionEvents N T StackOverflowCaughtTarg java.lang.Exception 41 * @run driver ExceptionEvents C T StackOverflowCaughtTarg null 42 * @run driver ExceptionEvents C T StackOverflowCaughtTarg java.lang.Error 43 * @run driver ExceptionEvents C T StackOverflowCaughtTarg java.lang.StackOverflowError 44 * @run driver ExceptionEvents N T StackOverflowCaughtTarg java.lang.NullPointerException 45 46 * @run driver ExceptionEvents N N StackOverflowCaughtTarg java.lang.Exception 47 * @run driver ExceptionEvents C N StackOverflowCaughtTarg null 48 * @run driver ExceptionEvents C N StackOverflowCaughtTarg java.lang.Error 49 * @run driver ExceptionEvents C N StackOverflowCaughtTarg java.lang.StackOverflowError 50 * @run driver ExceptionEvents N N StackOverflowCaughtTarg java.lang.NullPointerException 51 52 * @run driver ExceptionEvents N A StackOverflowUncaughtTarg java.lang.Exception 53 * @run driver ExceptionEvents U A StackOverflowUncaughtTarg null 54 * @run driver ExceptionEvents U A StackOverflowUncaughtTarg java.lang.Error 55 * @run driver ExceptionEvents U A StackOverflowUncaughtTarg java.lang.StackOverflowError 56 * @run driver ExceptionEvents N A StackOverflowUncaughtTarg java.lang.NullPointerException 57 58 * @run driver ExceptionEvents N T StackOverflowUncaughtTarg java.lang.NullPointerException 59 * @run driver ExceptionEvents N N StackOverflowUncaughtTarg java.lang.NullPointerException 60 61 */ 62 import com.sun.jdi.*; 63 import com.sun.jdi.event.*; 64 import com.sun.jdi.request.*; 65 import java.util.*; 66 67 class StackOverflowCaughtTarg { 68 public static void main(String[] args) { 69 try { 70 throw new StackOverflowError(); 71 } catch (Throwable exc) { 72 // ignore 73 } 74 } 75 } 76 77 class StackOverflowUncaughtTarg { 78 public static void main(String[] args) { 79 thrower(); 80 } 81 static void thrower() { 82 throw new StackOverflowError(); 83 } 84 } 85 86 class StackOverflowIndirectTarg { 87 public static void main(String[] args) { 88 try { 89 thrower(); 90 } catch (Throwable exc) { 91 System.out.println("Got exception: " + exc); 92 } 93 } 94 static void thrower() { 95 throw new StackOverflowError(); 96 } 97 } 98 99 public class ExceptionEvents extends TestScaffold { 100 static int failureCount = 0; 101 static StringBuffer tooManySummary = new StringBuffer(); 102 static StringBuffer notSentSummary = new StringBuffer(); 103 static StringBuffer unexpectedSummary = new StringBuffer(); 104 static int globalSuspendPolicy = -1; 105 static String[] flags; 106 107 final String target; 108 final String exceptionName; 109 final boolean caught; 110 final boolean uncaught; 111 final int suspendPolicy; 112 113 int eventCount = 0; 114 ExceptionRequest request; 115 116 ExceptionEvents(String target, 117 String exceptionName, 118 boolean caught, boolean uncaught, 119 int suspendPolicy) { 120 super(flags); 121 this.target = target; 122 this.exceptionName = exceptionName; 123 this.caught = caught; 124 this.uncaught = uncaught; 125 this.suspendPolicy = suspendPolicy; 126 } 127 128 static void everything() throws Exception { 129 goNeither("StackOverflowCaughtTarg", "java.lang.Exception"); 130 goCaught("StackOverflowCaughtTarg", null); 131 goCaught("StackOverflowCaughtTarg", "java.lang.Error"); 132 goCaught("StackOverflowCaughtTarg", "java.lang.StackOverflowError"); 133 goNeither("StackOverflowCaughtTarg", "java.lang.NullPointerException"); 134 135 goNeither("StackOverflowUncaughtTarg", "java.lang.Exception"); 136 goUncaught("StackOverflowUncaughtTarg", null); 137 goUncaught("StackOverflowUncaughtTarg", "java.lang.Error"); 138 goUncaught("StackOverflowUncaughtTarg", "java.lang.StackOverflowError"); 139 goNeither("StackOverflowUncaughtTarg", "java.lang.NullPointerException"); 140 } 141 142 static void usage() throws Exception { 143 System.err.println("Use either with no arguments or"); 144 System.err.println(" c|u|n a|t|n <TargetClass> <Exception>|null"); 145 System.err.println("or for verbose folk"); 146 System.err.println(" caught|uncaught|neither all|thread|none <TargetClass> <Exception>|null"); 147 throw new IllegalArgumentException("see usage"); 148 } 149 150 public static void main(String[] args) throws Exception { 151 StringBuffer testName = new StringBuffer("ExceptionEvents("); 152 List flagList = new ArrayList(); 153 List argList = new ArrayList(); 154 155 for (int i = 0; i < args.length; ++i) { 156 String arg = args[i]; 157 if (arg.startsWith("-")) { 158 flagList.add(arg); 159 } else { 160 argList.add(arg); 161 } 162 } 163 flags = (String[])flagList.toArray(new String[0]); 164 args = (String[])argList.toArray(new String[0]); 165 if (args.length == 0) { 166 everything(); 167 testName.append("Full Test"); 168 } else if (args.length == 4) { 169 switch (args[1].toLowerCase().charAt(0)) { 170 case 'a': 171 globalSuspendPolicy = EventRequest.SUSPEND_ALL; 172 break; 173 case 't': 174 globalSuspendPolicy = EventRequest.SUSPEND_EVENT_THREAD; 175 break; 176 case 'n': 177 globalSuspendPolicy = EventRequest.SUSPEND_NONE; 178 break; 179 default: 180 usage(); 181 } 182 String excString = args[3]; 183 if (excString.equals("null")) { 184 excString = null; 185 } 186 switch (args[0].toLowerCase().charAt(0)) { 187 case 'c': 188 goCaught(args[2], excString); 189 break; 190 case 'u': 191 goUncaught(args[2], excString); 192 break; 193 case 'n': 194 goNeither(args[2], excString); 195 break; 196 default: 197 usage(); 198 } 199 testName.append(args[0]); 200 testName.append(" "); 201 testName.append(args[1]); 202 testName.append(" "); 203 testName.append(args[2]); 204 } else { 205 usage(); 206 } 207 testName.append(")"); 208 209 summarize(testName.toString()); 210 } 211 212 static void summarize(String testName) throws Exception { 213 // final analyse 214 if (tooManySummary.length() > 0) { 215 System.out.println("\nSummary of tests with too many events:\n" + 216 tooManySummary.toString()); 217 } 218 if (notSentSummary.length() > 0) { 219 System.out.println("\nSummary of tests with expected events not sent:\n" + 220 notSentSummary.toString()); 221 } 222 if (unexpectedSummary.length() > 0) { 223 System.out.println("\nSummary of tests with events when none expected:\n" + 224 unexpectedSummary.toString()); 225 } 226 227 if (failureCount > 0) { 228 throw new Exception(testName + " FAILED " + 229 failureCount + " tests!"); 230 } else { 231 System.out.println("\n" + testName + " test PASSED"); 232 } 233 } 234 235 /** 236 * Target throws caught exception. 237 * Events if caught enabled. 238 */ 239 static void goCaught(String target, 240 String exceptionName) throws Exception { 241 goSuspendPolicy(target, true, exceptionName, 242 true, true); 243 goSuspendPolicy(target, true, exceptionName, 244 true, false); 245 goSuspendPolicy(target, false, exceptionName, 246 false, true); 247 goSuspendPolicy(target, false, exceptionName, 248 false, false); 249 } 250 251 /** 252 * Target throws uncaught exception. 253 * Events if uncaught enabled. 254 */ 255 static void goUncaught(String target, 256 String exceptionName) throws Exception { 257 goSuspendPolicy(target, true, exceptionName, 258 true, true); 259 goSuspendPolicy(target, true, exceptionName, 260 false, true); 261 goSuspendPolicy(target, false, exceptionName, 262 true, false); 263 goSuspendPolicy(target, false, exceptionName, 264 false, false); 265 } 266 267 /** 268 * Target doesn't throw named exception. No events. 269 */ 270 static void goNeither(String target, 271 String exceptionName) throws Exception { 272 goSuspendPolicy(target, false, exceptionName, 273 true, true); 274 goSuspendPolicy(target, false, exceptionName, 275 false, true); 276 goSuspendPolicy(target, false, exceptionName, 277 true, false); 278 goSuspendPolicy(target, false, exceptionName, 279 false, false); 280 } 281 282 /** 283 * Suspend policy should make no difference. 284 * Iterate over all of them. 285 */ 286 static void goSuspendPolicy(String target, 287 boolean expectedEvent, 288 String exceptionName, 289 boolean caught, boolean uncaught) throws Exception { 290 if (globalSuspendPolicy != -1) { 291 go(target, expectedEvent, exceptionName, 292 caught, uncaught, globalSuspendPolicy); 293 } else { 294 go(target, expectedEvent, exceptionName, 295 caught, uncaught, EventRequest.SUSPEND_ALL); 296 go(target, expectedEvent, exceptionName, 297 caught, uncaught, EventRequest.SUSPEND_EVENT_THREAD); 298 go(target, expectedEvent, exceptionName, 299 caught, uncaught, EventRequest.SUSPEND_NONE); 300 } 301 } 302 303 static void go(String target, 304 boolean expectedEvent, 305 String exceptionName, 306 boolean caught, boolean uncaught, 307 int suspendPolicy) throws Exception { 308 String description = target + " with " + 309 exceptionName + 310 "/caught=" + caught + 311 "/uncaught=" + uncaught + 312 " suspend="; 313 switch (suspendPolicy) { 314 case EventRequest.SUSPEND_ALL: 315 description += "All"; 316 break; 317 case EventRequest.SUSPEND_EVENT_THREAD: 318 description += "Thread"; 319 break; 320 case EventRequest.SUSPEND_NONE: 321 description += "None"; 322 break; 323 default: 324 throw new Exception("Test failure: bad suspend policy - " + 325 suspendPolicy); 326 } 327 description += "\n"; 328 329 System.out.print("\nTesting " + description); 330 331 ExceptionEvents aRun = new ExceptionEvents( 332 target, 333 exceptionName, caught, uncaught, 334 suspendPolicy); 335 aRun.startTests(); 336 aRun.analyse(expectedEvent, description); 337 } 338 339 void analyse(boolean expectedEvent, String description) { 340 if (expectedEvent) { 341 if (eventCount == 1) { 342 println("pass: got expected event"); 343 } else if (eventCount > 1) { 344 failure("FAILURE: expected only one event got: " + 345 eventCount); 346 tooManySummary.append(description); 347 ++failureCount; 348 } else { 349 failure("FAILURE: expected event not sent"); 350 notSentSummary.append(description); 351 ++failureCount; 352 } 353 } else { 354 if (eventCount > 0) { 355 failure("FAILURE: unexpected event sent"); 356 unexpectedSummary.append(description); 357 ++failureCount; 358 } else { 359 println("pass: as expected no event sent"); 360 } 361 } 362 } 363 364 365 /********** event handlers **********/ 366 367 public void exceptionThrown(ExceptionEvent event) { 368 if (event.request() == request) { 369 try { 370 System.out.print("ExceptionEvent: "); 371 System.out.print("" + event.exception().referenceType().name()); 372 Location loc = event.location(); 373 System.out.print(" @ " + loc.method().name()); 374 System.out.print(":" + loc.lineNumber()); 375 } catch (VMDisconnectedException exc) { 376 System.out.print("Oops - " + exc.toString()); 377 } 378 System.out.println(); 379 eventCount++; 380 } else { 381 System.out.print("alien exception: "); 382 try { 383 println(event.toString()); 384 } catch (VMDisconnectedException exc) { 385 println("Oops - " + exc.toString()); 386 } 387 } 388 } 389 390 /** 391 * Turn off default Exception Handling 392 */ 393 protected void createDefaultExceptionRequest() { 394 } 395 396 /********** test core **********/ 397 398 protected void runTests() throws Exception { 399 /* 400 * Get to the top of main() 401 */ 402 startToMain(target); 403 404 ReferenceType exceptionClass; 405 406 if (exceptionName == null) { 407 exceptionClass = null; 408 } else { 409 exceptionClass = findReferenceType(exceptionName); 410 if (exceptionName == null) { 411 throw new Exception("test failure - cannot find: " + 412 exceptionName); 413 } 414 } 415 416 request = eventRequestManager().createExceptionRequest(exceptionClass, 417 caught, uncaught); 418 request.addClassExclusionFilter("java.*"); 419 request.addClassExclusionFilter("javax.*"); 420 request.addClassExclusionFilter("sun.*"); 421 request.addClassExclusionFilter("com.sun.*"); 422 request.addClassExclusionFilter("com.oracle.*"); 423 request.addClassExclusionFilter("oracle.*"); 424 request.addClassExclusionFilter("jdk.internal.*"); 425 request.setSuspendPolicy(suspendPolicy); 426 request.enable(); 427 428 listenUntilVMDisconnect(); 429 } 430 }