# HG changeset patch # User qpzhang # Date 1555412448 0 # Node ID 4fc566b7a9c072bba921acb44dabc1550c42f820 # Parent 0a4214c90a558f20bafa7903f2a262ad601c4399 8222334: java -Xss0 triggers StackOverflowError Summary: Launcher to use the stack size decided by hotpot or system if -Xss is 0 Reviewed-by: dholmes, alanb diff -r 0a4214c90a55 -r 4fc566b7a9c0 src/java.base/share/native/libjli/java.c --- a/src/java.base/share/native/libjli/java.c Tue Apr 16 08:51:01 2019 +0200 +++ b/src/java.base/share/native/libjli/java.c Tue Apr 16 11:00:48 2019 +0000 @@ -204,11 +204,14 @@ */ static jlong threadStackSize = 0; /* stack size of the new thread */ static jlong maxHeapSize = 0; /* max heap size */ -static jlong initialHeapSize = 0; /* inital heap size */ +static jlong initialHeapSize = 0; /* initial heap size */ /* - * A minimum -Xss stack size suitable for all platforms. - */ + * A minimum initial-thread stack size suitable for most platforms. + * This is the minimum amount of stack needed to load the JVM such + * that it can reject a too small -Xss value. If this is too small + * JVM initialization would cause a StackOverflowError. + */ #ifndef STACK_SIZE_MINIMUM #define STACK_SIZE_MINIMUM (64 * KB) #endif @@ -934,16 +937,18 @@ options[numOptions].optionString = str; options[numOptions++].extraInfo = info; + /* + * -Xss is used both by the JVM and here to establish the stack size of the thread + * created to launch the JVM. In the latter case we need to ensure we don't go + * below the minimum stack size allowed. If -Xss is zero that tells the JVM to use + * 'default' sizes (either from JVM or system configuration, e.g. 'ulimit -s' on linux), + * and is not itself a small stack size that will be rejected. So we ignore -Xss0 here. + */ if (JLI_StrCCmp(str, "-Xss") == 0) { jlong tmp; if (parse_size(str + 4, &tmp)) { threadStackSize = tmp; - /* - * Make sure the thread stack size is big enough that we won't get a stack - * overflow before the JVM startup code can check to make sure the stack - * is big enough. - */ - if (threadStackSize < (jlong)STACK_SIZE_MINIMUM) { + if (threadStackSize > 0 && threadStackSize < (jlong)STACK_SIZE_MINIMUM) { threadStackSize = STACK_SIZE_MINIMUM; } } @@ -2322,38 +2327,38 @@ int argc, char **argv, int mode, char *what, int ret) { - - /* - * If user doesn't specify stack size, check if VM has a preference. - * Note that HotSpot no longer supports JNI_VERSION_1_1 but it will - * return its default stack size through the init args structure. - */ if (threadStackSize == 0) { - struct JDK1_1InitArgs args1_1; - memset((void*)&args1_1, 0, sizeof(args1_1)); - args1_1.version = JNI_VERSION_1_1; - ifn->GetDefaultJavaVMInitArgs(&args1_1); /* ignore return value */ - if (args1_1.javaStackSize > 0) { - threadStackSize = args1_1.javaStackSize; - } + /* + * If the user hasn't specified a non-zero stack size ask the JVM for its default. + * A returned 0 means 'use the system default' for a platform, e.g., Windows. + * Note that HotSpot no longer supports JNI_VERSION_1_1 but it will + * return its default stack size through the init args structure. + */ + struct JDK1_1InitArgs args1_1; + memset((void*)&args1_1, 0, sizeof(args1_1)); + args1_1.version = JNI_VERSION_1_1; + ifn->GetDefaultJavaVMInitArgs(&args1_1); /* ignore return value */ + if (args1_1.javaStackSize > 0) { + threadStackSize = args1_1.javaStackSize; + } } { /* Create a new thread to create JVM and invoke main method */ - JavaMainArgs args; - int rslt; + JavaMainArgs args; + int rslt; - args.argc = argc; - args.argv = argv; - args.mode = mode; - args.what = what; - args.ifn = *ifn; + args.argc = argc; + args.argv = argv; + args.mode = mode; + args.what = what; + args.ifn = *ifn; - rslt = CallJavaMainInNewThread(threadStackSize, (void*)&args); - /* If the caller has deemed there is an error we - * simply return that, otherwise we return the value of - * the callee - */ - return (ret != 0) ? ret : rslt; + rslt = CallJavaMainInNewThread(threadStackSize, (void*)&args); + /* If the caller has deemed there is an error we + * simply return that, otherwise we return the value of + * the callee + */ + return (ret != 0) ? ret : rslt; } } diff -r 0a4214c90a55 -r 4fc566b7a9c0 test/hotspot/jtreg/runtime/Thread/TooSmallStackSize.java --- a/test/hotspot/jtreg/runtime/Thread/TooSmallStackSize.java Tue Apr 16 08:51:01 2019 +0200 +++ b/test/hotspot/jtreg/runtime/Thread/TooSmallStackSize.java Tue Apr 16 11:00:48 2019 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -187,12 +187,18 @@ checkMinStackAllowed("-XX:ThreadStackSize=", ThreadStackSizeString, "513"); /* + * Try with 0k which indicates that the default thread stack size from JVM will be used. + */ + checkMinStackAllowed("-XX:ThreadStackSize=", ThreadStackSizeString, "0"); + + /* * Now redo the same tests with the compiler thread stack size: */ checkStack("-XX:CompilerThreadStackSize=", CompilerThreadStackSizeString, "16"); min_stack_allowed = checkStack("-XX:CompilerThreadStackSize=", CompilerThreadStackSizeString, "64"); checkMinStackAllowed("-XX:CompilerThreadStackSize=", CompilerThreadStackSizeString, min_stack_allowed); checkMinStackAllowed("-XX:CompilerThreadStackSize=", CompilerThreadStackSizeString, "513"); + checkMinStackAllowed("-XX:CompilerThreadStackSize=", CompilerThreadStackSizeString, "0"); /* * Now redo the same tests with the VM thread stack size: @@ -201,5 +207,6 @@ min_stack_allowed = checkStack("-XX:VMThreadStackSize=", VMThreadStackSizeString, "64"); checkMinStackAllowed("-XX:VMThreadStackSize=", VMThreadStackSizeString, min_stack_allowed); checkMinStackAllowed("-XX:VMThreadStackSize=", VMThreadStackSizeString, "513"); + checkMinStackAllowed("-XX:VMThreadStackSize=", VMThreadStackSizeString, "0"); } } diff -r 0a4214c90a55 -r 4fc566b7a9c0 test/jdk/tools/launcher/TooSmallStackSize.java --- a/test/jdk/tools/launcher/TooSmallStackSize.java Tue Apr 16 08:51:01 2019 +0200 +++ b/test/jdk/tools/launcher/TooSmallStackSize.java Tue Apr 16 11:00:48 2019 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,7 @@ /* * @test - * @bug 6762191 + * @bug 6762191 8222334 * @summary Setting stack size to 16K causes segmentation fault * @compile TooSmallStackSize.java * @run main TooSmallStackSize @@ -171,5 +171,11 @@ * asserts added for 8176768 are not triggered. */ checkMinStackAllowed("513k"); + + /* + * Try with 0k which indicates that the default thread stack size either from JVM or system + * will be used, this should always succeed. + */ + checkMinStackAllowed("0k"); } }