--- old/src/os/linux/vm/os_linux.cpp Sun Dec 18 23:42:45 2016 +++ new/src/os/linux/vm/os_linux.cpp Sun Dec 18 23:42:44 2016 @@ -1075,13 +1075,24 @@ // 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 @@ -1088,16 +1099,6 @@ // 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? - // Problem still exists RH7.2 (IA64 anyway) but 2MB is a little small - if (stack_size > 2 * K * K IA64_ONLY(*2)) - stack_size = 2 * K * K IA64_ONLY(*2); // 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 @@ -1257,14 +1258,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!"); } ////////////////////////////////////////////////////////////////////////////////