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 classObject = jni_env->GetObjectClass(thread); 145 if (!NSK_JNI_VERIFY(jni_env, classObject != NULL)) { 146 nsk_jvmti_setFailStatus(); 147 return; 148 } 149 150 if (!NSK_JVMTI_VERIFY(jvmti_env->GetClassSignature(classObject, &className, &generic))) { 151 nsk_jvmti_setFailStatus(); 152 return; 153 } 154 155 if (strcmp(className, EXPECTED_CLASS_NAME) == 0) { 156 changeCount(event); 157 NSK_DISPLAY3("%25s(%4d)>>\tclass: %s\n", 158 TranslateEvent(event), 159 eventCount[event - JVMTI_MIN_EVENT_TYPE_VAL], 160 className); 161 } 162 163 if (!NSK_JVMTI_VERIFY(jvmti_env->GetPhase(&phase))) { 164 nsk_jvmti_setFailStatus(); 165 } 166 167 if (phase != currentPhase) { 168 NSK_DISPLAY2("Unexpected phase %s, but supposed %s", 169 TranslatePhase(phase), TranslatePhase(currentPhase)); 170 } 171 172 if ((phase != JVMTI_PHASE_START) && (phase != JVMTI_PHASE_LIVE)) { 173 NSK_COMPLAIN4("%25s was sent during %s(%d)\n\tclass: %s\n", 174 TranslateEvent(event), 175 TranslatePhase(phase), 176 phase, 177 className); 178 nsk_jvmti_setFailStatus(); 179 } 180 181 if (!NSK_JVMTI_VERIFY(jvmti_env->Deallocate((unsigned char*)className))) { 182 nsk_jvmti_setFailStatus(); 183 } 184 if (generic != NULL) 185 if (!NSK_JVMTI_VERIFY(jvmti_env->Deallocate((unsigned char*)generic))) { 186 nsk_jvmti_setFailStatus(); 187 } 188 } 189 190 JNIEXPORT void JNICALL 191 cbVMStart(jvmtiEnv* jvmti_env, JNIEnv* jni_env) { 192 193 jvmtiPhase phase; 194 195 if (!NSK_JVMTI_VERIFY(jvmti_env->GetPhase(&phase))) { 196 nsk_jvmti_setFailStatus(); 197 } 198 199 if ((phase != JVMTI_PHASE_START) && (phase != JVMTI_PHASE_LIVE)) { 200 NSK_COMPLAIN3("%25s was sent during %s(%d)\n", 201 TranslateEvent(JVMTI_EVENT_VM_START), 202 TranslatePhase(phase), 203 phase); 204 nsk_jvmti_setFailStatus(); 205 } 206 207 changeCount(JVMTI_EVENT_VM_START); 208 currentPhase = JVMTI_PHASE_START; 209 } 210 211 JNIEXPORT void JNICALL 212 cbVMInit(jvmtiEnv* jvmti_env, JNIEnv* jni_env, jthread thread) { 213 214 jvmtiPhase phase; 215 216 if (!NSK_JVMTI_VERIFY(jvmti_env->GetPhase(&phase))) { 217 nsk_jvmti_setFailStatus(); 218 } 219 220 if (phase != JVMTI_PHASE_LIVE) { 221 NSK_COMPLAIN3("%25s was sent during %s(%d)\n", 222 TranslateEvent(JVMTI_EVENT_VM_INIT), 223 TranslatePhase(phase), 224 phase); 225 nsk_jvmti_setFailStatus(); 226 } 227 228 changeCount(JVMTI_EVENT_VM_INIT); 229 currentPhase = JVMTI_PHASE_LIVE; 230 } 231 232 JNIEXPORT void JNICALL 233 cbVMDeath(jvmtiEnv* jvmti_env, JNIEnv* jni_env) { 234 235 jvmtiPhase phase; 236 237 if (!NSK_JVMTI_VERIFY(jvmti_env->GetPhase(&phase))) { 238 nsk_jvmti_setFailStatus(); 239 } 240 241 if (phase != JVMTI_PHASE_LIVE) { 242 NSK_COMPLAIN3("%25s was sent during %s(%d)\n", 243 TranslateEvent(JVMTI_EVENT_VM_INIT), 244 TranslatePhase(phase), 245 phase); 246 nsk_jvmti_setFailStatus(); 247 } 248 249 currentPhase = JVMTI_PHASE_DEAD; 250 changeCount(JVMTI_EVENT_VM_DEATH); 251 252 if (!NSK_JVMTI_VERIFY(jvmti->DestroyRawMonitor(syncLock))) 253 nsk_jvmti_setFailStatus(); 254 255 } 256 257 JNIEXPORT void JNICALL 258 cbClassLoad(jvmtiEnv* jvmti_env, JNIEnv* jni_env, jthread thread, 259 jclass klass) { 260 261 classEventsHandler(JVMTI_EVENT_CLASS_LOAD, jvmti_env, jni_env, klass); 262 } 263 264 JNIEXPORT void JNICALL 265 cbClassPrepare(jvmtiEnv* jvmti_env, JNIEnv* jni_env, jthread thread, 266 jclass klass) { 267 268 classEventsHandler(JVMTI_EVENT_CLASS_PREPARE, jvmti_env, jni_env, klass); 269 } 270 271 JNIEXPORT void JNICALL 272 cbThreadStart(jvmtiEnv* jvmti_env, JNIEnv* jni_env, jthread thread) { 273 274 threadEventHandler(JVMTI_EVENT_THREAD_START, jvmti_env, jni_env, thread); 275 } 276 277 JNIEXPORT void JNICALL 278 cbThreadEnd(jvmtiEnv* jvmti_env, JNIEnv* jni_env, jthread thread) { 279 280 threadEventHandler(JVMTI_EVENT_THREAD_END, jvmti_env, jni_env, thread); 281 } 282 283 /* ============================================================================= */ 284 285 static int 286 enableEvent(jvmtiEventMode enable, jvmtiEvent event) { 287 NSK_DISPLAY1("enabling %s\n", TranslateEvent(event)); 288 if (!NSK_JVMTI_VERIFY(jvmti->SetEventNotificationMode(enable, event, NULL))) { 289 nsk_jvmti_setFailStatus(); 290 return NSK_FALSE; 291 } 292 293 return NSK_TRUE; 294 } 295 296 /* ============================================================================= */ 297 298 /** 299 * Testcase: check tested events. 300 * - check if expected events received for each method 301 * 302 * Returns NSK_TRUE if test may continue; or NSK_FALSE for test break. 303 */ 304 int checkEvents(int step) { 305 306 int i; 307 jvmtiEvent curr; 308 int result = NSK_TRUE; 309 int mustBeChecked; 310 311 showEventStatistics(); 312 313 for (i = 0; i < JVMTI_EVENT_COUNT; i++) { 314 315 curr = (jvmtiEvent) (i + JVMTI_MIN_EVENT_TYPE_VAL); 316 switch (step) { 317 case 1: 318 mustBeChecked = ((curr == JVMTI_EVENT_CLASS_LOAD) 319 || (curr == JVMTI_EVENT_CLASS_PREPARE)); 320 break; 321 322 case 2: 323 mustBeChecked = ((curr == JVMTI_EVENT_CLASS_LOAD) 324 || (curr == JVMTI_EVENT_CLASS_PREPARE) 325 || (curr == JVMTI_EVENT_THREAD_START) 326 || (curr == JVMTI_EVENT_THREAD_END)); 327 break; 328 default: 329 mustBeChecked = NSK_TRUE; 330 } 331 332 if (mustBeChecked && eventCount[i] != classLoaderCount) { 333 nsk_jvmti_setFailStatus(); 334 NSK_COMPLAIN3("Unexpected number of %s events %7d\n\texpected value %d\n", 335 TranslateEvent(curr), 336 eventCount[i], 337 classLoaderCount); 338 nsk_jvmti_setFailStatus(); 339 result = NSK_FALSE; 340 } 341 } 342 343 return result; 344 } 345 346 /* ============================================================================= */ 347 348 static int 349 setCallBacks() { 350 jvmtiEventCallbacks eventCallbacks; 351 memset(&eventCallbacks, 0, sizeof(eventCallbacks)); 352 353 eventCallbacks.VMStart = cbVMStart; 354 eventCallbacks.VMInit = cbVMInit; 355 eventCallbacks.VMDeath = cbVMDeath; 356 eventCallbacks.ClassLoad = cbClassLoad; 357 eventCallbacks.ClassPrepare = cbClassPrepare; 358 eventCallbacks.ThreadStart = cbThreadStart; 359 eventCallbacks.ThreadEnd = cbThreadEnd; 360 361 if (!NSK_JVMTI_VERIFY(jvmti->SetEventCallbacks(&eventCallbacks, sizeof(eventCallbacks)))) 362 return NSK_FALSE; 363 364 return NSK_TRUE; 365 } 366 367 /* ============================================================================= */ 368 369 /** Agent algorithm. */ 370 static void JNICALL 371 agentProc(jvmtiEnv* jvmti, JNIEnv* agentJNI, void* arg) { 372 373 NSK_DISPLAY0("Wait for debuggee to become ready\n"); 374 if (!nsk_jvmti_waitForSync(timeout)) 375 return; 376 377 NSK_DISPLAY0("Let debuggee to load class\n"); 378 if (!nsk_jvmti_resumeSync()) 379 return; 380 381 if (!nsk_jvmti_waitForSync(timeout)) 382 return; 383 384 /* check only CLASS_LOAD and CLASS_PREPARE events */ 385 if (!checkEvents(1)) { 386 nsk_jvmti_setFailStatus(); 387 } 388 389 NSK_DISPLAY0("Let debuggee to start threads\n"); 390 if (!nsk_jvmti_resumeSync()) 391 return; 392 393 if (!nsk_jvmti_waitForSync(timeout)) 394 return; 395 396 NSK_DISPLAY0("check event 2\n"); 397 if (!checkEvents(2)) { 398 nsk_jvmti_setFailStatus(); 399 NSK_DISPLAY0("fail\n"); 400 } 401 402 NSK_DISPLAY0("Let debuggee to finish\n"); 403 if (!nsk_jvmti_resumeSync()) 404 return; 405 406 } 407 408 /* ============================================================================= */ 409 410 /** Agent library initialization. */ 411 #ifdef STATIC_BUILD 412 JNIEXPORT jint JNICALL Agent_OnLoad_em01t001(JavaVM *jvm, char *options, void *reserved) { 413 return Agent_Initialize(jvm, options, reserved); 414 } 415 JNIEXPORT jint JNICALL Agent_OnAttach_em01t001(JavaVM *jvm, char *options, void *reserved) { 416 return Agent_Initialize(jvm, options, reserved); 417 } 418 JNIEXPORT jint JNI_OnLoad_em01t001(JavaVM *jvm, char *options, void *reserved) { 419 return JNI_VERSION_1_8; 420 } 421 #endif 422 jint Agent_Initialize(JavaVM *jvm, char *options, void *reserved) { 423 424 currentPhase = JVMTI_PHASE_ONLOAD; 425 426 if (!NSK_VERIFY(nsk_jvmti_parseOptions(options))) 427 return JNI_ERR; 428 429 timeout = nsk_jvmti_getWaitTime() * 60 * 1000; 430 classLoaderCount = nsk_jvmti_findOptionIntValue(CLASS_LOADER_COUNT_PARAM, 10); 431 432 jvmti = nsk_jvmti_createJVMTIEnv(jvm, reserved); 433 if (!NSK_VERIFY(jvmti != NULL)) 434 return JNI_ERR; 435 436 if (!NSK_JVMTI_VERIFY(jvmti->CreateRawMonitor("_syncLock", &syncLock))) { 437 nsk_jvmti_setFailStatus(); 438 return JNI_ERR; 439 } 440 441 if (!setCallBacks()) { 442 return JNI_ERR; 443 } 444 445 if (!enableEvent(JVMTI_ENABLE, JVMTI_EVENT_CLASS_LOAD) 446 || !enableEvent(JVMTI_ENABLE, JVMTI_EVENT_CLASS_PREPARE) 447 || !enableEvent(JVMTI_ENABLE, JVMTI_EVENT_THREAD_START) 448 || !enableEvent(JVMTI_ENABLE, JVMTI_EVENT_THREAD_END) 449 || !enableEvent(JVMTI_ENABLE, JVMTI_EVENT_VM_START) 450 || !enableEvent(JVMTI_ENABLE, JVMTI_EVENT_VM_INIT) 451 || !enableEvent(JVMTI_ENABLE, JVMTI_EVENT_VM_DEATH) 452 ) { 453 NSK_COMPLAIN0("Events could not be enabled"); 454 nsk_jvmti_setFailStatus(); 455 return JNI_ERR; 456 } 457 458 if (!NSK_VERIFY(nsk_jvmti_setAgentProc(agentProc, NULL))) 459 return JNI_ERR; 460 461 currentPhase = JVMTI_PHASE_PRIMORDIAL; 462 463 return JNI_OK; 464 } 465 466 }