1 /* 2 * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 #include <stdio.h> 25 #include <stdarg.h> 26 #include <stdlib.h> 27 #include <string.h> 28 29 #include <jvmti.h> 30 #include "agent_common.h" 31 32 #include "nsk_tools.h" 33 #include "JVMTITools.h" 34 #include "jvmti_tools.h" 35 36 extern "C" { 37 38 #define PASSED 0 39 #define STATUS_FAILED 2 40 41 /* classes which must have the class load event */ 42 static const char *expSigs[] = { 43 "Lnsk/jvmti/ClassLoad/classload001;", 44 "Lnsk/jvmti/ClassLoad/classload001$TestedClass;" 45 }; 46 #define EXP_SIG_NUM (sizeof(expSigs)/sizeof(char*)) 47 48 /* classes which must not have the class load event */ 49 static const char *unexpSigs[] = { 50 "Z", /* boolean */ 51 "B", /* byte */ 52 "C", /* char */ 53 "D", /* double */ 54 "F", /* float */ 55 "I", /* integer */ 56 "J", /* long */ 57 "S", /* short */ 58 59 "[Z", /* boolean array */ 60 "[B", /* byte array */ 61 "[C", /* char array */ 62 "[D", /* double array */ 63 "[F", /* float array */ 64 "[I", /* integer array */ 65 "[J", /* long array */ 66 "[S", /* short array */ 67 "[Lnsk/jvmti/ClassLoad/classload001$TestedClass;" 68 }; 69 #define UNEXP_SIG_NUM (sizeof(unexpSigs)/sizeof(char*)) 70 71 static volatile int clsEvents[EXP_SIG_NUM]; 72 static volatile int primClsEvents[UNEXP_SIG_NUM]; 73 74 static jint result = PASSED; 75 static jvmtiEnv *jvmti = NULL; 76 static jvmtiEventCallbacks callbacks; 77 static jrawMonitorID countLock; 78 79 static void initCounters() { 80 size_t i; 81 82 for(i=0; i<EXP_SIG_NUM; i++) 83 clsEvents[i] = 0; 84 85 for(i=0; i<UNEXP_SIG_NUM; i++) 86 primClsEvents[i] = 0; 87 } 88 89 static int findSig(char *sig, int expected) { 90 unsigned int i; 91 92 for (i=0; i<((expected==1)?EXP_SIG_NUM:UNEXP_SIG_NUM); i++) 93 if (sig != NULL && 94 strcmp(((expected==1)?expSigs[i]:unexpSigs[i]), sig) == 0) 95 return i; /* the signature found, return index */ 96 97 return -1; /* the signature not found */ 98 } 99 100 static void lock(jvmtiEnv *jvmti_env, JNIEnv *jni_env) { 101 if (!NSK_JVMTI_VERIFY(jvmti_env->RawMonitorEnter(countLock))) 102 jni_env->FatalError("failed to enter a raw monitor\n"); 103 } 104 105 static void unlock(jvmtiEnv *jvmti_env, JNIEnv *jni_env) { 106 if (!NSK_JVMTI_VERIFY(jvmti_env->RawMonitorExit(countLock))) 107 jni_env->FatalError("failed to exit a raw monitor\n"); 108 } 109 110 /** callback functions **/ 111 void JNICALL 112 ClassLoad(jvmtiEnv *jvmti_env, JNIEnv *env, jthread thread, jclass klass) { 113 int i = 0; 114 char *sig, *generic; 115 116 lock(jvmti_env, env); 117 118 if (!NSK_JVMTI_VERIFY(jvmti_env->GetClassSignature(klass, &sig, &generic))) { 119 result = STATUS_FAILED; 120 NSK_COMPLAIN0("TEST FAILURE: unable to obtain a class signature\n"); 121 } 122 123 if ((i = findSig(sig, 1)) != -1) { 124 clsEvents[i]++; 125 NSK_DISPLAY1("CHECK PASSED: ClassLoad event received for the class \"%s\" as expected\n", 126 sig); 127 } 128 else if ((i = findSig(sig, 0)) != -1) { 129 result = STATUS_FAILED; 130 primClsEvents[i]++; 131 NSK_COMPLAIN1( 132 "TEST FAILED: JVMTI_EVENT_CLASS_LOAD event received for\n" 133 "\t a primitive class/array of primitive types with the signature \"%s\"\n", 134 sig); 135 } 136 137 unlock(jvmti_env, env); 138 } 139 /************************/ 140 141 JNIEXPORT jint JNICALL 142 Java_nsk_jvmti_ClassLoad_classload001_check( 143 JNIEnv *env, jobject obj) { 144 size_t i; 145 146 for (i=0; i<EXP_SIG_NUM; i++) 147 if (clsEvents[i] != 1) { 148 result = STATUS_FAILED; 149 NSK_COMPLAIN2("TEST FAILED: wrong number of JVMTI_EVENT_CLASS_LOAD events for \"%s\":\n\tgot: %d\texpected: 1\n", 150 expSigs[i], clsEvents[i]); 151 } 152 153 for (i=0; i<UNEXP_SIG_NUM; i++) 154 if (primClsEvents[i] != 0) 155 NSK_COMPLAIN0("TEST FAILED: there are JVMTI_EVENT_CLASS_LOAD events for the primitive classes\n"); 156 157 return result; 158 } 159 160 #ifdef STATIC_BUILD 161 JNIEXPORT jint JNICALL Agent_OnLoad_classload001(JavaVM *jvm, char *options, void *reserved) { 162 return Agent_Initialize(jvm, options, reserved); 163 } 164 JNIEXPORT jint JNICALL Agent_OnAttach_classload001(JavaVM *jvm, char *options, void *reserved) { 165 return Agent_Initialize(jvm, options, reserved); 166 } 167 JNIEXPORT jint JNI_OnLoad_classload001(JavaVM *jvm, char *options, void *reserved) { 168 return JNI_VERSION_1_8; 169 } 170 #endif 171 jint Agent_Initialize(JavaVM *jvm, char *options, void *reserved) { 172 /* init framework and parse options */ 173 if (!NSK_VERIFY(nsk_jvmti_parseOptions(options))) 174 return JNI_ERR; 175 176 /* create JVMTI environment */ 177 if (!NSK_VERIFY((jvmti = 178 nsk_jvmti_createJVMTIEnv(jvm, reserved)) != NULL)) 179 return JNI_ERR; 180 181 initCounters(); 182 183 if (!NSK_JVMTI_VERIFY(jvmti->CreateRawMonitor("_counter_lock", &countLock))) 184 return JNI_ERR; 185 186 NSK_DISPLAY0("setting event callbacks ...\n"); 187 (void) memset(&callbacks, 0, sizeof(callbacks)); 188 callbacks.ClassLoad = &ClassLoad; 189 if (!NSK_JVMTI_VERIFY(jvmti->SetEventCallbacks(&callbacks, sizeof(callbacks)))) 190 return JNI_ERR; 191 192 NSK_DISPLAY0("setting event callbacks done\nenabling ClassLoad event ...\n"); 193 if (!NSK_JVMTI_VERIFY(jvmti->SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_CLASS_LOAD, NULL))) 194 return JNI_ERR; 195 NSK_DISPLAY0("the event enabled\n"); 196 197 return JNI_OK; 198 } 199 200 }