1 /* 2 * Copyright (c) 2004, 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 <string.h> 25 #include "jvmti.h" 26 #include "agent_common.h" 27 #include "jni_tools.h" 28 #include "jvmti_tools.h" 29 #include "JVMTITools.h" 30 31 extern "C" { 32 33 /* ============================================================================= */ 34 35 /* scaffold objects */ 36 static JNIEnv* jni = NULL; 37 static jvmtiEnv *jvmti = NULL; 38 static jlong timeout = 0; 39 static jrawMonitorID syncLock = NULL; 40 41 /* constant names */ 42 #define JVMTI_EVENT_COUNT (int)(JVMTI_MAX_EVENT_TYPE_VAL - JVMTI_MIN_EVENT_TYPE_VAL + 1) 43 #define EXPECTED_CLASS_NAME "Lnsk/jvmti/scenarios/events/EM01/em01t001a;" 44 #define CLASS_LOADER_COUNT_PARAM "classLoaderCount" 45 46 static int eventCount[JVMTI_EVENT_COUNT]; 47 48 static int classLoaderCount = 0; 49 50 static jvmtiPhase currentPhase; 51 52 /* ============================================================================= */ 53 54 static void 55 changeCount(jvmtiEvent event) { 56 57 if (!NSK_JVMTI_VERIFY(jvmti->RawMonitorEnter(syncLock))) 58 nsk_jvmti_setFailStatus(); 59 60 eventCount[event - JVMTI_MIN_EVENT_TYPE_VAL]++; 61 62 if (!NSK_JVMTI_VERIFY(jvmti->RawMonitorExit(syncLock))) 63 nsk_jvmti_setFailStatus(); 64 65 } 66 67 /* ============================================================================= */ 68 69 static void 70 showEventStatistics() { 71 int i; 72 const char* str; 73 74 NSK_DISPLAY0("Event statistics\n"); 75 NSK_DISPLAY0("----------------\n"); 76 for (i = 0; i < JVMTI_EVENT_COUNT; i++) { 77 if (eventCount[i] > 0) { 78 str = TranslateEvent((jvmtiEvent)(i+JVMTI_MIN_EVENT_TYPE_VAL)); 79 NSK_DISPLAY2("%-40s %7d\n", str, eventCount[i]); 80 } 81 } 82 } 83 84 /* ========================================================================== */ 85 86 /* callbacks */ 87 void 88 classEventsHandler(jvmtiEvent event, jvmtiEnv* jvmti_env, JNIEnv* jni_env, 89 jclass klass) { 90 91 char *className; 92 char *generic; 93 jvmtiPhase phase; 94 95 if (!NSK_JVMTI_VERIFY(jvmti_env->GetClassSignature(klass, &className, &generic))) { 96 nsk_jvmti_setFailStatus(); 97 return; 98 } 99 100 if (strcmp(className, EXPECTED_CLASS_NAME) == 0) { 101 changeCount(event); 102 NSK_DISPLAY3("%25s(%4d)>>\tclass: %s\n", 103 TranslateEvent(event), 104 eventCount[event - JVMTI_MIN_EVENT_TYPE_VAL], 105 className); 106 } 107 108 if (!NSK_JVMTI_VERIFY(jvmti_env->GetPhase(&phase))) { 109 nsk_jvmti_setFailStatus(); 110 } 111 112 if (phase != currentPhase) { 113 NSK_DISPLAY2("Unexpected phase %s, but supposed %s", 114 TranslatePhase(phase), TranslatePhase(currentPhase)); 115 } 116 117 if ((phase != JVMTI_PHASE_LIVE) && (phase != JVMTI_PHASE_START)) { 118 NSK_COMPLAIN4("%25s was sent during %s(%d)\n\tclass: %s\n", 119 TranslateEvent(event), 120 TranslatePhase(phase), 121 phase, 122 className); 123 nsk_jvmti_setFailStatus(); 124 } 125 126 if (!NSK_JVMTI_VERIFY(jvmti_env->Deallocate((unsigned char*)className))) { 127 nsk_jvmti_setFailStatus(); 128 } 129 if (generic != NULL) 130 if (!NSK_JVMTI_VERIFY(jvmti_env->Deallocate((unsigned char*)generic))) { 131 nsk_jvmti_setFailStatus(); 132 } 133 } 134 135 void 136 threadEventHandler(jvmtiEvent event, jvmtiEnv* jvmti_env, JNIEnv* jni_env, 137 jthread thread) { 138 jclass classObject; 139 char *className; 140 char *generic; 141 jvmtiPhase phase; 142 143 144 if (!NSK_JNI_VERIFY(jni_env, (classObject = jni_env->GetObjectClass(thread)) != NULL)) { 145 nsk_jvmti_setFailStatus(); 146 return; 147 } 148 149 if (!NSK_JVMTI_VERIFY(jvmti_env->GetClassSignature(classObject, &className, &generic))) { 150 nsk_jvmti_setFailStatus(); 151 return; 152 } 153 154 if (strcmp(className, EXPECTED_CLASS_NAME) == 0) { 155 changeCount(event); 156 NSK_DISPLAY3("%25s(%4d)>>\tclass: %s\n", 157 TranslateEvent(event), 158 eventCount[event - JVMTI_MIN_EVENT_TYPE_VAL], 159 className); 160 } 161 162 if (!NSK_JVMTI_VERIFY(jvmti_env->GetPhase(&phase))) { 163 nsk_jvmti_setFailStatus(); 164 } 165 166 if (phase != currentPhase) { 167 NSK_DISPLAY2("Unexpected phase %s, but supposed %s", 168 TranslatePhase(phase), TranslatePhase(currentPhase)); 169 } 170 171 if ((phase != JVMTI_PHASE_START) && (phase != JVMTI_PHASE_LIVE)) { 172 NSK_COMPLAIN4("%25s was sent during %s(%d)\n\tclass: %s\n", 173 TranslateEvent(event), 174 TranslatePhase(phase), 175 phase, 176 className); 177 nsk_jvmti_setFailStatus(); 178 } 179 180 if (!NSK_JVMTI_VERIFY(jvmti_env->Deallocate((unsigned char*)className))) { 181 nsk_jvmti_setFailStatus(); 182 } 183 if (generic != NULL) 184 if (!NSK_JVMTI_VERIFY(jvmti_env->Deallocate((unsigned char*)generic))) { 185 nsk_jvmti_setFailStatus(); 186 } 187 } 188 189 JNIEXPORT void JNICALL 190 cbVMStart(jvmtiEnv* jvmti_env, JNIEnv* jni_env) { 191 192 jvmtiPhase phase; 193 194 if (!NSK_JVMTI_VERIFY(jvmti_env->GetPhase(&phase))) { 195 nsk_jvmti_setFailStatus(); 196 } 197 198 if ((phase != JVMTI_PHASE_START) && (phase != JVMTI_PHASE_LIVE)) { 199 NSK_COMPLAIN3("%25s was sent during %s(%d)\n", 200 TranslateEvent(JVMTI_EVENT_VM_START), 201 TranslatePhase(phase), 202 phase); 203 nsk_jvmti_setFailStatus(); 204 } 205 206 changeCount(JVMTI_EVENT_VM_START); 207 currentPhase = JVMTI_PHASE_START; 208 } 209 210 JNIEXPORT void JNICALL 211 cbVMInit(jvmtiEnv* jvmti_env, JNIEnv* jni_env, jthread thread) { 212 213 jvmtiPhase phase; 214 215 if (!NSK_JVMTI_VERIFY(jvmti_env->GetPhase(&phase))) { 216 nsk_jvmti_setFailStatus(); 217 } 218 219 if (phase != JVMTI_PHASE_LIVE) { 220 NSK_COMPLAIN3("%25s was sent during %s(%d)\n", 221 TranslateEvent(JVMTI_EVENT_VM_INIT), 222 TranslatePhase(phase), 223 phase); 224 nsk_jvmti_setFailStatus(); 225 } 226 227 changeCount(JVMTI_EVENT_VM_INIT); 228 currentPhase = JVMTI_PHASE_LIVE; 229 } 230 231 JNIEXPORT void JNICALL 232 cbVMDeath(jvmtiEnv* jvmti_env, JNIEnv* jni_env) { 233 234 jvmtiPhase phase; 235 236 if (!NSK_JVMTI_VERIFY(jvmti_env->GetPhase(&phase))) { 237 nsk_jvmti_setFailStatus(); 238 } 239 240 if (phase != JVMTI_PHASE_LIVE) { 241 NSK_COMPLAIN3("%25s was sent during %s(%d)\n", 242 TranslateEvent(JVMTI_EVENT_VM_INIT), 243 TranslatePhase(phase), 244 phase); 245 nsk_jvmti_setFailStatus(); 246 } 247 248 currentPhase = JVMTI_PHASE_DEAD; 249 changeCount(JVMTI_EVENT_VM_DEATH); 250 251 if (!NSK_JVMTI_VERIFY(jvmti->DestroyRawMonitor(syncLock))) 252 nsk_jvmti_setFailStatus(); 253 254 } 255 256 JNIEXPORT void JNICALL 257 cbClassLoad(jvmtiEnv* jvmti_env, JNIEnv* jni_env, jthread thread, 258 jclass klass) { 259 260 classEventsHandler(JVMTI_EVENT_CLASS_LOAD, jvmti_env, jni_env, klass); 261 } 262 263 JNIEXPORT void JNICALL 264 cbClassPrepare(jvmtiEnv* jvmti_env, JNIEnv* jni_env, jthread thread, 265 jclass klass) { 266 267 classEventsHandler(JVMTI_EVENT_CLASS_PREPARE, jvmti_env, jni_env, klass); 268 } 269 270 JNIEXPORT void JNICALL 271 cbThreadStart(jvmtiEnv* jvmti_env, JNIEnv* jni_env, jthread thread) { 272 273 threadEventHandler(JVMTI_EVENT_THREAD_START, jvmti_env, jni_env, thread); 274 } 275 276 JNIEXPORT void JNICALL 277 cbThreadEnd(jvmtiEnv* jvmti_env, JNIEnv* jni_env, jthread thread) { 278 279 threadEventHandler(JVMTI_EVENT_THREAD_END, jvmti_env, jni_env, thread); 280 } 281 282 /* ============================================================================= */ 283 284 static int 285 enableEvent(jvmtiEventMode enable, jvmtiEvent event) { 286 NSK_DISPLAY1("enabling %s\n", TranslateEvent(event)); 287 if (!NSK_JVMTI_VERIFY(jvmti->SetEventNotificationMode(enable, event, NULL))) { 288 nsk_jvmti_setFailStatus(); 289 return NSK_FALSE; 290 } 291 292 return NSK_TRUE; 293 } 294 295 /* ============================================================================= */ 296 297 /** 298 * Testcase: check tested events. 299 * - check if expected events received for each method 300 * 301 * Returns NSK_TRUE if test may continue; or NSK_FALSE for test break. 302 */ 303 int checkEvents(int step) { 304 305 int i; 306 jvmtiEvent curr; 307 int result = NSK_TRUE; 308 int mustBeChecked; 309 310 showEventStatistics(); 311 312 for (i = 0; i < JVMTI_EVENT_COUNT; i++) { 313 314 curr = (jvmtiEvent) (i + JVMTI_MIN_EVENT_TYPE_VAL); 315 switch (step) { 316 case 1: 317 mustBeChecked = ((curr == JVMTI_EVENT_CLASS_LOAD) 318 || (curr == JVMTI_EVENT_CLASS_PREPARE)); 319 break; 320 321 case 2: 322 mustBeChecked = ((curr == JVMTI_EVENT_CLASS_LOAD) 323 || (curr == JVMTI_EVENT_CLASS_PREPARE) 324 || (curr == JVMTI_EVENT_THREAD_START) 325 || (curr == JVMTI_EVENT_THREAD_END)); 326 break; 327 default: 328 mustBeChecked = NSK_TRUE; 329 } 330 331 if (mustBeChecked && eventCount[i] != classLoaderCount) { 332 nsk_jvmti_setFailStatus(); 333 NSK_COMPLAIN3("Unexpected number of %s events %7d\n\texpected value %d\n", 334 TranslateEvent(curr), 335 eventCount[i], 336 classLoaderCount); 337 nsk_jvmti_setFailStatus(); 338 result = NSK_FALSE; 339 } 340 } 341 342 return result; 343 } 344 345 /* ============================================================================= */ 346 347 static int 348 setCallBacks() { 349 jvmtiEventCallbacks eventCallbacks; 350 memset(&eventCallbacks, 0, sizeof(eventCallbacks)); 351 352 eventCallbacks.VMStart = cbVMStart; 353 eventCallbacks.VMInit = cbVMInit; 354 eventCallbacks.VMDeath = cbVMDeath; 355 eventCallbacks.ClassLoad = cbClassLoad; 356 eventCallbacks.ClassPrepare = cbClassPrepare; 357 eventCallbacks.ThreadStart = cbThreadStart; 358 eventCallbacks.ThreadEnd = cbThreadEnd; 359 360 if (!NSK_JVMTI_VERIFY(jvmti->SetEventCallbacks(&eventCallbacks, sizeof(eventCallbacks)))) 361 return NSK_FALSE; 362 363 return NSK_TRUE; 364 } 365 366 /* ============================================================================= */ 367 368 /** Agent algorithm. */ 369 static void JNICALL 370 agentProc(jvmtiEnv* jvmti, JNIEnv* agentJNI, void* arg) { 371 372 NSK_DISPLAY0("Wait for debuggee to become ready\n"); 373 if (!nsk_jvmti_waitForSync(timeout)) 374 return; 375 376 NSK_DISPLAY0("Let debuggee to load class\n"); 377 if (!nsk_jvmti_resumeSync()) 378 return; 379 380 if (!nsk_jvmti_waitForSync(timeout)) 381 return; 382 383 /* check only CLASS_LOAD and CLASS_PREPARE events */ 384 if (!checkEvents(1)) { 385 nsk_jvmti_setFailStatus(); 386 } 387 388 NSK_DISPLAY0("Let debuggee to start threads\n"); 389 if (!nsk_jvmti_resumeSync()) 390 return; 391 392 if (!nsk_jvmti_waitForSync(timeout)) 393 return; 394 395 NSK_DISPLAY0("check event 2\n"); 396 if (!checkEvents(2)) { 397 nsk_jvmti_setFailStatus(); 398 NSK_DISPLAY0("fail\n"); 399 } 400 401 NSK_DISPLAY0("Let debuggee to finish\n"); 402 if (!nsk_jvmti_resumeSync()) 403 return; 404 405 } 406 407 /* ============================================================================= */ 408 409 /** Agent library initialization. */ 410 #ifdef STATIC_BUILD 411 JNIEXPORT jint JNICALL Agent_OnLoad_em01t001(JavaVM *jvm, char *options, void *reserved) { 412 return Agent_Initialize(jvm, options, reserved); 413 } 414 JNIEXPORT jint JNICALL Agent_OnAttach_em01t001(JavaVM *jvm, char *options, void *reserved) { 415 return Agent_Initialize(jvm, options, reserved); 416 } 417 JNIEXPORT jint JNI_OnLoad_em01t001(JavaVM *jvm, char *options, void *reserved) { 418 return JNI_VERSION_1_8; 419 } 420 #endif 421 jint Agent_Initialize(JavaVM *jvm, char *options, void *reserved) { 422 423 currentPhase = JVMTI_PHASE_ONLOAD; 424 425 if (!NSK_VERIFY(nsk_jvmti_parseOptions(options))) 426 return JNI_ERR; 427 428 timeout = nsk_jvmti_getWaitTime() * 60 * 1000; 429 classLoaderCount = nsk_jvmti_findOptionIntValue(CLASS_LOADER_COUNT_PARAM, 10); 430 431 if (!NSK_VERIFY((jvmti = nsk_jvmti_createJVMTIEnv(jvm, reserved)) != NULL)) 432 return JNI_ERR; 433 434 if (!NSK_JVMTI_VERIFY(jvmti->CreateRawMonitor("_syncLock", &syncLock))) { 435 nsk_jvmti_setFailStatus(); 436 return JNI_ERR; 437 } 438 439 if (!setCallBacks()) { 440 return JNI_ERR; 441 } 442 443 if (!enableEvent(JVMTI_ENABLE, JVMTI_EVENT_CLASS_LOAD) 444 || !enableEvent(JVMTI_ENABLE, JVMTI_EVENT_CLASS_PREPARE) 445 || !enableEvent(JVMTI_ENABLE, JVMTI_EVENT_THREAD_START) 446 || !enableEvent(JVMTI_ENABLE, JVMTI_EVENT_THREAD_END) 447 || !enableEvent(JVMTI_ENABLE, JVMTI_EVENT_VM_START) 448 || !enableEvent(JVMTI_ENABLE, JVMTI_EVENT_VM_INIT) 449 || !enableEvent(JVMTI_ENABLE, JVMTI_EVENT_VM_DEATH) 450 ) { 451 NSK_COMPLAIN0("Events could not be enabled"); 452 nsk_jvmti_setFailStatus(); 453 return JNI_ERR; 454 } 455 456 if (!NSK_VERIFY(nsk_jvmti_setAgentProc(agentProc, NULL))) 457 return JNI_ERR; 458 459 currentPhase = JVMTI_PHASE_PRIMORDIAL; 460 461 return JNI_OK; 462 } 463 464 }