hotspot/test/runtime/Thread/TooSmallStackSize.java
changeset 41070 496463b4e206
child 46346 4085295dcf51
equal deleted inserted replaced
40931:d4d2a4a0e023 41070:496463b4e206
       
     1 /*
       
     2  * Copyright (c) 2016, 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 8140520
       
    27  * @summary Setting small CompilerThreadStackSize, ThreadStackSize, and
       
    28  * VMThreadStackSize values should result in an error message that shows
       
    29  * the minimum stack size value for each thread type.
       
    30  * @library /test/lib
       
    31  * @modules java.base/jdk.internal.misc
       
    32  *          java.management
       
    33  * @run main TooSmallStackSize
       
    34  */
       
    35 
       
    36 /*
       
    37  * The primary purpose of this test is to make sure we can run with a
       
    38  * stack smaller than the minimum without crashing. Also this test will
       
    39  * determine the minimum allowed stack size for the platform (as
       
    40  * provided by the JVM error message when a very small stack is used),
       
    41  * and then verify that the JVM can be launched with that stack size
       
    42  * without a crash or any error messages.
       
    43  *
       
    44  * Note: The '-Xss<size>' and '-XX:ThreadStackSize=<k-bytes>' options
       
    45  * both control Java thread stack size. This repo's version of the test
       
    46  * exercises the '-XX:ThreadStackSize' VM option. The jdk repo's version
       
    47  * of the test exercises the '-Xss' option.
       
    48  */
       
    49 
       
    50 import jdk.test.lib.process.ProcessTools;
       
    51 import jdk.test.lib.process.OutputAnalyzer;
       
    52 
       
    53 public class TooSmallStackSize {
       
    54     /* for debugging. Normally false. */
       
    55     static final boolean verbose = false;
       
    56     static final String CompilerThreadStackSizeString = "CompilerThreadStackSize";
       
    57     static final String ThreadStackSizeString = "Java thread stack size";
       
    58     static final String VMThreadStackSizeString = "VMThreadStackSize";
       
    59 
       
    60     /*
       
    61      * Returns the minimum stack size this platform will allowed based on the
       
    62      * contents of the error message the JVM outputs when too small of a
       
    63      * stack size was used.
       
    64      *
       
    65      * The testOutput argument must contain the result of having already run
       
    66      * the JVM with too small of a stack size.
       
    67      */
       
    68     static String getMinStackAllowed(String testOutput) {
       
    69         /*
       
    70          * The JVM output will contain in one of the lines:
       
    71          *   "The CompilerThreadStackSize specified is too small. Specify at least 100k"
       
    72          *   "The Java thread stack size specified is too small. Specify at least 100k"
       
    73          *   "The VMThreadStackSize specified is too small. Specify at least 100k"
       
    74          * Although the actual size will vary. We need to extract this size
       
    75          * string from the output and return it.
       
    76          */
       
    77         String matchStr = "Specify at least ";
       
    78         int match_idx = testOutput.indexOf(matchStr);
       
    79         if (match_idx >= 0) {
       
    80             int size_start_idx = match_idx + matchStr.length();
       
    81             int k_start_idx = testOutput.indexOf("k", size_start_idx);
       
    82             // don't include the 'k'; the caller will have to
       
    83             // add it back as needed.
       
    84             return testOutput.substring(size_start_idx, k_start_idx);
       
    85         }
       
    86 
       
    87         System.out.println("Expect='" + matchStr + "'");
       
    88         System.out.println("Actual: " + testOutput);
       
    89         System.out.println("FAILED: Could not get the stack size from the output");
       
    90         throw new RuntimeException("test fails");
       
    91     }
       
    92 
       
    93     /*
       
    94      * Run the JVM with the specified stack size.
       
    95      *
       
    96      * Returns the minimum allowed stack size gleaned from the error message,
       
    97      * if there is an error message. Otherwise returns the stack size passed in.
       
    98      */
       
    99     static String checkStack(String stackOption, String optionMesg, String stackSize) throws Exception {
       
   100         String min_stack_allowed;
       
   101 
       
   102         System.out.println("*** Testing " + stackOption + stackSize);
       
   103 
       
   104         ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
       
   105             stackOption + stackSize,
       
   106             // Uncomment the following to get log output
       
   107             // that shows actual thread creation sizes.
       
   108             // "-Xlog:os+thread",
       
   109             "-version");
       
   110 
       
   111         OutputAnalyzer output = new OutputAnalyzer(pb.start());
       
   112 
       
   113         if (verbose) {
       
   114             System.out.println("stdout: " + output.getStdout());
       
   115         }
       
   116 
       
   117         if (output.getExitValue() == 0) {
       
   118             // checkMinStackAllowed() is called with stackSize values
       
   119             // that should be the minimum that works. This method,
       
   120             // checkStack(), is called with stackSize values that
       
   121             // should be too small and result in error messages.
       
   122             // However, some platforms fix up a stackSize value that is
       
   123             // too small into something that works so we have to allow
       
   124             // for checkStack() calls that work.
       
   125             System.out.println("PASSED: got exit_code == 0 with " + stackOption + stackSize);
       
   126             min_stack_allowed = stackSize;
       
   127         } else {
       
   128             String expect = "The " + optionMesg + " specified is too small";
       
   129             if (verbose) {
       
   130                 System.out.println("Expect='" + expect + "'");
       
   131             }
       
   132             output.shouldContain(expect);
       
   133             min_stack_allowed = getMinStackAllowed(output.getStdout());
       
   134 
       
   135             System.out.println("PASSED: got expected error message with " + stackOption + stackSize);
       
   136         }
       
   137 
       
   138         return min_stack_allowed;
       
   139     }
       
   140 
       
   141     /*
       
   142      * Run the JVM with the minimum allowed stack size. This should always succeed.
       
   143      */
       
   144     static void checkMinStackAllowed(String stackOption, String optionMesg, String stackSize) throws Exception {
       
   145         System.out.println("*** Testing " + stackOption + stackSize);
       
   146 
       
   147         ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
       
   148             stackOption + stackSize,
       
   149             // Uncomment the following to get log output
       
   150             // that shows actual thread creation sizes.
       
   151             // "-Xlog:os+thread",
       
   152             "-version");
       
   153 
       
   154         OutputAnalyzer output = new OutputAnalyzer(pb.start());
       
   155         output.shouldHaveExitValue(0);
       
   156 
       
   157         System.out.println("PASSED: VM launched with " + stackOption + stackSize);
       
   158     }
       
   159 
       
   160     public static void main(String... args) throws Exception {
       
   161         /*
       
   162          * The result of a 16k stack size should be a quick exit with a complaint
       
   163          * that the stack size is too small. However, for some win32 builds, the
       
   164          * stack is always at least 64k, and this also sometimes is the minimum
       
   165          * allowed size, so we won't see an error in this case.
       
   166          *
       
   167          * This test case will also produce a crash on some platforms if the fix
       
   168          * for 6762191 is not yet in place.
       
   169          */
       
   170         checkStack("-XX:ThreadStackSize=", ThreadStackSizeString, "16");
       
   171 
       
   172         /*
       
   173          * Try with a 32k stack size, which is the size that the launcher will
       
   174          * set to if you try setting to anything smaller. This should produce the same
       
   175          * result as setting to 16k if the fix for 6762191 is in place.
       
   176          */
       
   177         String min_stack_allowed = checkStack("-XX:ThreadStackSize=", ThreadStackSizeString, "32");
       
   178 
       
   179         /*
       
   180          * Try again with a the minimum stack size that was given in the error message
       
   181          */
       
   182         checkMinStackAllowed("-XX:ThreadStackSize=", ThreadStackSizeString, min_stack_allowed);
       
   183 
       
   184         /*
       
   185          * Now redo the same tests with the compiler thread stack size:
       
   186          */
       
   187         checkStack("-XX:CompilerThreadStackSize=", CompilerThreadStackSizeString, "16");
       
   188         min_stack_allowed = checkStack("-XX:CompilerThreadStackSize=", CompilerThreadStackSizeString, "32");
       
   189         checkMinStackAllowed("-XX:CompilerThreadStackSize=", CompilerThreadStackSizeString, min_stack_allowed);
       
   190 
       
   191         /*
       
   192          * Now redo the same tests with the VM thread stack size:
       
   193          */
       
   194         checkStack("-XX:VMThreadStackSize=", VMThreadStackSizeString, "16");
       
   195         min_stack_allowed = checkStack("-XX:VMThreadStackSize=", VMThreadStackSizeString, "32");
       
   196         checkMinStackAllowed("-XX:VMThreadStackSize=", VMThreadStackSizeString, min_stack_allowed);
       
   197     }
       
   198 }