--- /dev/null 2014-05-14 16:13:41.910435456 +0400 +++ new/test/runtime/StackGuardPages/DoOverflow.java 2014-05-14 13:36:52.041772126 +0400 @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2013, 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +public class DoOverflow { + + static int count; + + public void overflow() { + count+=1; + overflow(); + } + + public static void printAlive() { + System.out.println("Java thread is alive."); + } + + public static void printIt() { + System.out.println("Going to overflow stack"); + try { + new DoOverflow().overflow(); + } catch(java.lang.StackOverflowError e) { + System.out.println("Test PASSED. Got StackOverflowError at " + count + " iteration"); + } + } +} --- /dev/null 2014-05-14 16:13:41.910435456 +0400 +++ new/test/runtime/StackGuardPages/invoke.c 2014-05-14 13:36:52.516777251 +0400 @@ -0,0 +1,252 @@ +/* + * Copyright (c) 2010, 2014, 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +/* This code tests the fact that we actually remove stack guard page when calling + * JavaThread::exit() i.e. when detaching from current thread. + * We overflow the stack and check that we get access error because of a guard page. + * Than we detach from vm thread and overflow stack once again. This time we shouldn't + * get access error because stack guard page is removed + * + * Notice: due a complicated interaction of signal handlers, the test may crash. + * It's OK - don't file a bug. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +JavaVM* _jvm; + +static jmp_buf context; + +static int _last_si_code; +static int _failures = 0; + +pid_t gettid() { + return (pid_t) syscall(SYS_gettid); +} + +static void handler(int sig, siginfo_t *si, void *unused) { + _last_si_code = si->si_code; + printf("Got SIGSEGV(%d) at address: 0x%lx\n",si->si_code, (long) si->si_addr); + longjmp(context, 1); +} + +void set_signal_handler() { + static char altstack[SIGSTKSZ]; + + stack_t ss = { + .ss_size = SIGSTKSZ, + .ss_flags = 0, + .ss_sp = altstack + }; + + struct sigaction sa = { + .sa_sigaction = handler, + .sa_flags = SA_ONSTACK | SA_SIGINFO | SA_RESETHAND + }; + + sigaltstack(&ss, 0); + sigemptyset(&sa.sa_mask); + if (sigaction(SIGSEGV, &sa, NULL) == -1) { + fprintf(stderr, "Test ERROR. Can't set sigaction (%d)\n", errno); + exit(7); + } +} + +void *run_java_overflow (void *p) { + JNIEnv *env; + jclass class_id; + jmethodID method_id; + int res; + + res = (*_jvm)->AttachCurrentThread(_jvm, (void**)&env, NULL); + if (res != JNI_OK) { + fprintf(stderr, "Test ERROR. Can't attach to current thread\n"); + exit(7); + } + + class_id = (*env)->FindClass (env, "DoOverflow"); + if (class_id == NULL) { + fprintf(stderr, "Test ERROR. Can't load class DoOverflow\n"); + exit(7); + } + + method_id = (*env)->GetStaticMethodID(env, class_id, "printIt", "()V"); + if (method_id == NULL) { + fprintf(stderr, "Test ERROR. Can't find method DoOverflow.printIt\n"); + exit(7); + } + + (*env)->CallStaticVoidMethod(env, class_id, method_id, NULL); + + res = (*_jvm)->DetachCurrentThread(_jvm); + if (res != JNI_OK) { + fprintf(stderr, "Test ERROR. Can't call detach from current thread\n"); + exit(7); + } +} + +void do_overflow(){ + int *p = alloca(sizeof(int)); + do_overflow(); +} + +void *run_native_overflow(void *p) { + // Test that stack guard page is correctly set for initial and non initial thread + // and correctly removed for the initial thread + JNIEnv *env; + jclass class_id; + jmethodID method_id; + int res; + + printf("run_native_overflow %ld\n", (long) gettid()); + + res = (*_jvm)->AttachCurrentThread(_jvm, (void **)&env, NULL); + if (res != JNI_OK) { + fprintf(stderr, "Test ERROR. Can't attach to current thread\n"); + exit(7); + } + + class_id = (*env)->FindClass (env, "DoOverflow"); + if (class_id == NULL) { + fprintf(stderr, "Test ERROR. Can't load class DoOverflow\n"); + exit(7); + } + + method_id = (*env)->GetStaticMethodID (env, class_id, "printAlive", "()V"); + if (method_id == NULL) { + fprintf(stderr, "Test ERROR. Can't find method DoOverflow.printAlive\n"); + exit(7); + } + + (*env)->CallStaticVoidMethod (env, class_id, method_id, NULL); + + set_signal_handler(); + if (! setjmp(context)) { + do_overflow(); + } + + if (_last_si_code == SEGV_ACCERR) { + printf("Test PASSED. Got access violation accessing guard page\n"); + } + + res = (*_jvm)->DetachCurrentThread(_jvm); + if (res != JNI_OK) { + fprintf(stderr, "Test ERROR. Can't call detach from current thread\n"); + exit(7); + } + + if (getpid() != gettid()) { + // For non-initial thread we don't unmap the region but call os::uncommit_memory and keep PROT_NONE + // so if host has enough swap space we will get the same SEGV with code SEGV_ACCERR(2) trying + // to access it as if the guard page is present. + // We have no way to check this, so bail out, marking test as succeeded + printf("Test PASSED. Not initial thread\n"); + return NULL; + } + + set_signal_handler(); + if (! setjmp(context)) { + do_overflow(); + } + + if (_last_si_code == SEGV_ACCERR) { + ++ _failures; + fprintf(stderr,"Test FAILED. Stack guard page is still there\n"); + } + else { + printf("Test PASSED. No stack guard page is present\n"); + } + + return NULL; +} + +void usage() { + fprintf(stderr, "Usage: invoke test_java_overflow\n"); + fprintf(stderr, " invoke test_native_overflow\n"); + exit(7); +} + + +int main (int argc, const char** argv) { + JavaVMInitArgs vm_args; + JavaVMOption options[1]; + JNIEnv* env; + + printf("Test started with pid: %ld\n", (long) getpid()); + + options[0].optionString = "-Xss320k"; + + vm_args.version = JNI_VERSION_1_2; + vm_args.ignoreUnrecognized = JNI_TRUE; + vm_args.options = options; + vm_args.nOptions = 1; + + if (JNI_CreateJavaVM (&_jvm, (void **)&env, &vm_args) < 0 ) { + fprintf(stderr, "Test ERROR. Can't create JavaVM\n"); + exit(7); + } + + pthread_t thr; + + if (argc > 1 && strcmp(argv[1], "test_java_overflow") == 0) { + printf("\nTesting JAVA_OVERFLOW\n"); + + printf("Testing stack guard page behaviour for other thread\n"); + pthread_create (&thr, NULL, run_java_overflow, NULL); + pthread_join (thr, NULL); + + printf("Testing stack guard page behaviour for initial thread\n"); + run_java_overflow(NULL); + // This test crash on error + exit(0); + } + + if (argc > 1 && strcmp(argv[1], "test_native_overflow") == 0) { + printf("\nTesting NATIVE_OVERFLOW\n"); + + printf("Testing stack guard page behaviour for other thread\n"); + pthread_create (&thr, NULL, run_native_overflow, NULL); + pthread_join (thr, NULL); + + printf("Testing stack guard page behaviour for initial thread\n"); + run_native_overflow(NULL); + + exit((_failures > 0) ? 1 : 0); + } + + fprintf(stderr, "Test ERROR. Unknown parameter %s\n", ((argc > 1) ? argv[1] : "none")); + usage(); +} --- /dev/null 2014-05-14 16:13:41.910435456 +0400 +++ new/test/runtime/StackGuardPages/testme.sh 2014-05-14 13:36:52.984782301 +0400 @@ -0,0 +1,60 @@ +#!/bin/sh + +# +# @test testme.sh +# @summary Stack guard pages should be installed correctly and removed when thread is detached +# @run shell testme.sh +# + +if [ "${TESTSRC}" = "" ] +then + TESTSRC=${PWD} + echo "TESTSRC not set. Using "${TESTSRC}" as default" +fi +echo "TESTSRC=${TESTSRC}" +## Adding common setup Variables for running shell tests. +. ${TESTSRC}/../../test_env.sh + +if [ "${VM_OS}" != "linux" ] +then + echo "Test only valid for Linux" + exit 0 +fi + +gcc_cmd=`which gcc` +if [ "x$gcc_cmd" = "x" ]; then + echo "WARNING: gcc not found. Cannot execute test." 2>&1 + exit 0; +fi + +CFLAGS=-m${VM_BITS} + +LD_LIBRARY_PATH=.:${TESTJAVA}/jre/lib/${VM_CPU}/${VM_TYPE}:${TESTJAVA}/lib/${VM_CPU}/${VM_TYPE}:/usr/lib:$LD_LIBRARY_PATH +export LD_LIBRARY_PATH + +echo "Architecture: ${VM_CPU}" +echo "Compilation flag: ${CFLAGS}" +echo "VM type: ${VM_TYPE}" +echo "LD_LIBRARY_PATH: ${LD_LIBRARY_PATH}" + +# Note pthread may not be found thus invoke creation will fail to be created. +# Check to ensure you have a /usr/lib/libpthread.so if you don't please look +# for /usr/lib/`uname -m`-linux-gnu version ensure to add that path to below compilation. + +cp ${TESTSRC}/DoOverflow.java . +${COMPILEJAVA}/bin/javac DoOverflow.java + +$gcc_cmd -DLINUX -g3 ${CFLAGS} -o invoke \ + -I${TESTJAVA}/include -I${TESTJAVA}/include/linux \ + -L${TESTJAVA}/jre/lib/${VM_CPU}/${VM_TYPE} \ + -L${TESTJAVA}/lib/${VM_CPU}/${VM_TYPE} \ + ${TESTSRC}/invoke.c -ljvm -lpthread + +if [ $? -ne 0 ] ; then + echo "Compile failed, Ignoring failed compilation and forcing the test to pass" + exit 0 +fi + +./invoke test_java_overflow +./invoke test_native_overflow +exit $? --- old/test/runtime/6929067/T.java 2014-05-14 13:36:53.605789001 +0400 +++ /dev/null 2014-05-14 16:13:41.910435456 +0400 @@ -1,12 +0,0 @@ -public class T -{ - public static boolean foo(boolean bar) - { - return bar; - } - - public static void printIt() - { - System.out.println("Hello"); - } -} --- old/test/runtime/6929067/Test6929067.sh 2014-05-14 13:36:53.930792507 +0400 +++ /dev/null 2014-05-14 16:13:41.910435456 +0400 @@ -1,56 +0,0 @@ -#!/bin/sh - -## -## @test Test6929067.sh -## @bug 6929067 -## @bug 8021296 -## @bug 8025519 -## @summary Stack guard pages should be removed when thread is detached -## @run shell Test6929067.sh -## - -if [ "${TESTSRC}" = "" ] -then - TESTSRC=${PWD} - echo "TESTSRC not set. Using "${TESTSRC}" as default" -fi -echo "TESTSRC=${TESTSRC}" -## Adding common setup Variables for running shell tests. -. ${TESTSRC}/../../test_env.sh - -if [ "${VM_OS}" != "linux" ] -then - echo "Test only valid for Linux" - exit 0 -fi - -gcc_cmd=`which gcc` -if [ "x$gcc_cmd" = "x" ]; then - echo "WARNING: gcc not found. Cannot execute test." 2>&1 - exit 0; -fi - -CFLAGS=-m${VM_BITS} - -LD_LIBRARY_PATH=.:${TESTJAVA}/jre/lib/${VM_CPU}/${VM_TYPE}:/usr/lib:$LD_LIBRARY_PATH -export LD_LIBRARY_PATH - -cp ${TESTSRC}/*.java ${THIS_DIR} -${COMPILEJAVA}/bin/javac *.java - -echo "Architecture: ${VM_CPU}" -echo "Compilation flag: ${CFLAGS}" -echo "VM type: ${VM_TYPE}" -echo "LD_LIBRARY_PATH: ${LD_LIBRARY_PATH}" - -# Note pthread may not be found thus invoke creation will fail to be created. -# Check to ensure you have a /usr/lib/libpthread.so if you don't please look -# for /usr/lib/`uname -m`-linux-gnu version ensure to add that path to below compilation. - -$gcc_cmd -DLINUX ${CFLAGS} -o invoke \ - -I${TESTJAVA}/include -I${TESTJAVA}/include/linux \ - -L${TESTJAVA}/jre/lib/${VM_CPU}/${VM_TYPE} \ - ${TESTSRC}/invoke.c -ljvm -lpthread - -./invoke -exit $? --- old/test/runtime/6929067/invoke.c 2014-05-14 13:36:54.253795992 +0400 +++ /dev/null 2014-05-14 16:13:41.910435456 +0400 @@ -1,90 +0,0 @@ -#include -#include -#include - -#include - -union env_union -{ - void *void_env; - JNIEnv *jni_env; -}; - -union env_union tmp; -JNIEnv* env; -JavaVM* jvm; -JavaVMInitArgs vm_args; -JavaVMOption options[1]; -jclass class_id; -jmethodID method_id; -jint result; - -long product(unsigned long n, unsigned long m) { - if (m == 1) { - return n; - } else { - int *p = alloca(sizeof (int)); - *p = n; - return product (n, m-1) + *p; - } -} - -void * -floobydust (void *p) -{ - (*jvm)->AttachCurrentThread(jvm, &tmp.void_env, NULL); - env = tmp.jni_env; - - class_id = (*env)->FindClass (env, "T"); - assert (class_id); - - method_id = (*env)->GetStaticMethodID (env, class_id, "printIt", "()V"); - assert (method_id); - - (*env)->CallStaticVoidMethod (env, class_id, method_id, NULL); - - (*jvm)->DetachCurrentThread(jvm); - - printf("%ld\n", product(5000,5000)); - - (*jvm)->AttachCurrentThread(jvm, &tmp.void_env, NULL); - env = tmp.jni_env; - - class_id = (*env)->FindClass (env, "T"); - assert (class_id); - - method_id = (*env)->GetStaticMethodID (env, class_id, "printIt", "()V"); - assert (method_id); - - (*env)->CallStaticVoidMethod (env, class_id, method_id, NULL); - - (*jvm)->DetachCurrentThread(jvm); - - printf("%ld\n", product(5000,5000)); - - return NULL; -} - -int -main (int argc, const char** argv) -{ - options[0].optionString = "-Xss320k"; - - vm_args.version = JNI_VERSION_1_2; - vm_args.ignoreUnrecognized = JNI_TRUE; - vm_args.options = options; - vm_args.nOptions = 1; - - result = JNI_CreateJavaVM (&jvm, &tmp.void_env, &vm_args); - assert (result >= 0); - - env = tmp.jni_env; - - floobydust (NULL); - - pthread_t thr; - pthread_create (&thr, NULL, floobydust, NULL); - pthread_join (thr, NULL); - - return 0; -} --- old/test/runtime/InitialThreadOverflow/DoOverflow.java 2014-05-14 13:36:54.576799477 +0400 +++ /dev/null 2014-05-14 16:13:41.910435456 +0400 @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2013, 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 - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -public class DoOverflow { - - static int count; - - public void overflow() { - count+=1; - overflow(); - } - - public static void printIt() { - System.out.println("Going to overflow stack"); - try { - new DoOverflow().overflow(); - } catch(java.lang.StackOverflowError e) { - System.out.println("Overflow OK " + count); - } - } -} --- old/test/runtime/InitialThreadOverflow/invoke.c 2014-05-14 13:36:54.899802961 +0400 +++ /dev/null 2014-05-14 16:13:41.910435456 +0400 @@ -1,72 +0,0 @@ -/* - * Copyright (c) 2013, 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 - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -#include -#include - -#include - -JavaVM* jvm; - -void * -floobydust (void *p) { - JNIEnv *env; - jclass class_id; - jmethodID method_id; - - (*jvm)->AttachCurrentThread(jvm, (void**)&env, NULL); - - class_id = (*env)->FindClass (env, "DoOverflow"); - assert (class_id); - - method_id = (*env)->GetStaticMethodID(env, class_id, "printIt", "()V"); - assert (method_id); - - (*env)->CallStaticVoidMethod(env, class_id, method_id, NULL); - - (*jvm)->DetachCurrentThread(jvm); -} - -int -main (int argc, const char** argv) { - JavaVMOption options[1]; - options[0].optionString = (char*) "-Xss320k"; - - JavaVMInitArgs vm_args; - vm_args.version = JNI_VERSION_1_2; - vm_args.ignoreUnrecognized = JNI_TRUE; - vm_args.options = options; - vm_args.nOptions = 1; - - JNIEnv* env; - jint result = JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args); - assert(result >= 0); - - pthread_t thr; - pthread_create(&thr, NULL, floobydust, NULL); - pthread_join(thr, NULL); - - floobydust(NULL); - - return 0; -} --- old/test/runtime/InitialThreadOverflow/testme.sh 2014-05-14 13:36:55.224806469 +0400 +++ /dev/null 2014-05-14 16:13:41.910435456 +0400 @@ -1,77 +0,0 @@ -#!/bin/sh - -# Copyright (c) 2013 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 -# under the terms of the GNU General Public License version 2 only, as -# published by the Free Software Foundation. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. - -# @test testme.sh -# @bug 8009062 -# @summary Poor performance of JNI AttachCurrentThread after fix for 7017193 -# @compile DoOverflow.java -# @run shell testme.sh - -set -x -if [ "${TESTSRC}" = "" ] -then - TESTSRC=${PWD} - echo "TESTSRC not set. Using "${TESTSRC}" as default" -fi -echo "TESTSRC=${TESTSRC}" -## Adding common setup Variables for running shell tests. -. ${TESTSRC}/../../test_env.sh - -if [ "${VM_OS}" != "linux" ] -then - echo "Test only valid for Linux" - exit 0 -fi - -gcc_cmd=`which gcc` -if [ "x$gcc_cmd" = "x" ]; then - echo "WARNING: gcc not found. Cannot execute test." 2>&1 - exit 0; -fi - -CFLAGS="-m${VM_BITS}" - -LD_LIBRARY_PATH=.:${TESTJAVA}/jre/lib/${VM_CPU}/${VM_TYPE}:/usr/lib:$LD_LIBRARY_PATH -export LD_LIBRARY_PATH - -cp ${TESTSRC}/invoke.c . - -# Copy the result of our @compile action: -cp ${TESTCLASSES}/DoOverflow.class . - -echo "Architecture: ${VM_CPU}" -echo "Compilation flag: ${CFLAGS}" -echo "VM type: ${VM_TYPE}" -echo "LD_LIBRARY_PATH: ${LD_LIBRARY_PATH}" - -# Note pthread may not be found thus invoke creation will fail to be created. -# Check to ensure you have a /usr/lib/libpthread.so if you don't please look -# for /usr/lib/`uname -m`-linux-gnu version ensure to add that path to below compilation. - -$gcc_cmd -DLINUX ${CFLAGS} -o invoke \ - -I${TESTJAVA}/include -I${TESTJAVA}/include/linux \ - -L${TESTJAVA}/jre/lib/${VM_CPU}/${VM_TYPE} \ - -ljvm -lpthread invoke.c - -./invoke -exit $?