/* * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ /** * @test * @bug 4407397 * @key intermittent * @summary Test the requesting of exception events * @author Robert Field * * @run build TestScaffold VMConnection * @run compile -g ExceptionEvents.java * * @run driver ExceptionEvents N A StackOverflowCaughtTarg java.lang.Exception * @run driver ExceptionEvents C A StackOverflowCaughtTarg null * @run driver ExceptionEvents C A StackOverflowCaughtTarg java.lang.Error * @run driver ExceptionEvents C A StackOverflowCaughtTarg java.lang.StackOverflowError * @run driver ExceptionEvents N A StackOverflowCaughtTarg java.lang.NullPointerException * @run driver ExceptionEvents N T StackOverflowCaughtTarg java.lang.Exception * @run driver ExceptionEvents C T StackOverflowCaughtTarg null * @run driver ExceptionEvents C T StackOverflowCaughtTarg java.lang.Error * @run driver ExceptionEvents C T StackOverflowCaughtTarg java.lang.StackOverflowError * @run driver ExceptionEvents N T StackOverflowCaughtTarg java.lang.NullPointerException * @run driver ExceptionEvents N N StackOverflowCaughtTarg java.lang.Exception * @run driver ExceptionEvents C N StackOverflowCaughtTarg null * @run driver ExceptionEvents C N StackOverflowCaughtTarg java.lang.Error * @run driver ExceptionEvents C N StackOverflowCaughtTarg java.lang.StackOverflowError * @run driver ExceptionEvents N N StackOverflowCaughtTarg java.lang.NullPointerException * @run driver ExceptionEvents N A StackOverflowUncaughtTarg java.lang.Exception * @run driver ExceptionEvents U A StackOverflowUncaughtTarg null * @run driver ExceptionEvents U A StackOverflowUncaughtTarg java.lang.Error * @run driver ExceptionEvents U A StackOverflowUncaughtTarg java.lang.StackOverflowError * @run driver ExceptionEvents N A StackOverflowUncaughtTarg java.lang.NullPointerException * @run driver ExceptionEvents N T StackOverflowUncaughtTarg java.lang.NullPointerException * @run driver ExceptionEvents N N StackOverflowUncaughtTarg java.lang.NullPointerException */ import com.sun.jdi.*; import com.sun.jdi.event.*; import com.sun.jdi.request.*; import java.util.*; class StackOverflowCaughtTarg { public static void main(String[] args) { try { throw new StackOverflowError(); } catch (Throwable exc) { // ignore } } } class StackOverflowUncaughtTarg { public static void main(String[] args) { thrower(); } static void thrower() { throw new StackOverflowError(); } } class StackOverflowIndirectTarg { public static void main(String[] args) { try { thrower(); } catch (Throwable exc) { System.out.println("Got exception: " + exc); } } static void thrower() { throw new StackOverflowError(); } } public class ExceptionEvents extends TestScaffold { static int failureCount = 0; static StringBuffer tooManySummary = new StringBuffer(); static StringBuffer notSentSummary = new StringBuffer(); static StringBuffer unexpectedSummary = new StringBuffer(); static int globalSuspendPolicy = -1; static String[] flags; final String target; final String exceptionName; final boolean caught; final boolean uncaught; final int suspendPolicy; int eventCount = 0; ExceptionRequest request; ExceptionEvents(String target, String exceptionName, boolean caught, boolean uncaught, int suspendPolicy) { super(flags); this.target = target; this.exceptionName = exceptionName; this.caught = caught; this.uncaught = uncaught; this.suspendPolicy = suspendPolicy; } static void everything() throws Exception { goNeither("StackOverflowCaughtTarg", "java.lang.Exception"); goCaught("StackOverflowCaughtTarg", null); goCaught("StackOverflowCaughtTarg", "java.lang.Error"); goCaught("StackOverflowCaughtTarg", "java.lang.StackOverflowError"); goNeither("StackOverflowCaughtTarg", "java.lang.NullPointerException"); goNeither("StackOverflowUncaughtTarg", "java.lang.Exception"); goUncaught("StackOverflowUncaughtTarg", null); goUncaught("StackOverflowUncaughtTarg", "java.lang.Error"); goUncaught("StackOverflowUncaughtTarg", "java.lang.StackOverflowError"); goNeither("StackOverflowUncaughtTarg", "java.lang.NullPointerException"); } static void usage() throws Exception { System.err.println("Use either with no arguments or"); System.err.println(" c|u|n a|t|n |null"); System.err.println("or for verbose folk"); System.err.println(" caught|uncaught|neither all|thread|none |null"); throw new IllegalArgumentException("see usage"); } public static void main(String[] args) throws Exception { StringBuffer testName = new StringBuffer("ExceptionEvents("); List flagList = new ArrayList(); List argList = new ArrayList(); for (int i = 0; i < args.length; ++i) { String arg = args[i]; if (arg.startsWith("-")) { flagList.add(arg); } else { argList.add(arg); } } flags = (String[])flagList.toArray(new String[0]); args = (String[])argList.toArray(new String[0]); if (args.length == 0) { everything(); testName.append("Full Test"); } else if (args.length == 4) { switch (args[1].toLowerCase().charAt(0)) { case 'a': globalSuspendPolicy = EventRequest.SUSPEND_ALL; break; case 't': globalSuspendPolicy = EventRequest.SUSPEND_EVENT_THREAD; break; case 'n': globalSuspendPolicy = EventRequest.SUSPEND_NONE; break; default: usage(); } String excString = args[3]; if (excString.equals("null")) { excString = null; } switch (args[0].toLowerCase().charAt(0)) { case 'c': goCaught(args[2], excString); break; case 'u': goUncaught(args[2], excString); break; case 'n': goNeither(args[2], excString); break; default: usage(); } testName.append(args[0]); testName.append(" "); testName.append(args[1]); testName.append(" "); testName.append(args[2]); } else { usage(); } testName.append(")"); summarize(testName.toString()); } static void summarize(String testName) throws Exception { // final analyse if (tooManySummary.length() > 0) { System.out.println("\nSummary of tests with too many events:\n" + tooManySummary.toString()); } if (notSentSummary.length() > 0) { System.out.println("\nSummary of tests with expected events not sent:\n" + notSentSummary.toString()); } if (unexpectedSummary.length() > 0) { System.out.println("\nSummary of tests with events when none expected:\n" + unexpectedSummary.toString()); } if (failureCount > 0) { throw new Exception(testName + " FAILED " + failureCount + " tests!"); } else { System.out.println("\n" + testName + " test PASSED"); } } /** * Target throws caught exception. * Events if caught enabled. */ static void goCaught(String target, String exceptionName) throws Exception { goSuspendPolicy(target, true, exceptionName, true, true); goSuspendPolicy(target, true, exceptionName, true, false); goSuspendPolicy(target, false, exceptionName, false, true); goSuspendPolicy(target, false, exceptionName, false, false); } /** * Target throws uncaught exception. * Events if uncaught enabled. */ static void goUncaught(String target, String exceptionName) throws Exception { goSuspendPolicy(target, true, exceptionName, true, true); goSuspendPolicy(target, true, exceptionName, false, true); goSuspendPolicy(target, false, exceptionName, true, false); goSuspendPolicy(target, false, exceptionName, false, false); } /** * Target doesn't throw named exception. No events. */ static void goNeither(String target, String exceptionName) throws Exception { goSuspendPolicy(target, false, exceptionName, true, true); goSuspendPolicy(target, false, exceptionName, false, true); goSuspendPolicy(target, false, exceptionName, true, false); goSuspendPolicy(target, false, exceptionName, false, false); } /** * Suspend policy should make no difference. * Iterate over all of them. */ static void goSuspendPolicy(String target, boolean expectedEvent, String exceptionName, boolean caught, boolean uncaught) throws Exception { if (globalSuspendPolicy != -1) { go(target, expectedEvent, exceptionName, caught, uncaught, globalSuspendPolicy); } else { go(target, expectedEvent, exceptionName, caught, uncaught, EventRequest.SUSPEND_ALL); go(target, expectedEvent, exceptionName, caught, uncaught, EventRequest.SUSPEND_EVENT_THREAD); go(target, expectedEvent, exceptionName, caught, uncaught, EventRequest.SUSPEND_NONE); } } static void go(String target, boolean expectedEvent, String exceptionName, boolean caught, boolean uncaught, int suspendPolicy) throws Exception { String description = target + " with " + exceptionName + "/caught=" + caught + "/uncaught=" + uncaught + " suspend="; switch (suspendPolicy) { case EventRequest.SUSPEND_ALL: description += "All"; break; case EventRequest.SUSPEND_EVENT_THREAD: description += "Thread"; break; case EventRequest.SUSPEND_NONE: description += "None"; break; default: throw new Exception("Test failure: bad suspend policy - " + suspendPolicy); } description += "\n"; System.out.print("\nTesting " + description); ExceptionEvents aRun = new ExceptionEvents( target, exceptionName, caught, uncaught, suspendPolicy); aRun.startTests(); aRun.analyse(expectedEvent, description); } void analyse(boolean expectedEvent, String description) { if (expectedEvent) { if (eventCount == 1) { println("pass: got expected event"); } else if (eventCount > 1) { failure("FAILURE: expected only one event got: " + eventCount); tooManySummary.append(description); ++failureCount; } else { failure("FAILURE: expected event not sent"); notSentSummary.append(description); ++failureCount; } } else { if (eventCount > 0) { failure("FAILURE: unexpected event sent"); unexpectedSummary.append(description); ++failureCount; } else { println("pass: as expected no event sent"); } } } /********** event handlers **********/ public void exceptionThrown(ExceptionEvent event) { if (event.request() == request) { try { System.out.print("ExceptionEvent: "); System.out.print("" + event.exception().referenceType().name()); Location loc = event.location(); System.out.print(" @ " + loc.method().name()); System.out.print(":" + loc.lineNumber()); } catch (VMDisconnectedException exc) { System.out.print("Oops - " + exc.toString()); } System.out.println(); eventCount++; } else { System.out.print("alien exception: "); try { println(event.toString()); } catch (VMDisconnectedException exc) { println("Oops - " + exc.toString()); } } } /** * Turn off default Exception Handling */ protected void createDefaultExceptionRequest() { } /********** test core **********/ protected void runTests() throws Exception { /* * Get to the top of main() */ startToMain(target); ReferenceType exceptionClass; if (exceptionName == null) { exceptionClass = null; } else { exceptionClass = findReferenceType(exceptionName); if (exceptionName == null) { throw new Exception("test failure - cannot find: " + exceptionName); } } request = eventRequestManager().createExceptionRequest(exceptionClass, caught, uncaught); request.addClassExclusionFilter("java.*"); request.addClassExclusionFilter("javax.*"); request.addClassExclusionFilter("sun.*"); request.addClassExclusionFilter("com.sun.*"); request.addClassExclusionFilter("com.oracle.*"); request.addClassExclusionFilter("oracle.*"); request.addClassExclusionFilter("jdk.internal.*"); request.setSuspendPolicy(suspendPolicy); request.enable(); listenUntilVMDisconnect(); } }