# HG changeset patch # User dholmes # Date 1482267970 18000 # Node ID 285e3f9a1d189a128738829261e9584769972d80 # Parent 3d710f44a7f2e63131d8b755fe0aa0b4ed9f39a9 8170307: Stack size option -Xss is ignored Reviewed-by: dcubed, sspitsyn, gtriantafill diff -r 3d710f44a7f2 -r 285e3f9a1d18 src/os/linux/vm/os_linux.cpp --- a/src/os/linux/vm/os_linux.cpp Fri Dec 09 19:40:47 2016 +0300 +++ b/src/os/linux/vm/os_linux.cpp Tue Dec 20 16:06:10 2016 -0500 @@ -1160,33 +1160,30 @@ // Locate initial thread stack. This special handling of initial thread stack // is needed because pthread_getattr_np() on most (all?) Linux distros returns -// bogus value for initial thread. +// bogus value for the primordial process thread. While the launcher has created +// the VM in a new thread since JDK 6, we still have to allow for the use of the +// JNI invocation API from a primordial thread. void os::Linux::capture_initial_stack(size_t max_size) { - // stack size is the easy part, get it from RLIMIT_STACK - size_t stack_size; + + // max_size is either 0 (which means accept OS default for thread stacks) or + // a user-specified value known to be at least the minimum needed. If we + // are actually on the primordial thread we can make it appear that we have a + // smaller max_size stack by inserting the guard pages at that location. But we + // cannot do anything to emulate a larger stack than what has been provided by + // the OS or threading library. In fact if we try to use a stack greater than + // what is set by rlimit then we will crash the hosting process. + + // Maximum stack size is the easy part, get it from RLIMIT_STACK. + // If this is "unlimited" then it will be a huge value. struct rlimit rlim; getrlimit(RLIMIT_STACK, &rlim); - stack_size = rlim.rlim_cur; + size_t stack_size = rlim.rlim_cur; // 6308388: a bug in ld.so will relocate its own .data section to the // lower end of primordial stack; reduce ulimit -s value a little bit // so we won't install guard page on ld.so's data section. stack_size -= 2 * page_size(); - // 4441425: avoid crash with "unlimited" stack size on SuSE 7.1 or Redhat - // 7.1, in both cases we will get 2G in return value. - // 4466587: glibc 2.2.x compiled w/o "--enable-kernel=2.4.0" (RH 7.0, - // SuSE 7.2, Debian) can not handle alternate signal stack correctly - // for initial thread if its stack size exceeds 6M. Cap it at 2M, - // in case other parts in glibc still assumes 2M max stack size. - // FIXME: alt signal stack is gone, maybe we can relax this constraint? -#ifndef IA64 - if (stack_size > 2 * K * K) stack_size = 2 * K * K; -#else - // Problem still exists RH7.2 (IA64 anyway) but 2MB is a little small - if (stack_size > 4 * K * K) stack_size = 4 * K * K; -#endif - // Try to figure out where the stack base (top) is. This is harder. // // When an application is started, glibc saves the initial stack pointer in @@ -1346,14 +1343,18 @@ // stack_top could be partially down the page so align it stack_top = align_size_up(stack_top, page_size()); - if (max_size && stack_size > max_size) { - _initial_thread_stack_size = max_size; + // Allowed stack value is minimum of max_size and what we derived from rlimit + if (max_size > 0) { + _initial_thread_stack_size = MIN2(max_size, stack_size); } else { - _initial_thread_stack_size = stack_size; + // Accept the rlimit max, but if stack is unlimited then it will be huge, so + // clamp it at 8MB as we do on Solaris + _initial_thread_stack_size = MIN2(stack_size, 8*M); } _initial_thread_stack_size = align_size_down(_initial_thread_stack_size, page_size()); _initial_thread_stack_bottom = (address)stack_top - _initial_thread_stack_size; + assert(_initial_thread_stack_bottom < (address)stack_top, "overflow!"); } ////////////////////////////////////////////////////////////////////////////////