Path: blob/master/test/hotspot/jtreg/vmTestbase/nsk/stress/stack/stack018.java
41159 views
/*1* Copyright (c) 2000, 2020, 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*/2223/*24* @test25* @key stress26*27* @summary converted from VM testbase nsk/stress/stack/stack018.28* VM testbase keywords: [stress, diehard, stack, nonconcurrent]29* VM testbase readme:30* DESCRIPTION31* This test provokes multiple stack overflows by invocations via32* reflection -- repeatedly multiple times, and in multiple threads.33* Recursive method is invoked for the given fixed depth of recursion34* (though, for a large depth). The test measures a number of recursive35* invocations until stack overflow, and then tries to reproduce similar36* stack overflows 10 times in each of 10 threads -- each time by trying37* to invoke the same recursive method for the given fixed depth38* of invocations (which is 10 times that crucial depth just measured).39* The test is deemed passed, if VM have not crashed, and40* if exception other than due to stack overflow was not41* thrown.42* COMMENTS43* This test crashes HS versions 2.0, 1.3, and 1.4 on both44* Solaris and Win32 platforms.45* See the bug:46* 4366625 (P4/S4) multiple stack overflow causes HS crash47*48* @requires (vm.opt.DeoptimizeALot != true & vm.compMode != "Xcomp" & vm.pageSize == 4096)49* @library /vmTestbase50* @build nsk.share.Terminator51* @run main/othervm/timeout=900 -Xss220K nsk.stress.stack.stack018 -eager52*/5354package nsk.stress.stack;555657import nsk.share.Terminator;5859import java.io.PrintStream;60import java.lang.reflect.InvocationTargetException;61import java.lang.reflect.Method;6263public class stack018 extends Thread {64private final static int THREADS = 10;65private final static int CYCLES = 10;66private final static int STEP = 100;67private final static int RESERVE = 100;6869public static void main(String[] args) {70int exitCode = run(args, System.out);71System.exit(exitCode + 95);72}7374public static int run(String args[], PrintStream out) {75verbose = false;76boolean eager = false;77for (int i = 0; i < args.length; i++)78if (args[i].toLowerCase().equals("-verbose"))79verbose = true;80else if (args[i].toLowerCase().equals("-eager"))81eager = true;82if (!eager)83Terminator.appoint(Terminator.parseAppointment(args));84stack018.out = out;85stack018 test = new stack018();86return test.doRun();87}8889private static boolean verbose;90private static PrintStream out;9192private void display(Object message) {93if (!verbose)94return;95synchronized (out) {96out.println(message.toString());97}98}99100private int doRun() {101//102// Measure maximal recursion depth until stack overflow:103//104int maxDepth = 0;105for (depthToTry = 0; ; depthToTry += STEP)106try {107invokeRecurse(depthToTry);108maxDepth = depthToTry;109} catch (Throwable exception) {110Throwable target = getTargetException(exception);111if ((target instanceof StackOverflowError) ||112(target instanceof OutOfMemoryError))113break; // OK.114target.printStackTrace(out);115if (target instanceof ThreadDeath)116throw (ThreadDeath) target;117return 2;118}119out.println("Maximal recursion depth: " + maxDepth);120121//122// Run the tested threads:123//124stack018 threads[] = new stack018[THREADS];125for (int i = 0; i < threads.length; i++) {126threads[i] = new stack018();127threads[i].setName("Thread: " + (i + 1) + "/" + THREADS);128threads[i].depthToTry = RESERVE * maxDepth;129threads[i].start();130}131for (int i = 0; i < threads.length; i++)132if (threads[i].isAlive())133try {134threads[i].join();135} catch (InterruptedException exception) {136exception.printStackTrace(out);137return 2;138}139140//141// Check if unexpected exceptions were thrown:142//143int exitCode = 0;144for (int i = 0; i < threads.length; i++)145if (threads[i].thrown != null) {146out.println("# " + threads[i].getName()147+ ": " + threads[i].thrown);148exitCode = 2;149}150151if (exitCode != 0)152out.println("# TEST FAILED");153return exitCode;154}155156private int depthToTry = 0;157private Throwable thrown = null;158159public void run() {160String threadName = Thread.currentThread().getName();161for (int i = 1; i <= CYCLES; i++)162try {163display(threadName + ", iteration: " + i + "/" + CYCLES);164invokeRecurse(depthToTry);165throw new Error("TEST_RFE: try deeper invocations!");166167} catch (Throwable exception) {168Throwable target = getTargetException(exception);169if ((target instanceof StackOverflowError) ||170(target instanceof OutOfMemoryError))171continue; // OK.172if (target instanceof ThreadDeath)173throw (ThreadDeath) target;174thrown = target;175break;176}177}178179private static Throwable getTargetException(Throwable exception) {180Throwable target;181//182// Unwrap deep chain of exceptions to find StackOverflowError:183//184for (185target = exception;186target instanceof InvocationTargetException;187target = ((InvocationTargetException) target).getTargetException()188)189;190return target;191}192193private Method method = null;194private Object params[] = null;195196private void invokeRecurse(int depth) throws Exception {197if (method == null) {198//199// Optimization trick: allocate once, use everywhere.200//201method = stack018.class.getMethod("recurse");202params = new Object[]{};203}204this.depth = depth; // actual parameter205method.invoke(this, params);206}207208private int depth = 0; // actual parameter for recurse()209210public void recurse() throws Exception {211if (depth > 0)212//213// Self-invoke via reflection:214//215invokeRecurse(depth - 1);216}217}218219220