1 /* 2 * Copyright (c) 2001, 2019, 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 { main(String[] args)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 { main(String[] args)78 public static void main(String[] args) { 79 thrower(); 80 } thrower()81 static void thrower() { 82 throw new StackOverflowError(); 83 } 84 } 85 86 class StackOverflowIndirectTarg { main(String[] args)87 public static void main(String[] args) { 88 try { 89 thrower(); 90 } catch (Throwable exc) { 91 System.out.println("Got exception: " + exc); 92 } 93 } thrower()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 ExceptionEvents(String target, String exceptionName, boolean caught, boolean uncaught, int suspendPolicy)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 everything()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 usage()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 main(String[] args)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 summarize(String testName)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 */ goCaught(String target, String exceptionName)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 */ goUncaught(String target, String exceptionName)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 */ goNeither(String target, String exceptionName)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 */ goSuspendPolicy(String target, boolean expectedEvent, String exceptionName, boolean caught, boolean uncaught)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 go(String target, boolean expectedEvent, String exceptionName, boolean caught, boolean uncaught, int suspendPolicy)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 analyse(boolean expectedEvent, String description)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 exceptionThrown(ExceptionEvent event)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 */ createDefaultExceptionRequest()393 protected void createDefaultExceptionRequest() { 394 } 395 396 /********** test core **********/ 397 runTests()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.addClassExclusionFilter("jdk.vm.ci.hotspot.*"); 426 request.setSuspendPolicy(suspendPolicy); 427 request.enable(); 428 429 listenUntilVMDisconnect(); 430 } 431 } 432