1 /* 2 * Copyright (c) 2014, 2017, 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 6762191 27 * @summary Setting stack size to 16K causes segmentation fault 28 * @compile TooSmallStackSize.java 29 * @run main TooSmallStackSize 30 */ 31 32 /* 33 * The primary purpose of this test is to make sure we can run with a 16k stack 34 * size without crashing. Also this test will determine the minimum allowed 35 * stack size for the platform (as provided by the JVM error message when a very 36 * small stack is used), and then verify that the JVM can be launched with that stack 37 * size without a crash or any error messages. 38 * 39 * Note: The '-Xss<size>' and '-XX:ThreadStackSize=<k-bytes>' options 40 * both control Java thread stack size. This repo's version of the test 41 * exercises the '-Xss' option. The hotspot repo's version of the test 42 * exercises the '-XX:ThreadStackSize' VM option. 43 */ 44 45 public class TooSmallStackSize extends TestHelper { 46 /* for debugging. Normally false. */ 47 static final boolean verbose = false; 48 49 static void printTestOutput(TestResult tr) { 50 System.out.println("*** exitValue = " + tr.exitValue); 51 for (String x : tr.testOutput) { 52 System.out.println(x); 53 } 54 } 55 56 /* 57 * Returns the minimum stack size this platform will allowed based on the 58 * contents of the error message the JVM outputs when too small of a 59 * -Xss size was used. 60 * 61 * The TestResult argument must contain the result of having already run 62 * the JVM with too small of a stack size. 63 */ 64 static String getMinStackAllowed(TestResult tr) { 65 /* 66 * The JVM output will contain in one of the lines: 67 * "The Java thread stack size specified is too small. Specify at least 100k" 68 * Although the actual size will vary. We need to extract this size 69 * string from the output and return it. 70 */ 71 String matchStr = "Specify at least "; 72 for (String x : tr.testOutput) { 73 int match_idx = x.indexOf(matchStr); 74 if (match_idx >= 0) { 75 int size_start_idx = match_idx + matchStr.length(); 76 int k_start_idx = x.indexOf("k", size_start_idx); 77 return x.substring(size_start_idx, k_start_idx + 1); // include the "k" 78 } 79 } 80 81 System.out.println("Expect='" + matchStr + "'"); 82 System.out.println("Actual:"); 83 printTestOutput(tr); 84 System.out.println("FAILED: Could not get the stack size from the output"); 85 throw new RuntimeException("test fails"); 86 } 87 88 /* 89 * Run the JVM with the specified stack size. 90 * 91 * Returns the minimum allowed stack size gleaned from the error message, 92 * if there is an error message. Otherwise returns the stack size passed in. 93 */ 94 static String checkStack(String stackSize) { 95 String min_stack_allowed; 96 97 if (verbose) 98 System.out.println("*** Testing " + stackSize); 99 TestResult tr = doExec(javaCmd, "-Xss" + stackSize, "-version"); 100 if (verbose) 101 printTestOutput(tr); 102 103 if (tr.isOK()) { 104 System.out.println("PASSED: got no error message with stack size of " + stackSize); 105 min_stack_allowed = stackSize; 106 } else { 107 String matchStr = "The Java thread stack size specified is too small"; 108 if (tr.contains(matchStr)) { 109 System.out.println("PASSED: got expected error message with stack size of " + stackSize); 110 min_stack_allowed = getMinStackAllowed(tr); 111 } else { 112 // Likely a crash 113 System.out.println("Expect='" + matchStr + "'"); 114 System.out.println("Actual:"); 115 printTestOutput(tr); 116 System.out.println("FAILED: Did not get expected error message with stack size of " + stackSize); 117 throw new RuntimeException("test fails"); 118 } 119 } 120 121 return min_stack_allowed; 122 } 123 124 /* 125 * Run the JVM with the minimum allowed stack size. This should always succeed. 126 */ 127 static void checkMinStackAllowed(String stackSize) { 128 if (verbose) 129 System.out.println("*** Testing " + stackSize); 130 TestResult tr = doExec(javaCmd, "-Xss" + stackSize, "-version"); 131 if (verbose) 132 printTestOutput(tr); 133 134 if (tr.isOK()) { 135 System.out.println("PASSED: VM launched with minimum allowed stack size of " + stackSize); 136 } else { 137 // Likely a crash 138 System.out.println("Test output:"); 139 printTestOutput(tr); 140 System.out.println("FAILED: VM failed to launch with minimum allowed stack size of " + stackSize); 141 throw new RuntimeException("test fails"); 142 } 143 } 144 145 public static void main(String... args) { 146 /* 147 * The result of a 16k stack size should be a quick exit with a complaint 148 * that the stack size is too small. However, for some win32 builds, the 149 * stack is always at least 64k, and this also sometimes is the minimum 150 * allowed size, so we won't see an error in this case. 151 * 152 * This test case will also produce a crash on some platforms if the fix 153 * for 6762191 is not yet in place. 154 */ 155 checkStack("16k"); 156 157 /* 158 * Try with a 64k stack size, which is the size that the launcher will 159 * set to if you try setting to anything smaller. This should produce the same 160 * result as setting to 16k if the fix for 6762191 is in place. 161 */ 162 String min_stack_allowed = checkStack("64k"); 163 164 /* 165 * Try again with a the minimum stack size that was given in the error message 166 */ 167 checkMinStackAllowed(min_stack_allowed); 168 169 /* 170 * Try again with a size that is not OS page aligned. This is to help test that 171 * asserts added for 8176768 are not triggered. 172 */ 173 checkMinStackAllowed("513k"); 174 175 /* 176 * Try with 0k which indicates that the default thread stack size either from JVM or system 177 * will be used, this should always succeed. It can verify the issue fixed in 8222334. 178 */ 179 checkMinStackAllowed("0k"); 180 } 181 }