# HG changeset patch # User sspitsyn # Date 1497395989 25200 # Node ID d7709f2d4bd36bf4de3f485d936cbe581a82d2ec # Parent 921359dbc96bfd00a3134617d2882b3559d32a96 8178054: [TESTBUG] Need test for JVM TI IsModifiableModule Summary: Add new test hotspot/test/serviceability/jvmti/GetNamedModule Reviewed-by: alanb, iignatyev diff -r 921359dbc96b -r d7709f2d4bd3 make/test/JtregNative.gmk --- a/make/test/JtregNative.gmk Wed Jun 07 18:57:35 2017 -0700 +++ b/make/test/JtregNative.gmk Tue Jun 13 16:19:49 2017 -0700 @@ -56,6 +56,7 @@ $(HOTSPOT_TOPDIR)/test/compiler/floatingpoint/ \ $(HOTSPOT_TOPDIR)/test/compiler/calls \ $(HOTSPOT_TOPDIR)/test/serviceability/jvmti/GetNamedModule \ + $(HOTSPOT_TOPDIR)/test/serviceability/jvmti/IsModifiableModule \ $(HOTSPOT_TOPDIR)/test/serviceability/jvmti/AddModuleReads \ $(HOTSPOT_TOPDIR)/test/serviceability/jvmti/AddModuleExportsAndOpens \ $(HOTSPOT_TOPDIR)/test/serviceability/jvmti/AddModuleUsesAndProvides \ @@ -85,6 +86,7 @@ BUILD_HOTSPOT_JTREG_LIBRARIES_LIBS_liboverflow := -lc BUILD_HOTSPOT_JTREG_LIBRARIES_LIBS_libSimpleClassFileLoadHook := -lc BUILD_HOTSPOT_JTREG_LIBRARIES_LIBS_libGetNamedModuleTest := -lc + BUILD_HOTSPOT_JTREG_LIBRARIES_LIBS_libIsModifiableModuleTest := -lc BUILD_HOTSPOT_JTREG_LIBRARIES_LDFLAGS_libAddModuleReadsTest := -lc BUILD_HOTSPOT_JTREG_LIBRARIES_LDFLAGS_libAddModuleExportsAndOpensTest := -lc BUILD_HOTSPOT_JTREG_LIBRARIES_LDFLAGS_libAddModuleUsesAndProvidesTest := -lc diff -r 921359dbc96b -r d7709f2d4bd3 test/serviceability/jvmti/GetNamedModule/MyPackage/GetNamedModuleTest.java --- a/test/serviceability/jvmti/GetNamedModule/MyPackage/GetNamedModuleTest.java Wed Jun 07 18:57:35 2017 -0700 +++ b/test/serviceability/jvmti/GetNamedModule/MyPackage/GetNamedModuleTest.java Tue Jun 13 16:19:49 2017 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2017, 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 @@ -26,6 +26,7 @@ /** * @test * @summary Verifies the JVMTI GetNamedModule API + * @modules jdk.jdi * @compile GetNamedModuleTest.java * @run main/othervm/native -agentlib:GetNamedModuleTest MyPackage.GetNamedModuleTest */ diff -r 921359dbc96b -r d7709f2d4bd3 test/serviceability/jvmti/IsModifiableModule/MyPackage/IsModifiableModuleTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/serviceability/jvmti/IsModifiableModule/MyPackage/IsModifiableModuleTest.java Tue Jun 13 16:19:49 2017 -0700 @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2017, 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. + */ + +package MyPackage; + +/** + * @test + * @summary Verifies the JVMTI IsModifiableModule API + * @modules jdk.jdi + * @compile IsModifiableModuleTest.java + * @run main/othervm/native -agentlib:IsModifiableModuleTest MyPackage.IsModifiableModuleTest + */ + +import java.io.PrintStream; + +public class IsModifiableModuleTest { + + static { + try { + System.loadLibrary("IsModifiableModuleTest"); + } catch (UnsatisfiedLinkError ule) { + System.err.println("Could not load IsModifiableModuleTest library"); + System.err.println("java.library.path: " + + System.getProperty("java.library.path")); + throw ule; + } + } + + native static int check(); + + public static void main(String args[]) { + int status = check(); + if (status != 0) { + throw new RuntimeException("Non-zero status returned from the agent: " + status); + } + } +} diff -r 921359dbc96b -r d7709f2d4bd3 test/serviceability/jvmti/IsModifiableModule/libIsModifiableModuleTest.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/serviceability/jvmti/IsModifiableModule/libIsModifiableModuleTest.c Tue Jun 13 16:19:49 2017 -0700 @@ -0,0 +1,215 @@ +/* + * Copyright (c) 2017, 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 "jvmti.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef JNI_ENV_ARG + +#ifdef __cplusplus +#define JNI_ENV_ARG(x, y) y +#define JNI_ENV_PTR(x) x +#else +#define JNI_ENV_ARG(x,y) x, y +#define JNI_ENV_PTR(x) (*x) +#endif + +#endif + +#define TranslateError(err) "JVMTI error" + +#define PASSED 0 +#define FAILED 2 + +static const char *EXC_CNAME = "java/lang/AssertionError"; + +static jvmtiEnv *jvmti = NULL; +static jint result = PASSED; +static jboolean printdump = JNI_FALSE; + +static jint Agent_Initialize(JavaVM *jvm, char *options, void *reserved); + +JNIEXPORT +jint JNICALL Agent_OnLoad(JavaVM *jvm, char *options, void *reserved) { + return Agent_Initialize(jvm, options, reserved); +} + +JNIEXPORT +jint JNICALL Agent_OnAttach(JavaVM *jvm, char *options, void *reserved) { + return Agent_Initialize(jvm, options, reserved); +} + +JNIEXPORT +jint JNICALL JNI_OnLoad(JavaVM *jvm, void *reserved) { + return JNI_VERSION_1_8; +} + +static +jint Agent_Initialize(JavaVM *jvm, char *options, void *reserved) { + jint res; + + if (options != NULL && strcmp(options, "printdump") == 0) { + printdump = JNI_TRUE; + } + + res = JNI_ENV_PTR(jvm)->GetEnv(JNI_ENV_ARG(jvm, (void **) &jvmti), + JVMTI_VERSION_9); + if (res != JNI_OK || jvmti == NULL) { + printf(" Error: wrong result of a valid call to GetEnv!\n"); + return JNI_ERR; + } + + return JNI_OK; +} + +static +jclass find_class(JNIEnv *env, const char* cname) { + jclass cls = JNI_ENV_PTR(env)->FindClass(JNI_ENV_ARG(env, cname)); + + if (cls == NULL) { + printf("find_class: Error: FindClass(env, \"%s\") returned NULL\n", cname); + } + return cls; +} + +static +jint throw_exc(JNIEnv *env, char *msg) { + jclass exc_class = find_class(env, EXC_CNAME); + + if (exc_class == NULL) { + printf("throw_exc: Error in find_class(env, \"%s\")\n", EXC_CNAME); + return -1; + } + return JNI_ENV_PTR(env)->ThrowNew(JNI_ENV_ARG(env, exc_class), msg); +} + +static jobject get_module_by_class_name(JNIEnv *env, const char* cname) { + jobject module = NULL; + jclass cls = find_class(env, cname); + + printf(">>> getting module by class name: \"%s\"\n", cname); + if (cls == NULL) { + printf("get_module_by_class_name: Error in find_class(env, \"%s\")\n", cname); + return NULL; + } + module = JNI_ENV_PTR(env)->GetModule(JNI_ENV_ARG(env, cls)); + if (module == NULL) { + printf("get_module_by_class_name: Error in GetModule for class \"%s\"\n", cname); + } + return module; +} + +static +jint check_is_modifiable_error_codes(jobject module, jobject not_a_module) { + jvmtiError err = JVMTI_ERROR_NONE; + jboolean is_modifiable = JNI_FALSE; + + printf(">>> passing a bad module argument to JVMTI IsModifiableModule\n"); + err = (*jvmti)->IsModifiableModule(jvmti, not_a_module, &is_modifiable); + if (err != JVMTI_ERROR_INVALID_MODULE) { + printf(" Error #EC0: Did not get expected INVALID_MODULE error code from" + " IsModifiableModule: %s (%d)\n", TranslateError(err), err); + return FAILED; + } + printf(">>> passing NULL module argument to JVMTI IsModifiableModule\n"); + err = (*jvmti)->IsModifiableModule(jvmti, NULL, &is_modifiable); + if (err != JVMTI_ERROR_NULL_POINTER) { + printf(" Error #EC1: Did not get expected NULL_POINTER error code from" + " IsModifiableModule: %s (%d)\n", TranslateError(err), err); + return FAILED; + } + printf(">>> passing NULL status pointer to JVMTI IsModifiableModule\n"); + err = (*jvmti)->IsModifiableModule(jvmti, module, NULL); + if (err != JVMTI_ERROR_NULL_POINTER) { + printf(" Error #EC2: Did not get expected NULL_POINTER error code from" + " IsModifiableModule: %s (%d)\n", TranslateError(err), err); + return FAILED; + } + return PASSED; +} + +static +jint check_is_modifiable(jobject module) { + jvmtiError err = JVMTI_ERROR_NONE; + jboolean is_modifiable = JNI_FALSE; + + printf(">>> checking module %p is modifiable\n", module); + err = (*jvmti)->IsModifiableModule(jvmti, module, &is_modifiable); + if (err != JVMTI_ERROR_NONE) { + printf(" Error in IsModifiableModule for module %p: %s (%d)\n", + module, TranslateError(err), err); + return FAILED; + } + if (is_modifiable == JNI_FALSE) { + printf(" unexpected non-modifiable status for module: %p\n", module); + return FAILED; + } + return PASSED; +} + +JNIEXPORT jint JNICALL +Java_MyPackage_IsModifiableModuleTest_check(JNIEnv *env, jclass cls) { + jobject module = NULL; + + if (jvmti == NULL) { + throw_exc(env, "JVMTI client was not properly loaded!\n"); + return FAILED; + } + + printf("\n*** Testing IsModifiableModule ***\n\n"); + + if (check_is_modifiable_error_codes(module, cls) == FAILED) { + throw_exc(env, "check #MM0: failed to return expected error code from " + "a bad call to JVMTI IsModifiableModule"); + return FAILED; + } + + module = get_module_by_class_name(env, "java/lang/Class"); + if (check_is_modifiable(module) == FAILED) { + throw_exc(env, "check #MM1: failed to return modifiable module status"); + return FAILED; + } + + module = get_module_by_class_name(env, "com/sun/jdi/VirtualMachine"); + if (check_is_modifiable(module) == FAILED) { + throw_exc(env, "check #MM2: failed to return modifiable module status"); + return FAILED; + } + + module = get_module_by_class_name(env, "MyPackage/IsModifiableModuleTest"); + if (check_is_modifiable(module) == FAILED) { + throw_exc(env, "check #MM3: failed to return modifiable module status"); + return FAILED; + } + + return PASSED; +} + +#ifdef __cplusplus +} +#endif