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