--- /dev/null 2015-10-28 19:12:34.000000000 +0300 +++ new/runtime/ThreadSignalMask/Prog.java 2015-10-28 19:12:34.000000000 +0300 @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + */ + +public class Prog +{ + public static void main(String args[]) + { + System.out.println("Java class invoked: " + args[0]); + try { + Prog.class.wait(); + } catch (Exception e) {} + } +} --- /dev/null 2015-10-28 19:12:34.000000000 +0300 +++ new/runtime/ThreadSignalMask/ThreadSignalMask.java 2015-10-28 19:12:34.000000000 +0300 @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + */ + +import java.io.File; +import java.lang.ProcessBuilder.Redirect; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.nio.file.StandardCopyOption; +import java.util.Arrays; +import java.util.List; + +/* + * @test + * @key cte_test + * @bug 4345157 + * @summary JDK 1.3.0 alters thread signal mask + * @requires (os.simpleArch == "sparcv9" & vm.flavor == "server") + * @compile Prog.java + * @run main/native ThreadSignalMask + */ +public class ThreadSignalMask { + + public static void main(String args[]) throws Exception { + + String testClasses = getSystemProperty("test.classes"); + + String testNativePath = getSystemProperty("test.nativepath"); + + String testJdk = getSystemProperty("test.jdk"); + + String currentDirPath = Paths.get(".") + .toAbsolutePath().normalize().toString(); + + File classFile + = new File(testClasses + File.separator + + Prog.class.getSimpleName()); + + //copy Prog.class file to be invoked from native + Files.copy(classFile.toPath(), (new File(currentDirPath + + File.separator + classFile.getName())) + .toPath(), StandardCopyOption.REPLACE_EXISTING); + + //copy compiled native executable + File executableFile = new File(testNativePath + File.separator + + ThreadSignalMask.class.getSimpleName()); + File executableFileLocal = new File(currentDirPath + File.separator + + executableFile.getName()); + Files.copy(executableFile.toPath(), executableFileLocal.toPath(), + StandardCopyOption.REPLACE_EXISTING); + + executableFileLocal.setExecutable(true); + + long[] intervalsArray = {2000, 5000, 10000, 2000}; + + List processArgs = Arrays.asList(executableFileLocal.getPath(), + testJdk + ); + ProcessBuilder pb = new ProcessBuilder(processArgs); + pb.redirectOutput(Redirect.INHERIT); + pb.redirectError(Redirect.INHERIT); + int result = 0; + for (int i = 0; i < intervalsArray.length; i++) { + Process p = pb.start(); + + //sleep for a specified period of time to let native run + sleep(intervalsArray[i]); + p.destroy(); + //sleep for a specified period of time to let native exit + sleep(intervalsArray[i]); + + //get exit value and validate it + result = p.exitValue(); + System.out.println("Result = " + result); + if (result == 0) { + break; + } + } + + if (result != 0) { + throw new Exception("Test Failed"); + } + + System.out.println("Test Passed"); + + } + + /** + * Utility method to handle Thread.sleep + * @param millis to specify sleep period + */ + private static void sleep(long millis) { + try { + System.out.println("Sleep for " + millis); + Thread.sleep(millis); + } catch (InterruptedException ex) { + System.err.println("Interrupted"); + } + } + + /** + * Utility method to retrieve and validate system properties + * @param propertyName system property to retrieve + * @return retrieved system property + * @throws Exception if system property is empty + */ + private static String getSystemProperty(String propertyName) throws Exception { + String systemProperty = System.getProperty(propertyName, "").trim(); + System.out.println(propertyName + " = " + systemProperty); + if (systemProperty.isEmpty()) { + throw new Exception("Property " + propertyName + " is empty"); + } + return systemProperty; + } +} --- /dev/null 2015-10-28 19:12:34.000000000 +0300 +++ new/runtime/ThreadSignalMask/exeThreadSignalMask.c 2015-10-28 19:12:34.000000000 +0300 @@ -0,0 +1,198 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + */ + +#if defined(__sun) && defined(__SVR4) +#define _POSIX_PTHREAD_SEMANTICS + +#include +#include +#include +#include +#include +#include +#include +#include + +void *handle; +char* error; +char path[PATH_MAX]; + +jint(JNICALL *jni_create_java_vm)(JavaVM **, JNIEnv **, void *) = NULL; + +JavaVM *jvm; + +extern void exit(int); + +void loadJVM() { + char lib[PATH_MAX]; + sprintf(lib, "%s/lib/sparcv9/server/libjvm.so", path); + handle = dlopen(lib, RTLD_LAZY); + if (!handle) { + fputs(dlerror(), stderr); + fputs(" : 2\n", stderr); + exit(1); + } + fputs("Will load JVM...\n", stderr); + + //find the address of function + *(void **) (&jni_create_java_vm) = dlsym(handle, "JNI_CreateJavaVM"); + if ((error = dlerror()) != NULL) { + fputs(error, stderr); + fputs(" : 3\n", stderr); + exit(1); + } + + fputs("JVM loaded okay.\n", stderr); +} + +JNIEnv* initJVM() /* The JDK1.2 way of doing it */ { + JNIEnv *env = NULL; + JavaVMInitArgs vm_args; + JavaVMOption options[1]; + jint res; + + /* options[0].optionString = "-Djava.class.path=."; */ /* user classes */ + options[0].optionString = "-Xrs"; /* user classes */ + + vm_args.version = JNI_VERSION_1_2; + vm_args.nOptions = 1; + vm_args.options = options; + vm_args.ignoreUnrecognized = JNI_FALSE; + + fputs("Will create JVM...\n", stderr); + + res = (*jni_create_java_vm)(&jvm, &env, &vm_args); + if (res < 0) { + fprintf(stderr, "Can't create Java VM: %d\n", res); + exit(1); + } + + fputs("JVM created OK!\n", stderr); + return env; +} + +void doStuff(JNIEnv *env) { + jclass cls; + jmethodID mid; + jstring jstr; + jobjectArray args; + + cls = (*env)->FindClass(env, "Prog"); + if (cls == 0) { + fprintf(stderr, "Can't find Prog class\n"); + exit(1); + } + + mid = (*env)->GetStaticMethodID(env, cls, "main", "([Ljava/lang/String;)V"); + if (mid == 0) { + fprintf(stderr, "Can't find Prog.main\n"); + exit(1); + } + + jstr = (*env)->NewStringUTF(env, "from C!"); + if (jstr == 0) { + fprintf(stderr, "Out of memory\n"); + exit(1); + } + args = (*env)->NewObjectArray(env, 1, + (*env)->FindClass(env, "java/lang/String"), jstr); + if (args == 0) { + fprintf(stderr, "Out of memory\n"); + exit(1); + } + (*env)->CallStaticVoidMethod(env, cls, mid, args); + +} + +JNIEnv* atchJVM() { + JNIEnv *env = NULL; + int res; + res = (*jvm)->AttachCurrentThread(jvm, (void**) &env, NULL); + if (res < 0) { + fprintf(stderr, "Thread attach failed\n"); + return NULL; + } + return env; +} + +void* somethr(void* x) { + JNIEnv *env; + + fprintf(stderr, "Some thread will create JVM.\n"); + loadJVM(); + env = initJVM(); + + fprintf(stderr, "Some thread will call Java.\n"); + + doStuff(env); + + if ((*jvm)->DetachCurrentThread(jvm) != 0) + fputs("Error: thread not detached!\n", stderr); + fprintf(stderr, "Some thread exiting.\n"); + return env; +} + +int main(int argc, char **argv) { + JNIEnv *env; + sigset_t set; + pthread_t thr1; + pthread_attr_t attr; + size_t ss = 0; + int sig; + + if (argc != 2) { + printf("usage: a.out jdk_path\n"); + exit(0); + } + strncpy(path, argv[1], PATH_MAX); + + fprintf(stderr, "Main thread will set signal mask.\n"); + + sigemptyset(&set); + sigaddset(&set, SIGPIPE); + sigaddset(&set, SIGTERM); + sigaddset(&set, SIGHUP); + sigaddset(&set, SIGINT); + pthread_sigmask(SIG_BLOCK, &set, NULL); + + pthread_attr_init(&attr); + ss = 1024 * 1024; + pthread_attr_setstacksize(&attr, ss); + pthread_attr_getstacksize(&attr, &ss); + fprintf(stderr, "Stack size: %zu\n", ss); + + pthread_create(&thr1, NULL, somethr, NULL); + + sigemptyset(&set); + sigaddset(&set, SIGTERM); + sigaddset(&set, SIGHUP); + sigaddset(&set, SIGINT); + + fprintf(stderr, "Main thread waiting for signal.\n"); + + do { + int err; + + sig = 0; + err = sigwait(&set, &sig); + if (err != 0 && err != EINTR) { + fprintf(stderr, "main: sigwait() error: %s\n", strerror(err)); + } else { + fprintf(stderr, "main: sigwait() got: %d\nSucceed!\n", sig); + exit(0); + } + } while (sig != SIGTERM && sig != SIGINT); + + pthread_join(thr1, NULL); + + dlclose(handle); + fputs("Main thread exiting.\n", stderr); + return 0; +} +#else +int main(int argc, char **argv) { + return 0; +} +#endif --- old/runtime/4345157/Makefile 2015-10-28 19:12:35.000000000 +0300 +++ /dev/null 2015-10-28 19:12:35.000000000 +0300 @@ -1,5 +0,0 @@ -all: RunTest Prog.class -RunTest: RunTest.c - cc -mt -m64 -D_LP64 -D_POSIX_PTHREAD_SEMANTICS -I${COMPILEJAVA}/include -I${COMPILEJAVA}/include/solaris -ldl RunTest.c -Prog.class: Prog.java - ${COMPILEJAVA}/bin/javac ${TESTJAVACOPTS} Prog.java --- old/runtime/4345157/Prog.java 2015-10-28 19:12:35.000000000 +0300 +++ /dev/null 2015-10-28 19:12:35.000000000 +0300 @@ -1,20 +0,0 @@ -/* - * @test - * @key cte_test - * @bug 4345157 - * @summary JDK 1.3.0 alters thread signal mask - * @ignore 8055113 - * @compile Prog.java - * @run shell Test4345157.sh -*/ - -public class Prog -{ - public static void main(String args[]) - { - System.out.println("Java class invoked: " + args[0]); - try { - Prog.class.wait(); - } catch (Exception e) {} - } -} --- old/runtime/4345157/README 2015-10-28 19:12:35.000000000 +0300 +++ /dev/null 2015-10-28 19:12:35.000000000 +0300 @@ -1,12 +0,0 @@ -Bug # 4345157 - - JDK 1.3.0 alters thread signal mask - -Run the test on a Solaris sparc machine. -If you don't see RunTest and Prog.class files, do a make. -Run the testcase as: -RunTest jdk_path -e.g., RunTest /usr/local/java/jdk1.3.1/solsparc, or - RunTest /usr/local/java/jdk1.3.0-solaris/solaris -After you see the line of "Java class invoked: from C!" or -"Some thread exiting.", hit Ctrl-C. If you see "Succeed!" before -it exits, the test passes. Otherwise, it fails. --- old/runtime/4345157/RunTest.c 2015-10-28 19:12:36.000000000 +0300 +++ /dev/null 2015-10-28 19:12:36.000000000 +0300 @@ -1,182 +0,0 @@ -#include -#include -#include -#include -#include -#include - -void *handle; -char* error; -char path[PATH_MAX]; - -jint (JNICALL *jni_create_java_vm)(JavaVM **, JNIEnv **, void *) = NULL; - -JavaVM *jvm; - -void loadJVM() -{ - char lib[PATH_MAX]; - sprintf(lib, "%s/jre/lib/sparcv9/server/libjvm.so", path); - handle = dlopen(lib, RTLD_LAZY); - if (!handle) { - fputs (dlerror(), stderr); - fputs (" : 2\n", stderr); - exit(1); - } - fputs("Will load JVM...\n", stderr); - - jni_create_java_vm = dlsym(handle, "JNI_CreateJavaVM"); - if ((error = dlerror()) != NULL) { - fputs(error, stderr); - fputs (" : 3\n", stderr); - exit(1); - } - - fputs("JVM loaded okay.\n", stderr); -} - -JNIEnv* initJVM() /* The JDK1.2 way of doing it */ -{ - JNIEnv *env = NULL; - JavaVMInitArgs vm_args; - JavaVMOption options[1]; - jint res; - -/* options[0].optionString = "-Djava.class.path=."; */ /* user classes */ - options[0].optionString = "-Xrs"; /* user classes */ - - vm_args.version = JNI_VERSION_1_2; - vm_args.nOptions = 1; - vm_args.options = options; - vm_args.ignoreUnrecognized = JNI_FALSE; - - fputs("Will create JVM...\n", stderr); - - res = (*jni_create_java_vm)(&jvm, &env, &vm_args); - if (res < 0) { - fprintf(stderr, "Can't create Java VM: %d\n", res); - exit(1); - } - - fputs("JVM created OK!\n", stderr); - return env; -} - -void doStuff(JNIEnv *env) -{ - jclass cls; - jmethodID mid; - jstring jstr; - jobjectArray args; - - cls = (*env)->FindClass(env, "Prog"); - if (cls == 0) { - fprintf(stderr, "Can't find Prog class\n"); - exit(1); - } - - mid = (*env)->GetStaticMethodID(env, cls, "main", "([Ljava/lang/String;)V"); - if (mid == 0) { - fprintf(stderr, "Can't find Prog.main\n"); - exit(1); - } - - jstr = (*env)->NewStringUTF(env, "from C!"); - if (jstr == 0) { - fprintf(stderr, "Out of memory\n"); - exit(1); - } - args = (*env)->NewObjectArray(env, 1, - (*env)->FindClass(env, "java/lang/String"), jstr); - if (args == 0) { - fprintf(stderr, "Out of memory\n"); - exit(1); - } - (*env)->CallStaticVoidMethod(env, cls, mid, args); - -} - -JNIEnv* atchJVM() -{ - JNIEnv *env = NULL; - int res; - res = (*jvm)->AttachCurrentThread(jvm, (void**)&env, NULL); - if (res < 0) { - fprintf(stderr, "Thread attach failed\n"); - return NULL; - } - return env; -} - -void* somethr(void* x) -{ - JNIEnv *env; - - fprintf(stderr, "Some thread will create JVM.\n"); - loadJVM(); - env = initJVM(); - - fprintf(stderr, "Some thread will call Java.\n"); - - doStuff(env); - - if((*jvm)->DetachCurrentThread(jvm) != 0) - fputs("Error: thread not detached!\n", stderr); - fprintf(stderr, "Some thread exiting.\n"); - return env; -} -int main(int argc, char **argv) -{ - JNIEnv *env; - sigset_t set; - pthread_t thr1; - pthread_attr_t attr; - size_t ss=0; - int sig; - - if (argc != 2) {printf("usage: a.out jdk_path\n"); exit(0);} - strncpy(path, argv[1], PATH_MAX); - - fprintf(stderr, "Main thread will set signal mask.\n"); - - sigemptyset(&set); - sigaddset(&set, SIGPIPE); - sigaddset(&set, SIGTERM); - sigaddset(&set, SIGHUP); - sigaddset(&set, SIGINT); - pthread_sigmask(SIG_BLOCK, &set, NULL); - - pthread_attr_init(&attr); - ss = 1024 * 1024; - pthread_attr_setstacksize(&attr, ss); - pthread_attr_getstacksize(&attr, &ss); - fprintf(stderr, "Stack size: %d\n", ss); - - pthread_create(&thr1,NULL,somethr,NULL); - - sigemptyset(&set); - sigaddset(&set, SIGTERM); - sigaddset(&set, SIGHUP); - sigaddset(&set, SIGINT); - - fprintf(stderr, "Main thread waiting for signal.\n"); - - do { - int err; - - sig = 0; - err = sigwait(&set, &sig); - if (err != 0 && err != EINTR) { - fprintf(stderr, "main: sigwait() error: %s\n", strerror(err)); - } - else { - fprintf(stderr, "main: sigwait() got: %d\nSucceed!\n", sig); - exit(0); - } - } while (sig != SIGTERM && sig != SIGINT); - - pthread_join(thr1, NULL); - - dlclose(handle); - fputs("Main thread exiting.\n", stderr); -} --- old/runtime/4345157/Test4345157.sh 2015-10-28 19:12:36.000000000 +0300 +++ /dev/null 2015-10-28 19:12:36.000000000 +0300 @@ -1,95 +0,0 @@ -#!/bin/sh -# -# Copyright (c) 2011, 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. -# -# - -## some tests require path to find test source dir -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 - -# set platform-dependent variables -OS=`uname -s` -case "$OS" in - SunOS ) - if [ `uname -p` != 'sparc' ] - then - echo "Test Passed for Solaris X86 platform" - exit 0 - fi - NULL=/dev/null - ;; - * ) - echo "Test Passed, only for Solaris sparc platform" - exit 0; - ;; -esac - -${COMPILEJAVA}${FS}bin${FS}jar -xf ${TESTSRC}${FS}RunTest.jar -cp ${TESTCLASSES}${FS}Prog.class . -chmod 777 RunTest - -#${TESTJAVA}${FS}bin${FS}java ${TESTOPTS} Test > test${time}.out 2>&1 - -RETURN_VALUE=0 -# use increased sleep values as optimization, JDK-8033268 -for time in 2 5 10 20 -do -{ - echo "Running the test with sleep time: "$time - - ./RunTest ${TESTJAVA} > test${time}.out 2>&1 & - C_PID=$! - - sleep $time - - kill -TERM $C_PID - - sleep $time - - grep "Succeed!" test${time}.out - RETURN_VALUE=$? - if [ $RETURN_VALUE -eq 0 ]; then - { - break - } - fi -} -done - -if [ $RETURN_VALUE -eq 0 ]; then -{ - echo "Test Passed" -} -else -{ - echo "Test Failed" -} -fi - -exit $RETURN_VALUE;