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