Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8222334

java -Xss0 triggers StackOverflowError

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Fixed
    • Icon: P3 P3
    • 13
    • 11, 12, 13
    • tools
    • 10
    • b17
    • generic
    • generic

      The fix for JDK-6762191 and JDK-8177015 forced the stack size to be 32K, 64K for pthread_create in CallJavaMainInNewThread, if users specified a small value with -Xss. That fixed majority of cases except one: -Xss0, since hotspot would handle "0" as a special input when telling if it is an acceptable stack size (not too small), -Xss0 will pass the checking logic of Arguments::parse_xss safely, arrive at os::Posix::set_minimum_stack_sizandes() in os_posix.cpp or the similar function in os_windows.cpp, then "stack_size_in_bytes != 0 " would indicate that users might need a default size, instead of a JNI_ERR. Finally, the os::stack_shadow_pages_available will fail and
      throw StackOverflowError.

      > java -Xss0
      Error occurred during initialization of VM
      java.lang.StackOverflowError
      at java.lang.Object.<clinit>(java.base/Object.java:43)

      > java -Xss1
      The Java thread stack size specified is too small. Specify at least 136k
      Error: Could not create the Java Virtual Machine.
      Error: A fatal exception has occurred. Program will exit.

      Verified on CentOS with one of my Ampere aarch64 platforms and a couple of x86 systems.

      A possible fix could be: do not write threadStackSize if it is 0, and ask for hotspot's help (JNI_GetDefaultJavaVMInitArgs in jni.cpp) to provide a reasonable value, if cannot get a valid one, force a bigger value to ensure the safety.

      jdk/src/java.base/share/native/libjli/java.c
      AddOption(char *str, void *info)
                  if (threadStackSize < (jlong)STACK_SIZE_MINIMUM) {
                      threadStackSize = STACK_SIZE_MINIMUM;
                  }

      ContinueInNewThread(InvocationFunctions* ifn, jlong threadStackSize,
          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;
            }
          }

            qpzhang Patrick Zhang
            qpzhang Patrick Zhang
            Votes:
            0 Vote for this issue
            Watchers:
            4 Start watching this issue

              Created:
              Updated:
              Resolved: