Path: blob/master/test/hotspot/jtreg/vmTestbase/nsk/stress/except/except004.java
41155 views
/*1* Copyright (c) 1999, 2021, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/222324/*25* @test26* @key stress27*28* @summary converted from VM testbase nsk/stress/except/except004.29* VM testbase keywords: [stress, diehard, slow, nonconcurrent, quick]30* VM testbase readme:31* DESCRIPTION32* This checks if various exceptions are thrown (and caught) correctly33* when there apparently are no free space in the heap to allocate new34* Throwable instance.35* The test tries to occupy all of memory available in the heap by allocating36* lots of new Object() instances. Instances of the type Object are the smallest37* objects, so they apparently should occupy most fine-grained fragments in the38* heap and leave no free space for new Throwable instance. After that, the test39* provokes various exceptions (e.g.: by executing integer division by 0 and so40* on), and checks if appropriate exceptions are thrown.41* COMMENTS42* The test needs a lot of memory to start up, so it should not run under older43* JDK 1.1.x release due to its poorer heap utilization. Also, some checks are44* skipped when testing classic VM, because OutOfMemoryError is correctly thrown45* instead of target exception.46* When the test is being self-initiating (i.e.: eating heap), memory occupation47* is terminated if memory allocation slows down crucially. This is a workaround48* intended to avoid the HotSpot bug:49* #4248801 (P1/S5) slow memory allocation when heap is almost exhausted50* There is also a workaround involved to avoid the following bugs known51* for HotSpot and for classic VM:52* #4239841 (P1/S5) 1.1: poor garbage collector performance (HotSpot bug)53* #4245060 (P4/S5) poor garbage collector performance (Classic VM bug)54* However, printing of the test's error messages, warnings, and of execution55* trace fails under JDK 1.2 for Win32 even so. If the test fails due to this56* problem, exit status 96 is returned instead of 97.57* JDK 1.3 classic VM for Sparc may crash (core dump) due to the known bug:58* #4245057 (P2/S3) VM crashes when heap is exhausted59*60* @run main/othervm -Xms50M -Xmx200M -XX:-UseGCOverheadLimit nsk.stress.except.except00461*/6263package nsk.stress.except;6465import java.io.PrintStream;66import java.lang.reflect.Field;6768/**69* This checks if various exceptions are thrown (and caught) correctly70* when there apparently are no free space in the heap to allocate new71* <code>Throwable</code> instance.72* <p>73* <p>The test tries to occupy all of memory available in the heap by74* allocating lots of new <code>Object()</code> instances. Instances of the75* type <code>Object</code> are the smallest objects, so they apparently should76* occupy most fine-grained fragments in the heap and leave no free space for77* new <code>Throwable</code> instance. After that, the test provokes various78* exceptions (e.g.: by executing integer division by 0 and so on), and checks79* if appropriate exceptions are thrown.80* <p>81* <p>Note, that memory occupation is terminated if memory allocation slows82* down crucially. This is a workaround intended to avoid the HotSpot bug:83* <br> 84* #4248801 (P1/S5) slow memory allocation when heap is almost exhausted85* <p>86* <p>There is also a workaround involved to avoid the following bugs known87* for HotSpot and for classic VM:88* <br> 89* #4239841 (P1/S5) 1.1: poor garbage collector performance90* <br> 91* #4245060 (P4/S5) poor garbage collector performance92* <br>However, printing of the test's error messages, warnings, and of93* execution trace may fail even so. If the test fails due to poor GC94* performance, exit status 96 is returned instead of 97.95* <p>96* <p>Also note, that the test needs a lot of memory to start up, so it should97* not run under older JDK 1.1.x release due to its poor heap utilization.98*/99public class except004 {100/**101* Either allow or supress printing of execution trace.102*/103private static boolean TRACE_ON = false;104/**105* Either allow or supress printing of warning messages.106*/107private static final boolean WARN_ON = true;108/*109* Storage for a lot of tiny objects110* "static volatile" keywords are for preventing heap optimization111*/112private static volatile Object pool[] = null;113/**114* Temporary <code>log</code> for error messages, warnings and/or execution trace.115*116* @see #messages117*/118private static String log[] = new String[1000]; // up to 1000 messages119/**120* How many <code>messages</code> were submitted to the <code>log</code>.121*122* @see #log123*/124private static int messages = 0;125126/**127* Re-call to the method <code>run(out)</code> (ignore <code>args[]</code>),128* and print the test summary - either test passed of failed.129*/130public static int run(String args[], PrintStream out) {131if (args.length > 0) {132if (args[0].toLowerCase().startsWith("-v"))133TRACE_ON = true;134}135136int exitCode;137try {138exitCode = run(out);139} finally { // ensure we have free memory for exception processing140pool = null;141System.gc();142}143if (TRACE_ON)144out.println("Test completed.");145146// Print the log[] and the test summary:147try {148for (int i = 0; i < messages; i++)149out.println(log[i]);150if (exitCode == 0) {151if (TRACE_ON)152out.println("Test passed.");153} else154out.println("Test failed.");155} catch (OutOfMemoryError oome) {156// Poor performance of garbage collector:157exitCode = 1;158}159160return exitCode;161}162163/**164* Allocate as much <code>Object</code> instances as possible to bring JVM165* into stress, and then check if exceptions are correctly thrown accordingly166* to various situations like integer division by 0, etc.167*/168private static int run(PrintStream out) {169out.println("# While printing this message, JVM seems to initiate the output");170out.println("# stream, so that it will not need more memory to print later,");171out.println("# when the heap would fail to provide more memory.");172out.println("# ");173out.println("# Note, that the test maintains especial static log[] field in");174out.println("# order to avoid printing when the heap seems exhausted.");175out.println("# Nevertheless, printing could cause OutOfMemoryError even");176out.println("# after all the memory allocated by the test is released.");177out.println("# ");178out.println("# That problem is caused by the known JDK/HotSpot bugs:");179out.println("# 4239841 (P1/S5) 1.1: poor garbage collector performance");180out.println("# 4245060 (P4/S5) poor garbage collector performance");181out.println("# ");182out.println("# This message is just intended to work-around that problem.");183out.println("# If printing should fail even so, the test will return the");184out.println("# exit status 96 instead of 97 to indicate the problem.");185186// run all tests normally to ensure all needed classes are loaded and187// initialized before the heap is exhausted - else we may trigger OOME188// in unexpected places.189try {190if (TRACE_ON)191out.println("Running without heap exhaustion");192runTests(out, false);193} catch (Throwable unexpected) {194out.println("Test pre-initialisation failed: " + unexpected);195return 2;196}197198if (TRACE_ON)199out.println("Running with heap exhaustion");200201return runTests(out, true);202}203204private static int runTests(PrintStream out, boolean exhaustHeap) {205// reset message index206messages = 0;207208// Prepare some items, which will be used by the test:209Object stringArray[] = new String[1];210Object integerValue = Integer.valueOf(0);211Object doubleValue = Double.valueOf(0);212Object trash = null;213Field abraIntegerField;214Field abraBooleanField;215Field extPrivateField;216try {217abraIntegerField = Abra.class.getDeclaredField("MAIN_CYR_NUMBER");218abraBooleanField = Abra.class.getDeclaredField("NOT_AN_INTEGER");219extPrivateField = Ext.class.getDeclaredField("DONT_TOUCH_ME");220} catch (NoSuchFieldException nsfe) {221out.println("Test initialisation failed: field not found: " + nsfe.getMessage());222return 2;223}224225Abra abra = new Abra("via public constructor");226Abra.Cadabra cadabra = new Abra.Cadabra();227// Sum up exit code:228int exitCode = 0; // apparently PASSED229int skipped = 0; // some checks may correctly suffer OutOfMemoryError230231int poolSize = 0;232int index = 0;233234if (exhaustHeap) {235pool = null;236// Allocate repository for lots of tiny objects:237for (int size = 1 << 30; size > 0 && pool == null; size >>= 1) {238try {239pool = new Object[size];240} catch (OutOfMemoryError oome) {241}242}243if (pool == null)244throw new Error("HS bug: cannot allocate new Object[1]");245poolSize = pool.length;246index = 0;247248// Sum up time spent, when it was hard for JVM to allocate next object249// (i.e.: when JVM has spent more than 1 second to allocate new object):250double totalDelay = 0;251long timeMark = System.currentTimeMillis();252try {253for (; index < poolSize; index++) {254//-------------------------255pool[index] = new Object();256long nextTimeMark = System.currentTimeMillis();257long elapsed = nextTimeMark - timeMark;258timeMark = nextTimeMark;259//----------------------260if (elapsed > 1000) {261double seconds = elapsed / 1000.0;262if (TRACE_ON)263out.println(264"pool[" + index + "]=new Object(); // elapsed " + seconds + "s");265totalDelay += seconds;266if (totalDelay > 60) {267if (TRACE_ON)268out.println(269"Memory allocation became slow; so, heap seems exhausted.");270break;271}272}273}274} catch (OutOfMemoryError oome) {275if (TRACE_ON)276log[messages++] = "Heap seems exhausted - OutOfMemoryError thrown.";277// Do not release any byte once allocated:278pool[index++] = oome;279}280281if (index > poolSize - 1000) {282if (WARN_ON)283log[messages++] = "Warning: pool[] is full; so, checks would not be enough hard...";284}285} else {286// pool gets used for array index tests287pool = new Object[3];288poolSize = pool.length;289}290291// Check ArithmeticException:292try {293int x, y, z;294x = y = 0;295z = x / y;296log[messages++] = "Failure: ArithmeticException";297exitCode = 2; // FAILED298} catch (ArithmeticException ae) {299if (TRACE_ON)300log[messages++] = "Success: ArithmeticException";301if (exhaustHeap)302pool[index++] = ae;303} catch (OutOfMemoryError oome) {304if (WARN_ON)305log[messages++] = "Skipped: ArithmeticException";306skipped++;307}308309// Check ArrayIndexOutOfBoundsException:310try {311pool[poolSize] = pool[0];312log[messages++] = "Failure: ArrayIndexOutOfBoundsException";313exitCode = 2; // FAILED314} catch (ArrayIndexOutOfBoundsException aioobe) {315if (TRACE_ON)316log[messages++] = "Success: ArrayIndexOutOfBoundsException";317} catch (OutOfMemoryError oome) {318if (WARN_ON)319log[messages++] = "Skipped: ArrayIndexOutOfBoundsException";320skipped++;321}322323// Check ArrayStoreException:324try {325stringArray[0] = integerValue;326log[messages++] = "Failure: ArrayStoreException";327exitCode = 2; // FAILED328} catch (ArrayStoreException ase) {329if (TRACE_ON)330log[messages++] = "Success: ArrayStoreException";331} catch (OutOfMemoryError oome) {332if (WARN_ON)333log[messages++] = "Skipped: ArrayStoreException";334skipped++;335}336337// Check ClassCastException:338try {339trash = (Double) integerValue;340log[messages++] = "Failure: ClassCastException";341exitCode = 2; // FAILED342} catch (ClassCastException cce) {343if (TRACE_ON)344log[messages++] = "Success: ClassCastException";345if (exhaustHeap)346pool[index++] = cce;347} catch (OutOfMemoryError oome) {348if (WARN_ON)349log[messages++] = "Skipped: ClassCastException";350skipped++;351}352353// Check CloneNotSupportedException:354try {355trash = abra.clone(); // illegal - should fail356// trash = cadabra.clone(); // legal - should pass357log[messages++] = "Failure: CloneNotSupportedException";358exitCode = 2; // FAILED359} catch (CloneNotSupportedException cnse) {360if (TRACE_ON)361log[messages++] = "Success: CloneNotSupportedException";362} catch (OutOfMemoryError oome) {363if (WARN_ON)364log[messages++] = "Skipped: CloneNotSupportedException";365skipped++;366}367368// Check IllegalAccessException (positive):369try {370int junkIt = abraIntegerField.getInt(null); // legal - should pass371if (TRACE_ON)372log[messages++] = "Success: IllegalAccessException (positive)";373} catch (IllegalAccessException iae) {374log[messages++] = "Failure: IllegalAccessException (positive)";375exitCode = 2;376} catch (OutOfMemoryError oome) {377if (WARN_ON)378log[messages++] = "Skipped: IllegalAccessException (positive)";379skipped++;380}381382// Check IllegalAccessException (negative):383try {384int junkIt = extPrivateField.getInt(null); // illegal - should fail385log[messages++] = "Failure: IllegalAccessException (negative)";386exitCode = 2; // FAILED387} catch (IllegalAccessException iae) {388if (TRACE_ON)389log[messages++] = "Success: IllegalAccessException (negative)";390} catch (OutOfMemoryError oome) {391if (WARN_ON)392log[messages++] = "Skipped: IllegalAccessException (negative)";393skipped++;394}395396// Check IllegalArgumentException (positive):397try {398int junkIt = abraIntegerField.getInt(null); // legal - should pass399// int junkIt = abraBooleanField.getInt(null); // illegal - should fail400if (TRACE_ON)401log[messages++] = "Success: IllegalArgumentException (positive)";402} catch (IllegalAccessException iae) {403log[messages++] =404"Failure: IllegalArgumentException (positive) incorrectly thrown IllegalAccessException";405exitCode = 2;406} catch (IllegalArgumentException iae) {407log[messages++] = "Failure: IllegalArgumentException (positive)";408exitCode = 2;409} catch (OutOfMemoryError oome) {410if (WARN_ON)411log[messages++] = "Skipped: IllegalArgumentException (positive)";412skipped++;413}414415// Check IllegalArgumentException (negative):416try {417// int junkIt = abraIntegerField.getInt(null); // legal - should pass418int junkIt = abraBooleanField.getInt(null); // illegal - should fail419log[messages++] = "Failure: IllegalArgumentException (negative)";420exitCode = 2; // FAILED421} catch (IllegalAccessException iae) {422log[messages++] =423"Failure: IllegalArgumentException (negative) incorrectly thrown IllegalAccessException";424exitCode = 2;425} catch (IllegalArgumentException iae) {426if (TRACE_ON)427log[messages++] = "Success: IllegalArgumentException (negative)";428} catch (OutOfMemoryError oome) {429if (WARN_ON)430log[messages++] = "Skipped: IllegalArgumentException (negative)";431skipped++;432}433434// Check IllegalMonitorStateException (positive):435try {436synchronized (cadabra) {437cadabra.notifyAll(); // legal - should pass438}439// cadabra.notifyAll(); // illegal - should fail440if (TRACE_ON)441log[messages++] = "Success: IllegalMonitorStateException (positive)";442} catch (IllegalMonitorStateException imse) {443log[messages++] = "Failure: IllegalMonitorStateException (positive)";444exitCode = 2;445} catch (OutOfMemoryError oome) {446if (WARN_ON)447log[messages++] = "Skipped: IllegalMonitorStateException (positive)";448skipped++;449}450451// Check IllegalMonitorStateException (negative):452try {453// synchronized (cadabra) {454// cadabra.notifyAll(); // legal - should pass455// }456cadabra.notifyAll(); // illegal - should fail457log[messages++] = "Failure: IllegalMonitorStateException (negative)";458exitCode = 2;459} catch (IllegalMonitorStateException imse) {460if (TRACE_ON)461log[messages++] = "Success: IllegalMonitorStateException (negative)";462} catch (OutOfMemoryError oome) {463if (WARN_ON)464log[messages++] = "Skipped: IllegalMonitorStateException (negative)";465skipped++;466}467468return exitCode;469}470471/**472* Re-call to <code>run(args,out)</code>, and return JCK-like exit status.473* (The stream <code>out</code> is assigned to <code>System.out</code> here.)474*475* @see #run(String[], PrintStream)476*/477public static void main(String args[]) {478Thread.currentThread().setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {479// Last try. If there is some exception outside the code, test should end correctly480@Override481public void uncaughtException(Thread t, Throwable e) {482try {483pool = null;484log = null;485System.gc();486if (e instanceof OutOfMemoryError) {487try {488System.out.println("OOME : Test Skipped");489System.exit(0);490} catch (Throwable ignore) {491} // No code in the handler can provoke correct exceptions.492} else {493e.printStackTrace();494if (e instanceof RuntimeException)495throw (RuntimeException) e;496else if (e instanceof Error)497throw (Error) e;498else499throw new Error("Unexpected checked exception", e);500}501} catch (OutOfMemoryError oome) {502}503}504});505int exitCode = run(args, System.out);506System.exit(exitCode + 95);507// JCK-like exit status.508}509510/**511* This class should be used to check <code>CloneNotSupportedException</code>,512* and <code>IllegalArgumentException</code>.513* The class extends <code>except004</code> in order that its (protected)514* method <code>clone()</code> be available from <code>except004</code>.515*/516private static class Abra extends except004 {517/**518* Will try to incorrectly find this class as <code>Cadabra</code>519* instead of <code>Abra$Cadabra</code>.520*/521public static class Cadabra implements Cloneable {522}523524/**525* Will try to incorrectly access to this field from outside this class.526*/527public static final int MAIN_CYR_NUMBER = 47;528/**529* Will try to get this field like <code>int<code> zero.530*/531public static final boolean NOT_AN_INTEGER = false;532533/**534* Will try to correctly instantiate <code>Abra.Cadabra</code>,535* not <code>Abra</code>.536*/537private Abra() {538}539540/**541* Yet another constructor, which is <code>public</code>.542*/543public Abra(String nothingSpecial) {544}545}546}547548/* Package accessible class that has non-accessible private member */549class Ext {550/**551* Will try to incorrectly access to this field from outside this class.552*/553private static final int DONT_TOUCH_ME = 666;554}555556557