8222334: java -Xss0 triggers StackOverflowError

Launcher to use the stack size decided by hotpot or system if -Xss is 0

Reviewed-by: dholmes, alanb
This commit is contained in:
Patrick Zhang 2019-04-16 11:00:48 +00:00
parent ced9f6cb77
commit b9a4ede307
3 changed files with 56 additions and 38 deletions

View File

@ -204,11 +204,14 @@ static jboolean IsWildCardEnabled();
*/
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 @@ AddOption(char *str, void *info)
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 @@ ContinueInNewThread(InvocationFunctions* ifn, jlong threadStackSize,
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;
}
}

View File

@ -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
@ -186,6 +186,11 @@ public class TooSmallStackSize {
*/
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:
*/
@ -193,6 +198,7 @@ public class TooSmallStackSize {
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 @@ public class TooSmallStackSize {
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");
}
}

View File

@ -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 @@ public class TooSmallStackSize extends TestHelper {
* 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");
}
}