diff --git a/SOURCES/jdk8258836-jni_local_refs_exceed_capacity.patch b/SOURCES/jdk8258836-jni_local_refs_exceed_capacity.patch new file mode 100644 index 0000000..5da3e3c --- /dev/null +++ b/SOURCES/jdk8258836-jni_local_refs_exceed_capacity.patch @@ -0,0 +1,282 @@ +# HG changeset patch +# User sgehwolf +# Date 1611565076 0 +# Mon Jan 25 08:57:56 2021 +0000 +# Node ID 61c497b3b886f671646aec9d6e4cf3f44c422f99 +# Parent 59a62286b0b2a3057040df83640f38ea9499a60c +8258836: JNI local refs exceed capacity getDiagnosticCommandInfo +Reviewed-by: cjplummer, shade + +diff --git a/src/jdk.management/share/native/libmanagement_ext/DiagnosticCommandImpl.c b/src/jdk.management/share/native/libmanagement_ext/DiagnosticCommandImpl.c +--- a/src/jdk.management/share/native/libmanagement_ext/DiagnosticCommandImpl.c ++++ b/src/jdk.management/share/native/libmanagement_ext/DiagnosticCommandImpl.c +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2013, 2021, 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 +@@ -45,12 +45,21 @@ + return jmm_interface->GetDiagnosticCommands(env); + } + +-#define EXCEPTION_CHECK_AND_FREE(x) do { \ +- if ((*env)->ExceptionCheck(env)) { \ +- free(x); \ +- return NULL; \ +- } \ +- } while(0) ++// ++// Checks for an exception and if one occurred, ++// pops 'pops' local frames and frees 'x' before ++// returning NULL ++// ++#define POP_EXCEPTION_CHECK_AND_FREE(pops, x) do { \ ++ if ((*env)->ExceptionCheck(env)) { \ ++ int i; \ ++ for (i = 0; i < pops; i++) { \ ++ (*env)->PopLocalFrame(env, NULL); \ ++ } \ ++ free(x); \ ++ return NULL; \ ++ } \ ++ } while(0) + + jobject getDiagnosticCommandArgumentInfoArray(JNIEnv *env, jstring command, + int num_arg) { +@@ -73,10 +82,7 @@ + dcmd_arg_info_array); + dcmdArgInfoCls = (*env)->FindClass(env, + "com/sun/management/internal/DiagnosticCommandArgumentInfo"); +- if ((*env)->ExceptionCheck(env)) { +- free(dcmd_arg_info_array); +- return NULL; +- } ++ POP_EXCEPTION_CHECK_AND_FREE(0, dcmd_arg_info_array); + + result = (*env)->NewObjectArray(env, num_arg, dcmdArgInfoCls, NULL); + if (result == NULL) { +@@ -84,19 +90,21 @@ + return NULL; + } + for (i=0; iPushLocalFrame(env, 5); ++ jstring jname, jdesc, jtype, jdefStr; + + jname = (*env)->NewStringUTF(env,dcmd_arg_info_array[i].name); +- EXCEPTION_CHECK_AND_FREE(dcmd_arg_info_array); ++ POP_EXCEPTION_CHECK_AND_FREE(1, dcmd_arg_info_array); + + jdesc = (*env)->NewStringUTF(env,dcmd_arg_info_array[i].description); +- EXCEPTION_CHECK_AND_FREE(dcmd_arg_info_array); ++ POP_EXCEPTION_CHECK_AND_FREE(1, dcmd_arg_info_array); + + jtype = (*env)->NewStringUTF(env,dcmd_arg_info_array[i].type); +- EXCEPTION_CHECK_AND_FREE(dcmd_arg_info_array); ++ POP_EXCEPTION_CHECK_AND_FREE(1, dcmd_arg_info_array); + + jdefStr = (*env)->NewStringUTF(env, dcmd_arg_info_array[i].default_string); +- EXCEPTION_CHECK_AND_FREE(dcmd_arg_info_array); ++ POP_EXCEPTION_CHECK_AND_FREE(1, dcmd_arg_info_array); + obj = JNU_NewObjectByName(env, + "com/sun/management/internal/DiagnosticCommandArgumentInfo", + "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ZZZI)V", +@@ -107,11 +115,13 @@ + dcmd_arg_info_array[i].multiple, + dcmd_arg_info_array[i].position); + if (obj == NULL) { ++ (*env)->PopLocalFrame(env, NULL); + free(dcmd_arg_info_array); + return NULL; + } ++ obj = (*env)->PopLocalFrame(env, obj); + (*env)->SetObjectArrayElement(env, result, i, obj); +- EXCEPTION_CHECK_AND_FREE(dcmd_arg_info_array); ++ POP_EXCEPTION_CHECK_AND_FREE(0, dcmd_arg_info_array); + } + free(dcmd_arg_info_array); + arraysCls = (*env)->FindClass(env, "java/util/Arrays"); +@@ -144,51 +154,67 @@ + jint ret = jmm_interface->GetOptionalSupport(env, &mos); + jsize num_commands; + dcmdInfo* dcmd_info_array; +- jstring jname, jdesc, jimpact; ++ jstring jname, jdesc, jimpact, cmd; + + if (commands == NULL) { + JNU_ThrowNullPointerException(env, "Invalid String Array"); + return NULL; + } + num_commands = (*env)->GetArrayLength(env, commands); ++ // Ensure capacity for 2 + num_commands local refs: ++ // 2 => dcmdInfoCls, result ++ // num_commmands => one obj per command ++ (*env)->PushLocalFrame(env, 2 + num_commands); + dcmdInfoCls = (*env)->FindClass(env, + "com/sun/management/internal/DiagnosticCommandInfo"); + if ((*env)->ExceptionCheck(env)) { ++ (*env)->PopLocalFrame(env, NULL); + return NULL; + } + + result = (*env)->NewObjectArray(env, num_commands, dcmdInfoCls, NULL); + if (result == NULL) { ++ (*env)->PopLocalFrame(env, NULL); + return NULL; + } + if (num_commands == 0) { ++ result = (*env)->PopLocalFrame(env, result); + /* Handle the 'zero commands' case specially to avoid calling 'malloc()' */ + /* with a zero argument because that may legally return a NULL pointer. */ + return result; + } + dcmd_info_array = (dcmdInfo*) malloc(num_commands * sizeof(dcmdInfo)); + if (dcmd_info_array == NULL) { ++ (*env)->PopLocalFrame(env, NULL); + JNU_ThrowOutOfMemoryError(env, NULL); + return NULL; + } + jmm_interface->GetDiagnosticCommandInfo(env, commands, dcmd_info_array); + for (i=0; i jname, jdesc, jimpact, cmd, args, obj ++ // 3 => permission class, name, action ++ (*env)->PushLocalFrame(env, 6 + 3); ++ ++ cmd = (*env)->GetObjectArrayElement(env, commands, i); + args = getDiagnosticCommandArgumentInfoArray(env, +- (*env)->GetObjectArrayElement(env,commands,i), ++ cmd, + dcmd_info_array[i].num_arguments); + if (args == NULL) { ++ (*env)->PopLocalFrame(env, NULL); ++ (*env)->PopLocalFrame(env, NULL); + free(dcmd_info_array); + return NULL; + } + + jname = (*env)->NewStringUTF(env,dcmd_info_array[i].name); +- EXCEPTION_CHECK_AND_FREE(dcmd_info_array); ++ POP_EXCEPTION_CHECK_AND_FREE(2, dcmd_info_array); + + jdesc = (*env)->NewStringUTF(env,dcmd_info_array[i].description); +- EXCEPTION_CHECK_AND_FREE(dcmd_info_array); ++ POP_EXCEPTION_CHECK_AND_FREE(2, dcmd_info_array); + + jimpact = (*env)->NewStringUTF(env,dcmd_info_array[i].impact); +- EXCEPTION_CHECK_AND_FREE(dcmd_info_array); ++ POP_EXCEPTION_CHECK_AND_FREE(2, dcmd_info_array); + + obj = JNU_NewObjectByName(env, + "com/sun/management/internal/DiagnosticCommandInfo", +@@ -200,13 +226,17 @@ + dcmd_info_array[i].enabled, + args); + if (obj == NULL) { ++ (*env)->PopLocalFrame(env, NULL); ++ (*env)->PopLocalFrame(env, NULL); + free(dcmd_info_array); + return NULL; + } ++ obj = (*env)->PopLocalFrame(env, obj); + + (*env)->SetObjectArrayElement(env, result, i, obj); +- EXCEPTION_CHECK_AND_FREE(dcmd_info_array); ++ POP_EXCEPTION_CHECK_AND_FREE(1, dcmd_info_array); + } ++ result = (*env)->PopLocalFrame(env, result); + free(dcmd_info_array); + return result; + } +diff --git a/test/jdk/com/sun/management/DiagnosticCommandMBean/DcmdMBeanTestCheckJni.java b/test/jdk/com/sun/management/DiagnosticCommandMBean/DcmdMBeanTestCheckJni.java +new file mode 100644 +--- /dev/null ++++ b/test/jdk/com/sun/management/DiagnosticCommandMBean/DcmdMBeanTestCheckJni.java +@@ -0,0 +1,84 @@ ++/* ++ * Copyright (c) 2021, Red Hat, Inc. ++ * 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 ++ * @bug 8258836 ++ * @summary JNI local refs exceed capacity getDiagnosticCommandInfo ++ * @library /test/lib ++ * @run main/othervm DcmdMBeanTestCheckJni ++ */ ++ ++import java.lang.management.ManagementFactory; ++import javax.management.MBeanServer; ++import javax.management.ObjectName; ++import javax.management.MBeanServerConnection; ++import javax.management.remote.JMXConnectorFactory; ++import javax.management.remote.JMXConnector; ++import javax.management.remote.JMXConnectorServerFactory; ++import javax.management.remote.JMXServiceURL; ++import javax.management.remote.JMXConnectorServer; ++ ++import jdk.test.lib.process.OutputAnalyzer; ++import jdk.test.lib.process.ProcessTools; ++ ++public class DcmdMBeanTestCheckJni { ++ ++ public static void main(String[] args) throws Exception { ++ OutputAnalyzer out = ProcessTools.executeTestJvm( ++ "-Xcheck:jni", ++ DcmdMBeanRunner.class.getName()); ++ out.shouldNotMatch("WARNING: JNI local refs: \\d+, exceeds capacity: \\d+") ++ .shouldContain("DcmdMBeanRunner COMPLETE") ++ .shouldHaveExitValue(0); ++ } ++ ++} ++ ++class DcmdMBeanRunner { ++ ++ private static final String HOTSPOT_DIAGNOSTIC_MXBEAN_NAME = ++ "com.sun.management:type=DiagnosticCommand"; ++ ++ public static void main(String[] args) throws Exception { ++ MBeanServer mbs = ManagementFactory.getPlatformMBeanServer(); ++ JMXServiceURL url = new JMXServiceURL("rmi", null, 0); ++ JMXConnectorServer cs = null; ++ JMXConnector cc = null; ++ try { ++ cs = JMXConnectorServerFactory.newJMXConnectorServer(url, null, mbs); ++ cs.start(); ++ JMXServiceURL addr = cs.getAddress(); ++ cc = JMXConnectorFactory.connect(addr); ++ MBeanServerConnection mbsc = cc.getMBeanServerConnection(); ++ ObjectName name = new ObjectName(HOTSPOT_DIAGNOSTIC_MXBEAN_NAME); ++ System.out.println("DiagnosticCommand MBean: " + name); ++ System.out.println("DcmdMBeanRunner COMPLETE"); ++ } finally { ++ try { ++ cc.close(); ++ cs.stop(); ++ } catch (Exception e) { /* ignored */ } ++ } ++ } ++} diff --git a/SPECS/java-11-openjdk.spec b/SPECS/java-11-openjdk.spec index 6ce9832..21616b2 100644 --- a/SPECS/java-11-openjdk.spec +++ b/SPECS/java-11-openjdk.spec @@ -288,7 +288,7 @@ %global origin_nice OpenJDK %global top_level_dir_name %{origin} %global buildver 9 -%global rpmrelease 0 +%global rpmrelease 1 #%%global tagsuffix %%{nil} # priority must be 7 digits in total # setting to 1, so debug ones can have 0 @@ -1074,13 +1074,14 @@ Patch7: jdk8009550-rh910107-search_for_versioned_libpcsclite.patch ############################################# # -# Patches appearing in 11.0.10 +# Patches appearing in 11.0.11 # # This section includes patches which are present # in the listed OpenJDK 8u release and should be # able to be removed once that release is out # and used by this RPM. ############################################# +Patch8: jdk8258836-jni_local_refs_exceed_capacity.patch BuildRequires: autoconf BuildRequires: automake @@ -1095,13 +1096,6 @@ BuildRequires: freetype-devel BuildRequires: giflib-devel BuildRequires: gcc-c++ BuildRequires: gdb -%ifarch %{arm} -BuildRequires: devtoolset-7-build -BuildRequires: devtoolset-7-binutils -BuildRequires: devtoolset-7-gcc -BuildRequires: devtoolset-7-gcc-c++ -BuildRequires: devtoolset-7-gdb -%endif BuildRequires: gtk2-devel # LCMS on rhel7 is older then LCMS in intree JDK BuildRequires: lcms2-devel @@ -1383,6 +1377,7 @@ pushd %{top_level_dir_name} %patch3 -p1 %patch4 -p1 %patch7 -p1 +%patch8 -p1 popd # openjdk %patch1000 @@ -1436,10 +1431,6 @@ sed -e "s:@NSS_LIBDIR@:%{NSS_LIBDIR}:g" %{SOURCE11} > nss.cfg %build -%ifarch %{arm} -%{?enable_devtoolset7:%{enable_devtoolset7}} -%endif - # How many CPU's do we have? export NUM_PROC=%(/usr/bin/getconf _NPROCESSORS_ONLN 2> /dev/null || :) export NUM_PROC=${NUM_PROC:-1} @@ -1985,6 +1976,10 @@ require "copy_jdk_configs.lua" %endif %changelog +* Tue Mar 02 2021 Andrew Hughes - 1:11.0.10.0.9-1 +- Add backport of JDK-8258836 to fix -Xcheck:jni warnings +- Resolves: rhbz#1897602 + * Fri Jan 15 2021 Andrew Hughes - 1:11.0.10.0.9-0 - Update to jdk-11.0.10.0+9 - Update release notes to 11.0.10.0+9